Как я могу написать расширение для UIButton в UITableViewCell или UICollectionViewCell, которое влияет только на ячейку, внутри которой оно находится? - PullRequest
0 голосов
/ 24 мая 2019

Как вы знаете, когда мы объявляем кнопку внутри многократно используемой ячейки, она повторяет пользовательский интерфейс после 5 или 6 ячеек при прокрутке.Метод prepareToReuse () только сбрасывает пользовательский интерфейс, но чтобы сохранить изменения в пользовательском интерфейсе, нам необходимо объявить словарь,

метод prepareToReuse () только сбрасывает пользовательский интерфейс, но;чтобы сохранить изменения в пользовательском интерфейсе 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 для выполнения той же работы или есть более короткий и лучший способ его использования.Отслеживание повторяющихся кнопок в элементах многократного использования, таких как «как кнопки, переключатели, флажки и т. Д.»проблема не знаю, почему яблоко не делает что-то для этого.Я был бы очень рад, если бы кто-нибудь показал мне лучший способ.Спасибо.

1 Ответ

0 голосов
/ 24 мая 2019

проверьте этот код, я считаю ваш источник данных моделью, а не словарем, вы можете легко это сделать.

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
    }
}
...