【问题标题】:Swift: How to reuse a ViewController properlySwift:如何正确重用 ViewController
【发布时间】:2018-08-16 07:09:42
【问题描述】:

我有一个 UICollectionViewController 类型的 HomeController,它处理一些 PictureCell(包含图片和标签)。 现在我将一个 PictureCell 发送到另一个 ViewController 以编辑标签。这一切都完美无缺。我可以使用协议将其发送回 HVC,但我不想返回,而是想更进一步,在新的 ViewController 中显示已编辑的 PictureCell。

我没有创建一个全新的,而是将现有的 HomeController 子类化以重用他的CollectionView。一切正常,视图显示了,但编辑后的 ​​PictureCell 根本没有显示,即使我可以显示它的图层,Cell 本身及其内容也没有显示。

(凌乱的)类图如下所示: ClassDiagram

    class HomeController: UICollectionViewController, UICollectionViewDelegateFlowLayout, MyProtocol {


    override func viewDidLoad() {
        super.viewDidLoad()

        collectionView?.backgroundColor = UIColor.black
        collectionView?.register(PictureCell.self, forCellWithReuseIdentifier: Constants.cellId)
    }


    //MARK: Get value from second VC
    var valueSentFromSecondViewController: String?
    var cellSentFromSecondViewController: PictureCell?

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(true)
        //Acting with Protocol here
    }
     //HERE ARE THE COLLECTIONVIEWFUNCTIONS
}


class PictureEditViewController: UIViewController, UITextFieldDelegate {

    var delegate:MyProtocol?
    var myCell: PictureCell?

    let collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.backgroundColor = UIColor.white
        return cv
    }()

    init(pictureCellInit: PictureCell?) {
        self.myCell = pictureCellInit
        super.init(nibName: nil, bundle: nil)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        showThings()
    }

    @objc func showNextVC() {
        let newViewController = PictureShowViewController(withCell: self.myCell)
        newViewController.modalPresentationStyle = .overCurrentContext
        present(newViewController, animated: true) //with dismiss
    }


    @objc func showThings() {
        view.addSubview(collectionView)
        self.collectionView.frame = CGRect(x: x, y: y, width: width, height: height)
        self.setupViews()
    }

    func setupViews() {
        //ADDING THE SUBVIEWS
    }

    func confBounds() {
        //LAYOUT
    }

    @objc func handleDismiss() {
        self.dismiss(animated: true, completion: nil)
    }


class PictureShowViewController: HomeController {

    //MARK: Variable/Constant declaration
    var myCellToShow: PictureCell?

    init(withCell: PictureCell?) {
        let layoutUsing = UICollectionViewFlowLayout()
        myCellToShow = withCell
        super.init(collectionViewLayout: layoutUsing)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        collectionView?.backgroundColor = .white
    }

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(true)
        collectionView?.addSubview(myCellToShow!)
        self.collectionView?.reloadData()
    }

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 1
    }


    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        if let cell = myCellToShow {
            cell.layer.borderColor = UIColor.red.cgColor
            cell.layer.borderWidth = 2
            return cell
        }
        else {
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Constants.cellId, for: indexPath) as! PictureCell
            return cell
        }
    }

    //Size of Cell
    override func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

        let cellSize = CGFloat(view.frame.width)
        return CGSize(width: cellSize, height: cellSize)
    }
}

有人知道我哪里出错了吗?

【问题讨论】:

    标签: ios swift cell viewcontroller collectionview


    【解决方案1】:

    使用PictureCell 在视图控制器周围移动数据是个坏主意。 UICollectionView 重用单元格的实例,因此单元格的内容必然会随时更改。

    因此,不要使用您的单元格,而是交出基础数据并将数据插入到新出列的集合视图单元格中。

    最后, var cellSentFromSecondViewController: PictureCell? 应该是var pictureFromSecondViewController: YourPictureData

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Constants.cellId, for: indexPath) as! PictureCell
    
        //Set your data
        cell.picture = pictureFromSecondViewController
    
        return cell
    }
    

    【讨论】:

    • 我一开始就是这样做的,但是我公司的一位非常有经验的人告诉我不要那样做,更好的方法是传递我想要的 Cell 实例编辑。
    • 嗯,我认为集合视图重用单元格的性质使其不适合将其存储在某个地方并期望它成为您认为的将来的样子。我只是把细胞想象成一个一次性的盘子来放我的食物(数据),食物可以随时更换。
    • 但是你也可以给周围一个盘子,让你的朋友修改上面的食物.. ;)
    • @sj-r 是对的。 Collection View 可以控制自己的单元格。它决定何时重用单元格。因此,如果您尝试在其他地方使用单元格,旧的集合视图仍然拥有它,并且可以随时尝试重用它。
    • @Noodledew 是的.. 问题是您想要五分钟前放置的香蕉,但您的朋友用草莓代替了它,您无法取回您想要的香蕉。 :(
    猜你喜欢
    • 1970-01-01
    • 2022-01-17
    • 2018-12-16
    • 1970-01-01
    • 1970-01-01
    • 2016-06-02
    • 2014-04-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多