Проблемы с приведением типов ячеек к исключению из очереди

avatar
Valerio Zhang
2 января 2017 в 13:45
611
2
2

Здравствуйте, у меня возникли проблемы с моим cellForItem. В нем говорится об ошибке ниже. Я не понимаю, почему я не могу бросить ячейки. Это происходит в первой строке оператора else.

Методы категории UIConstraintBasedLayoutDebugging в UIView, указанные в списке, также могут быть полезны.

Не удалось преобразовать значение типа "Spoexs.MenuCell2" (0x10d059660) в "Spoexs.MenuCell1" (0x10d0595c0).

import UIKit
import MIBadgeButton_Swift

class SecondMenuBar: UIView, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {

    lazy var collectionView: UICollectionView = {
        let layout = UICollectionViewFlowLayout()
        let cv = UICollectionView(frame: .zero, collectionViewLayout: layout)
        cv.backgroundColor = UIColor.rgb(r:240, g:240, b:240)
        cv.dataSource = self
        cv.delegate = self
        return cv
    }()

    let cellId = "cellId"
    let cellId2 = "cellId2"

    let menuItems = ["inventory", "checkout", "scanner"]
    var inventoryController: InventoryTabController?

    override init(frame: CGRect){ //on run
        super.init(frame: frame)

        collectionView.register(MenuCell1.self,
                                forCellWithReuseIdentifier: cellId) //registering superclass

        collectionView.register(MenuCell2.self,
                                forCellWithReuseIdentifier: cellId) //registering superclass

        addSubview(collectionView)
        addConstraintsWithFormat("H:|[v0]|", views: collectionView)
        addConstraintsWithFormat("V:|[v0]|", views: collectionView)

        let selectedIndexPath = NSIndexPath(item:0, section:0)
        collectionView.selectItem(at: selectedIndexPath as IndexPath, animated: false, scrollPosition: []) //home button glows on run


        //setup horizontal bar
        slider()
        NotificationCenter.default.addObserver(forName: .arrayValueChanged, object: nil, queue: OperationQueue.main) { [weak self] (notif) in
            badge = "\(checkout.count)"
            self?.collectionView.reloadData()
        }
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }

    var horizontalBarLeftAnchorConstraint: NSLayoutConstraint?

    func slider() {
        let horizontalBarView = UIView()
        if #available(iOS 10.0, *) {
            horizontalBarView.backgroundColor = UIColor(displayP3Red:0.29, green:0.78, blue:0.47, alpha:0.2)
        } else {
            horizontalBarView.backgroundColor = UIColor.rgb(r:190, g:190, b:190)
        }
        horizontalBarView.translatesAutoresizingMaskIntoConstraints = false
        addSubview(horizontalBarView) //add to hierarchy

        // need x,y coordinate
        horizontalBarLeftAnchorConstraint = horizontalBarView.leftAnchor.constraint(equalTo: self.leftAnchor)
        horizontalBarLeftAnchorConstraint?.isActive = true

        horizontalBarView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
        horizontalBarView.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 1/3).isActive = true
        horizontalBarView.heightAnchor.constraint(equalToConstant: 3).isActive = true
    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        inventoryController?.scrollToMenuIndex(menuIndex: indexPath.item)
        print("Right here \(indexPath.section)")
        print("Right here \(indexPath.item)")
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
        return CGSize(width: frame.width/3, height: frame.height)
    }

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return 0
    }

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

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {


        if indexPath.section == 1{
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId2, for: indexPath) as! MenuCell2
            cell.imageView2.setImage(UIImage(named:menuItems[indexPath.section])?.withRenderingMode(.alwaysTemplate), for: .normal)
            cell.imageView2.badgeString = badge
            cell.tintColor = UIColor.rgb(r:255, g:0, b:255) //set tint color
            return cell
        } else{
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! MenuCell1
            cell.imageView1.image = UIImage(named: menuItems[indexPath.section])?.withRenderingMode(.alwaysTemplate)
            cell.tintColor = UIColor.rgb(r:255, g:0, b:255) //set tint color
            return cell
        }
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

class MenuCell1: UICollectionViewCell {

    override init(frame: CGRect){
        super.init(frame: frame)
        setupViews()

    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    let imageView1: UIImageView = {
        let iv = UIImageView()
        iv.image = UIImage(named: "")?.withRenderingMode(.alwaysTemplate)
        iv.tintColor = UIColor.rgb(r:144, g:157, b:255)//set tint color of each menu image bg
        return iv
    }()


    override var isSelected: Bool {
        didSet {
            imageView1.tintColor = isSelected ? UIColor.rgb(r:76, g:200, b:120) : UIColor.rgb(r:190, g:190, b:190)  //green when selected otherwise grey
        }
    }

    func setupViews() {

        addSubview(imageView1)

        addConstraintsWithFormat("H:[v0(28)]", views: imageView1)
        addConstraintsWithFormat("V:[v0(28)]", views: imageView1)

        addConstraint(NSLayoutConstraint(item: imageView1, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier:1, constant: 0)) //center menu icons
        addConstraint(NSLayoutConstraint(item: imageView1, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier:1, constant: 0))
    }

}


class MenuCell2: UICollectionViewCell {

    override init(frame: CGRect){
        super.init(frame: frame)
        setupViews()

    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }


    let imageView2: MIBadgeButton = {
        let button = MIBadgeButton()
        var image = UIImage(named: "home")?.withRenderingMode(.alwaysTemplate)
        button.setImage(image, for: .normal)
        button.badgeString = badge
        button.isUserInteractionEnabled = false
        button.tintColor = UIColor.rgb(r:190, g:190, b:190) //intital button tint grey
        return button
    }()

    override var isSelected: Bool {
        didSet {
            imageView2.tintColor = isSelected ? UIColor.rgb(r:76, g:200, b:120) : UIColor.rgb(r:190, g:190, b:190)  //green when selected otherwise grey
        }
    }

    func setupViews() {

        addSubview(imageView2)

        addConstraintsWithFormat("H:[v0(28)]", views: imageView2)
        addConstraintsWithFormat("V:[v0(28)]", views: imageView2)

        addConstraint(NSLayoutConstraint(item: imageView2, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier:1, constant: 0)) //center menu icons
        addConstraint(NSLayoutConstraint(item: imageView2, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier:1, constant: 0))

    }

}
Источник

Ответы (2)

avatar
luk2302
2 января 2017 в 13:51
7

Ваш код для регистрации классов ячеек неверен:

collectionView.register(MenuCell1.self, forCellWithReuseIdentifier: cellId)
collectionView.register(MenuCell2.self, forCellWithReuseIdentifier: cellId) // <-- probably not intended

Вы регистрируете оба класса для одного и того же cellId, один должен быть cellId2:

collectionView.register(MenuCell1.self, forCellWithReuseIdentifier: cellId)
collectionView.register(MenuCell2.self, forCellWithReuseIdentifier: cellId2)
Umair Afzal
2 января 2017 в 13:59
0

@ValerioZhang Примите ответ, если он решил вашу проблему.

avatar
matt
2 января 2017 в 13:51
1

Проблема в этой строке:

let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellId, for: indexPath) as! MenuCell1

Ячейка, которую вы зарегистрировали для этого идентификатора повторного использования, называется MenuCell2, так что вы получаете именно ее. Затем вы не сможете волшебным образом превратить его в MenuCell1!