最新消息:20210816 当前crifan.com域名已被污染,为防止失联,请关注(页面右下角的)公众号

[已解决]swift中UICollectionViewCell在reloadData()之后显示内容出现重叠现象

Swift crifan 5582浏览 0评论

折腾:

[已解决]swift编辑和删除UICollectionViewCell

之后,加了:

else if selectedContactItem.id == removePersonId  {
                self.isRemoveMode = !self.isRemoveMode
                print("self.isRemoveMode=\(self.isRemoveMode)")
                self.collectionView.reloadData()
            }

然后重新让cell绘图,结果cell出现重叠内容:

1.尝试了:

//        let cell:UICollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier(StrIdConversationManageCollectionViewCell, forIndexPath: indexPath)
        let cell:UICollectionViewCell = UICollectionViewCell()

不行,会出错:

Assertion failure in -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:isFocused:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3512.30.14/UICollectionView.m:1520
2015-12-25 14:02:41.755 JianDao[28445:1291040] *** Terminating app due to uncaught exception ‘NSInternalInconsistencyException’, reason: ‘the cell returned from -collectionView:cellForItemAtIndexPath: does not have a reuseIdentifier – cells must be retrieved by calling -dequeueReusableCellWithReuseIdentifier:forIndexPath:’

2.试了试:

调整布局,把之前的,手动计算frame的,都换成constraint的:

        if let contactItem = getContactItem(indexPath) {
            let contactImage = contactItem.headerImageLarge
            let contactImageView:UIImageView = UIImageView(image: contactImage)
            //            contactImageView.center.x = cell.contentView.center.x
            cell.contentView.addSubview(contactImageView)
//            cell.addSubview(contactImageView)
           
            constrain(contactImageView, cell) { contactImageView, cell in
                contactImageView.top == cell.top
                contactImageView.centerX == cell.centerX
            }
           
            if !isSperialItem(contactItem) {
                //                let nameLabelFrame = CGRectMake(0, contactImage.size.height + collectionViewCellPaddingY, contactImage.size.width, collectionViewCellNameLabelHeight)
                //                let nameLabel:UILabel = UILabel(frame: nameLabelFrame)
                let nameLabel:UILabel = UILabel()
                nameLabel.text = contactItem.name
                nameLabel.textAlignment = NSTextAlignment.Center
                nameLabel.font = UIFont.systemFontOfSize(12)
                cell.contentView.addSubview(nameLabel)
               
                constrain(nameLabel, cell) { nameLabel, cell in
                    nameLabel.bottom == cell.bottom
                    nameLabel.centerX == cell.centerX
                }
                
                if isRemoveMode {
                    //here is got reusable cell, not draw it again, just need add extra delete button
                    let removeBadgeButton:UIButton = UIButton()
                    removeBadgeButton.setBackgroundImage(UIImage(named: "remove_badge"), forState: UIControlState.Normal)
                    removeBadgeButton.tag = indexPath.row
                    removeBadgeButton.addTarget(self, action: Selector("removeSelectedPerson:"), forControlEvents: UIControlEvents.TouchUpInside)
                    cell.contentView.addSubview(removeBadgeButton)
                   
                    constrain(removeBadgeButton, cell) { removeBadgeButton, cell in
                        removeBadgeButton.left == cell.right 10
                        removeBadgeButton.top == cell.top 5
                    }
                }
            }
        }

结果问题依旧。

3.把字视图都加到cell,而不是cell.contentView上:

cell.contentView.addSubview(removeBadgeButton)

都换成:

cell.addSubview(removeBadgeButton)

也还是不行。

4.此时已经意识到了:

是由于用了:

let cell:UICollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier(StrIdConversationManageCollectionViewCell, forIndexPath: indexPath)

的dequeueReusableCellWithReuseIdentifier

所以cell都是复用了

-》之前已经存在的cell,会被随机获得拿来复用

-》导致之前的cell中还有头像图片,还有nameLabel

-》所以此处要去删除掉已有的字视图,再重新绘制,即可:

5.后来再去优化,解决,当已经处于remove模式时,点击减号,结果之前加的remove button,却还保留,的问题。

6.最终代码是:

    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        print("ConversationManageViewController cellForItemAtIndexPath")
        let cell:UICollectionViewCell = collectionView.dequeueReusableCellWithReuseIdentifier(StrIdConversationManageCollectionViewCell, forIndexPath: indexPath)
       
//        if isRemoveMode {
            //remove previous added subview
            // isRemoveMode==true: header image, name label
            // isRemoveMode==false: header image, name label, remove button
            //otherwise will cause overlapp namelabel
            let prevAddedSubViews = cell.contentView.subviews
//            print("prevAddedSubViews=\(prevAddedSubViews)")
            for eachPreAddedSubView in prevAddedSubViews {
                eachPreAddedSubView.removeFromSuperview()
            }
//        }
       
        if let contactItem = getContactItem(indexPath) {
            let contactImage = contactItem.headerImageLarge
            let contactImageView:UIImageView = UIImageView(image: contactImage)
            cell.contentView.addSubview(contactImageView)
           
            constrain(contactImageView, cell) { contactImageView, cell in
                contactImageView.top == cell.top
                contactImageView.centerX == cell.centerX
            }
           
            if !isSperialItem(contactItem) {
                let nameLabel:UILabel = UILabel()
                nameLabel.text = contactItem.name
                nameLabel.textAlignment = NSTextAlignment.Center
                nameLabel.font = UIFont.systemFontOfSize(12)
                cell.contentView.addSubview(nameLabel)
               
                constrain(nameLabel, cell) { nameLabel, cell in
                    nameLabel.bottom == cell.bottom
                    nameLabel.centerX == cell.centerX
                }
               
                constrain(nameLabel, contactImageView) { nameLabel, contactImageView in
                    nameLabel.top == contactImageView.bottom + collectionViewCellPaddingY
                }
//                constrain(nameLabel, contactImageView) { nameLabel, contactImageView in
//                    distribute(by: 10, vertically: nameLabel, contactImageView)
//                }
               
                if isRemoveMode {
                    //here is got reusable cell, not draw it again, just need add extra delete button
                    let removeBadgeButton:UIButton = UIButton()
                    removeBadgeButton.setBackgroundImage(UIImage(named: "remove_badge"), forState: UIControlState.Normal)
                    removeBadgeButton.tag = indexPath.row
                    removeBadgeButton.addTarget(self, action: Selector("removeSelectedPerson:"), forControlEvents: UIControlEvents.TouchUpInside)
                    cell.contentView.addSubview(removeBadgeButton)
                   
                    constrain(removeBadgeButton, cell) { removeBadgeButton, cell in
                        removeBadgeButton.left == cell.right 10
                        removeBadgeButton.top == cell.top 5
                    }
                }
            }
        }
       
        return cell
    }
                    dispatch_async(dispatch_get_main_queue(), { () -> Void in
                        self.deleteContactItem(indexPath)
                        self.collectionView.deleteItemsAtIndexPaths([indexPath])
                    })
    }

效果是:

再去点击减号,即可还原:

转载请注明:在路上 » [已解决]swift中UICollectionViewCell在reloadData()之后显示内容出现重叠现象

发表我的评论
取消评论

表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
91 queries in 0.147 seconds, using 22.17MB memory