ios - 我如何在 UITableViewCell 或 UICollectionViewCell 中编写仅影响其所在单元格的 UIButton 扩展?

标签 ios swift uitableview uicollectionview uicollectionviewcell

如您所知,当我们在可重用单元格内声明一个按钮时,它会在滚动时在 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/

相关文章:

iOS UiTableViewCell 选择性单元格显示附件 View

ios - 如何获取Xcode构建目录?

ios - 如何定义 pin 的触摸区域(Skobbler iOS)

iOS TableView on Scrollview 事件问题

ios - 如何识别这个数组中某些字符的索引?

swift - UIScrollView 宽度比屏幕宽

swift - 异步图像下载功能 Swift - 有些图像不返回

SwiftUI 使用编辑模式更改 View

iphone - 自定义 UITableViewCell 给我 : this class is not key value coding-compliant

ios - 如何在 iOS 中以编程方式更改表格的高度