【问题标题】:Is there a way to stop UICollectionView from reusing cells?有没有办法阻止 UICollectionView 重用单元格?
【发布时间】:2019-08-05 08:25:10
【问题描述】:

我正在尝试在 Swift 4 中创建一个表,其中包含 UITextFields 和 UILabels。

由于 UICollectionView 中有很多行,因此需要滚动。

但是,当我滚动时,重用功能会弄乱布局。

除了 UICollectionView 还有其他选择吗?在 Android 中,我创建了一个类似的应用程序,TableLayout 呈现所有单元格并且在滚动时不会导致任何错误。

所需的布局

向下再向上滚动后的布局

我用这个方法重用:

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

    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! EUPCell

    cell.row = indexPath.section
    cell.column = indexPath.row
    //print("row: \(cell.row) column: \(cell.column)")
    CellCreation.make(self, indexPath, self.textfields, cell)

    return cell
}

static func make(_ view: EUPViewController,
                 _ indexPath: IndexPath,
                 _ textfields: TextFields,
                 _ cell: EUPCell) {

    let row = indexPath.section
    let column = indexPath.row

    if (row == 0 && column == 0) {
        CellCreation.makeLabel("Datum", cell)
    } else if (row == 0 && column == 1) {
        CellCreation.makeLabel("Skift", cell)
    } else if (row == 0 && column == 2) {
        CellCreation.makeLabel("EUP Operatör", cell)
    } else if (row == 0 && column == 3) {
        CellCreation.makeLabel("Kund", cell)
    } else if (row == 0 && column == 4) {
        CellCreation.makeLabel("Kontaktperson", cell)
    } else if (row == 0 && column == 5) {
        CellCreation.makeLabel("Artikel", cell)
    } else if (row == 0 && column == 6) {
        CellCreation.makeLabel("Plats", cell)
    } else if (row == 1 && (column >= 0 && column <= 6)) {
        CellCreation.makeInput(view, cell, textfields, false)
    } else if (row == 2 && column == 0) {
        CellCreation.makeLabel("Artikel nr", cell)
    } else if (row == 2 && column == 1) {
        CellCreation.makeLabel("Kolli nr", cell)
    } else if (row == 2 && column == 2) {
        CellCreation.makeLabel("FS nr", cell)
    } else if (row == 2 && column == 3) {
        CellCreation.makeLabel("Övrigt", cell)
    } else if (row == 2 && column == 4) {
        CellCreation.makeLabel("Antal i pall", cell)
    } else if (row == 2 && column == 5) {
        CellCreation.makeLabel("Antal OK", cell)
    } else if (row == 2 && column == 6) {
        CellCreation.makeLabel("Antal NOK", cell)
    } else if (row == 2 && column == 7) {
        CellCreation.makeLabel("Åtgärdade", cell)
    } else if (row == 2 && column == 8) {
        CellCreation.makeLabel("Utsorterade", cell)
    } else if ((row >= 3 && row <= 32) && (column >= 0 && column <= 8)) {
        columnCheck(view, column, cell, textfields)
    }
}

/**
 Uses a numeric keyboard for all UITextFields, except for those in
 the "Övrigt" column. This is equivalent to the fourth column
 of the table.
 */
static func columnCheck(_ view: EUPViewController,
                        _ column: Int,
                        _ cell: EUPCell,
                        _ textfields: TextFields) {

    if (column == 3) {
        CellCreation.makeInput(view, cell, textfields, false)
    } else {
        CellCreation.makeInput(view, cell, textfields, true)
    }
}

/**
 Creates an UILabel in the Cell. The font size
 is larger on an iPad.
 */
static func makeLabel(_ text: String, _ cell: EUPCell) {
    let label: UILabel
    let desiredFontSize: CGFloat

    label = UILabel(frame: CGRect(x: 0, y: 0, width: cell.frame.width, height: cell.frame.height))

    if (UIDevice.modelName.contains("iPhone")) {
        desiredFontSize = 8.0
    } else {
        desiredFontSize = 13.0
    }

    let font = UIFont(name: desiredFont, size: desiredFontSize)
    label.font = font

    label.textAlignment = .center

    label.text = text
    cell.addSubview(label)
}

/**
 Creates an UITextField in the given Cell.
 */
static func makeInput(_ view: EUPViewController,
                      _ cell: EUPCell,
                      _ textfields: TextFields,
                      _ isNumeric: Bool) {

    let textField = UITextField(frame: CGRect(x: 0, y: 0, width: cell.frame.width, height: cell.frame.height))

    let desiredFontSize: CGFloat

    if (UIDevice.modelName.contains("iPad")) {
        desiredFontSize = 14.0
    } else {
        desiredFontSize = 13.0
    }

    let font = UIFont(name: desiredFont, size: desiredFontSize)
    textField.font = font

    textField.delegate = view

    textField.borderStyle = .roundedRect
    textField.autocorrectionType = .no
    textField.textAlignment = .left

    textField.contentVerticalAlignment = .center

    if (isNumeric) {
        textField.keyboardType = .asciiCapableNumberPad
    } else {
        textField.keyboardType = UIKeyboardType.default
    }

    textfields.add(textField)

    cell.addSubview(textField)
}

【问题讨论】:

  • 是的,使用UIScrollView。顺便说一句,UICollectionView 造成了什么混乱?
  • 很可能是你实现的复用方法错误。
  • 不要试图避免重用机制。这是一项重要的内存/CPU 优化。 Android 使用与其 CycleView 类似的系统。你必须理解它并正确使用它。
  • 寻找编写更好的代码而不是寻找更好的 UI ????
  • 根据代码重用函数 不会 弄乱布局 做。

标签: ios swift uicollectionview tablelayout uicollectionviewlayout


【解决方案1】:
  • 为避免这种混乱,您需要使用两种不同类型的单元格。

    1. 标签作为标题。
    2. 将 TextField 作为输入。
  • 现在你需要在numberOfSectionsInCollectionView中返回2

  • 现在在sizeForItem 中设置您的单元格大小。确保为每个单元格添加了适当的条件。

  • cellForItemAt

    if indexPath.section == 0  {
        if indexPath.row == 0  {
        // dequeue label Cell
        }
        // dequeue Textfield Cell            
    }
    else {
        if indexPath.row == 0  {
        // dequeue label Cell
        }
        // dequeue Textfield Cell    
    }
    

注意:要正确管理文本字段的数据,您需要这样做 -> Swift UICollectionView Textfields

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-11-22
    • 1970-01-01
    • 2014-09-10
    • 1970-01-01
    • 2019-10-20
    • 1970-01-01
    • 2011-01-18
    • 1970-01-01
    相关资源
    最近更新 更多