繁体   English   中英

UICollectionView单元格在reloadData()上大小不正确

[英]UICollectionView Cells resize incorrectly on reloadData()

我的视图有一个表格视图,每行都有一个集合视图。 收集单元具有一个文本字段(及其子类),一个标签和一个文本视图,它们全都是全尺寸的,除了一个以外,其他所有元素都根据单元位置隐藏了。

当文本字段之一被编辑时,委托(CollectionView)将新值传递回视图控制器以更改数组,然后重新加载适当的单元格,因为其中包含计算数据。

问题是第二次编辑一个文本字段时,两个单元格交换了宽度,如果再次编辑文本字段两次,似乎又交换回来了,但是边框停留在错误的位置。

初始加载后的表:

两次更换数量后的表

文本字段和视图委托方法

    func textFieldDidEndEditing(_ textField: UITextField) {
        let currencyField = textField as! CurrencyField
        let indexPath = indexPathForCellWithSubview(cellSubview: textField)!
        (dataSource as! DetailViewController).changeData(tableRow: tag, collectionItem: indexPath.row, newData: currencyField.decimal)
        let indexPaths: [IndexPath] = [IndexPath(row: 1, section: 0),IndexPath(row: 2, section: 0),IndexPath(row: 4, section: 0),IndexPath(row: 5, section: 0)]

        collectionViewLayout.invalidateLayout()
        reloadItems(at: indexPaths)
    }

    func textViewDidEndEditing(_ textView: UITextView) {
        let indexPath = indexPathForCellWithSubview(cellSubview: textView)!
        let indexPaths: [IndexPath] = [IndexPath(row: 1, section: 0),IndexPath(row: 2, section: 0),IndexPath(row: 4, section: 0),IndexPath(row: 5, section: 0)]
        let dec = textView.text!.decimalFromString()
        if(dec != 0){
            (dataSource as! DetailViewController).changeData(tableRow: tag, collectionItem: indexPath.row, newData: dec)
            reloadItems(at: indexPaths)
        } else {
            (dataSource as! DetailViewController).changeData(tableRow: tag, collectionItem: indexPath.row, newData: textView.text!)
        }
        collectionViewLayout.invalidateLayout()
    }

排列

var dummyData: [[Any]] = [
    ["Fencing garden",Decimal(1),Decimal(8500.00)],
    ["Ditching",Decimal(1),Decimal(1950.00)],
    ["Fred",Decimal(1),Decimal(1950.00)]]

像元宽度

let table4Cells: [Int] = [310,65,100,105]
let table6Cells: [Int] = [250,40,80,50,80,80]

数据设置与获取

func changeData(tableRow: Int, collectionItem: Int, newData: Any){

    var qty: Decimal = dummyData[tableRow][1] as! Decimal
    var cost: Decimal = dummyData[tableRow][2] as! Decimal
    var total: Decimal

    switch(collectionItem){
    case 1:
        qty = newData as! Decimal
    case 2:
        cost = newData as! Decimal
    case 3:
        total = newData as! Decimal
        cost = total / qty
    case 5:
        total = newData as! Decimal
        cost = (total / qty) / (1 + vatPC)
    default: dummyData[tableRow][collectionItem] = newData
    }
    dummyData[tableRow][1] = qty
    dummyData[tableRow][2] = cost
}

func collectionViewCellText(tag: Int, row: Int) -> String {
    var text: String = ""
    if(tag == 666){
        if(!vatRegistered && row == 3){
            return tableHeaderText[5]
        } else {
            return tableHeaderText[row]
        }
    } else {
        let qty: Decimal = dummyData[tag][1] as! Decimal
        let cost: Decimal = dummyData[tag][2] as! Decimal
        switch(row){
        case 3:
            if(vatRegistered){
                text = String(describing: vatPC * 100)
            } else {
                text = String(describing: qty * cost)
            }
        case 4:
            text = String(describing: cost * vatPC)
        case 5:
            text = String(describing: qty * (cost * (1 + vatPC)))
        default:
            text = String(describing: dummyData[tag][row])
        }
    }
    return text
}

索引路径处单元格的大小

    func collectionView(_ collectionView: UICollectionView,
                        layout collectionViewLayout: UICollectionViewLayout,
                        sizeForItemAt indexPath: IndexPath) -> CGSize {
        if(vatRegistered){
            return CGSize(width: self.table6Cells[indexPath.row], height:self.collectionCellHeight)
        }
        return CGSize(width: self.table4Cells[indexPath.row], height:self.collectionCellHeight)
    }

索引路径中行的单元格

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

        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell",
                                                      for: indexPath as IndexPath) as! InvoiceCollectionViewCell
        cell.textView.delegate = self
        if(collectionView is RJCollectionView){
            cell.currencyField.delegate = collectionView as! RJCollectionView
            cell.textView.delegate = collectionView as! RJCollectionView
        }
        if(collectionView.tag == 666){
            if(indexPath.row == 0){
                cell.addBorder(side: .left, thickness: 0.5, color: UIColor.black)
                cell.addBorder(side: .right, thickness: 0.5, color: UIColor.black)
                cell.addBorder(side: .top, thickness: 0.5, color: UIColor.black)
                cell.addBorder(side: .bottom, thickness: 0.5, color: UIColor.black)
            } else {
                cell.label.textAlignment = NSTextAlignment.center
                cell.textView.textAlignment = NSTextAlignment.center
                cell.addBorder(side: .right, thickness: 0.5, color: UIColor.black)
                cell.addBorder(side: .top, thickness: 0.5, color: UIColor.black)
                cell.addBorder(side: .bottom, thickness: 0.5, color: UIColor.black)
            }
        } else {
            if(indexPath.row == 0){
                cell.addBorder(side: .left, thickness: 0.5, color: UIColor.black)
                cell.addBorder(side: .right, thickness: 0.5, color: UIColor.black)
                cell.addBorder(side: .bottom, thickness: 0.5, color: UIColor.black)
            } else {
                cell.label.textAlignment = NSTextAlignment.center
                cell.textView.textAlignment = NSTextAlignment.center
                cell.addBorder(side: .right, thickness: 0.5, color: UIColor.black)
                cell.addBorder(side: .bottom, thickness: 0.5, color: UIColor.black)
            }
            if(vatRegistered){
                switch(indexPath.row){
                case 2,5: cell.textType(i: "CurrencyView")
                case 3:
                    cell.textType(i: "TextView")
                    cell.textView.isUserInteractionEnabled = false
                case 4:
                    cell.currencyField.isUserInteractionEnabled = false
                    cell.textType(i: "CurrencyView")
                default: cell.textType(i: "TextView")
                }

            } else {
                switch(indexPath.row){
                case 2,3: cell.textType(i: "CurrencyView")
                default: cell.textType(i: "TextView")
                }
            }
        }

        if(collectionView.tag == 0){
            print(cell.currencyField.bounds.width)
        }

        cell.text = collectionViewCellText(tag: collectionView.tag, row: indexPath.row)

        return cell
    }

注意:collectionview.tag是收集视图所在的表上的行。666是标题行。 vatRegistered是一个布尔值,当为true时会将集合视图的宽度设置为6个而不是4个单元格

更新:

我将整个项目剥离为一个次级项目,并将collectionview直接放入主视图中,但是仍然存在问题

似乎问题是由于contentView的大小未调整为单元格的大小而引起的,这似乎是iOS的一个错误,因此当单元格在重新加载时被推入并弹出堆栈时,它们会切换顺序,但是无论出于何种原因设置单元格大小未重置contentView的大小。

添加:

    cell.contentView.frame = cell.bounds;
    cell.contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

为sizeforitem流布局方法修复了奇怪的偏移量。

边框在错误的地方是我用来添加边框的uiview扩展,它只是将设置宽度的视图添加到要求的任何边缘,重新使用单元格时必须将其删除

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM