如您所知,当我们在可重用单元格内声明一个按钮时,它会在滚动时在 5 或 6 个单元格后重复 UI。 prepareToReuse() 方法仅重置 UI,但为了保留 UI 上的更改,我们需要声明一个字典,
prepareToReuse() 方法仅重置 UI,但是;为了保持 UI 上的更改 1) 我们需要声明一个字典数组 2)用我们需要的单元格数量的默认值填充该字典 3)更改与我们的单元格相同索引处的元素的值 4)在重用单元格时检查我们是否更改默认值
import UIKit
//defining a enum to track cell state
enum CellState {
case selected
case unselected
init() {
self = .unselected
}
}
class yourCell: UICollectionViewCell {
@IBOutlet weak var yourBtn: UIButton!
// creating our func
var buttonAction: (() -> ())?
override func awakeFromNib() {
super.awakeFromNib()
}
@IBAction func sliderAction(_ sender: UISlider) {
// defining our func where we want to use it
buttonAction()
}
}
// inside our viewController
import UIKit
class yourViewController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
@IBOutlet weak var collectionView: UICollectionView!
// you data source that you fill the cells
var yourDataArray: [yourDataSource]()
// the array that will hold status of our cells
private var cellStateArray: [CellState]?
override func viewDidLoad() {
super.viewDidLoad()
//confirming our delegate and dataSource
collectionView.dataSource = self
collectionView.delegate = self
//filling your cellStateArray as many as your cell count
self.cellStateArray = Array(repeating: .unselected, count: self.yourDataArray!.count )
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if yourDataArray?.isEmpty == false {
return yourDataArray!.count
} else {
print("Caution yourDataArray IS EMPTY")
return 0
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "yourCell", for: indexPath) as! yourCell
// checking your button selected or not while reuse it (while scrolling)
if cellStateArray![indexPath.row] == .selected {
cell.yourBtn.backgroundColor = .red
} else {
cell.yourBtn.backgroundColor = .blue
}
cell.buttonAction = {
//calling button function
button_Select(_ sender: cell.yourBtn, cellStateArray: cellStateArray, indexPath: IndexPath)
}
}
// Defining the function what you want to do with your button in each cell
func button_Select(_ sender: UIButton, cellStateArray: [CellState], indexPath: IndexPath ) {
sender.isSelected = !sender.isSelected
if sender.isSelected{
sender.backgroundColor = .red
//setting value when your button selected
cellStateArray[indexPath.row] = .selected
}
else{
sender.backgroundColor = .blue
//setting value when your button unselected
cellStateArray[indexPath.row] = .unselected
}
collectionView.reloadData()
}
}
如果有人需要使用它,我也提到了我自己的方法,但正如你所见,它是如此漫长。我的问题是我们是否可以为 UIButton 定义一个扩展来完成相同的工作,或者是否有更短、更好的方法来使用它。跟踪可重用单元格中的重复按钮,例如“按钮、开关、复选框等”问题是不知道为什么苹果不为此做点什么。如果有人向我展示更好的方法,我会非常高兴。谢谢。
最佳答案
check this code i have consider your datasource as model not dictionary you can make it easily.
class yourCell: UICollectionViewCell {
@IBOutlet weak var yourBtn: UIButton!
// creating our func
var reloadData: (() -> ())?
var model = yourDataSource()
override func awakeFromNib() {
super.awakeFromNib()
}
@IBAction func sliderAction(_ sender: UISlider) {
self.model.isSelected = !self.model.isSelected
reloadData?()
}
func setCellData(model:yourDataSource){
self.model = model
if model.isSelected {
yourBtn.backgroundColor = .red
} else {
yourBtn.backgroundColor = .blue
}
}
}
// inside our viewController
import UIKit
class yourViewController: UIViewController {
@IBOutlet weak var collectionView: UICollectionView!
// you data source that you fill the cells
var yourDataArray = [yourDataSource]() // considering this as model and has isSelected property (default false)
override func viewDidLoad() {
super.viewDidLoad()
//confirming our delegate and dataSource
collectionView.dataSource = self
collectionView.delegate = self
//fill your model here or pass data as u want
}
}
extension yourViewController : UICollectionViewDelegate, UICollectionViewDataSource{
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
if yourDataArray?.isEmpty == false {
return yourDataArray!.count
} else {
print("Caution yourDataArray IS EMPTY")
return 0
}
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let model = self.yourDataArray[indexPath.row]
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "yourCell", for: indexPath) as! yourCell
cell.setCellData(model: model)
cell.reloadData = {
//reload full collection view or single item
self.collectionView.reloadData()
}
return cell
}
}
关于ios - 我如何在 UITableViewCell 或 UICollectionViewCell 中编写仅影响其所在单元格的 UIButton 扩展?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56288230/