UICollectionViewListCell 始终将高度设置为 44,这与我在 AutoLayout 中设置的其他任何内容相冲突

Qua*_*ntm 6 ios autolayout uicollectionview uicollectionviewcell swift

我正在使用 newUICollectionViewListCellUIContentConfigurations,它们非常棒,但我不知道如何更改UIKit自动为这些单元格设置的默认单元格高度 44。这是一个示例单元格:


class TextFieldCell: UICollectionViewListCell {

    struct ContentConfiguration: UIContentConfiguration, Hashable {

        struct Handlers: ContentConfigurationHandlers {
            var onTextChanged: ((_ newText: String) -> Void)?
        }

        var handlers: Handlers?

        var text: String?
        var placeholder: String?
        var keyboardType: UIKeyboardType?

        func makeContentView() -> UIView & UIContentView {
            ContentView(configuration: self)
        }

        func updated(for state: UIConfigurationState) -> TextFieldCell.ContentConfiguration {
            guard let state = state as? UICellConfigurationState else { return self }
            var updatedConfiguration = self
            return updatedConfiguration
        }

    }

    class ContentView: UIView, UIContentView, UITextFieldDelegate {
        private var appliedConfiguration: TextFieldCell.ContentConfiguration!
        var configuration: UIContentConfiguration {
            get {
                appliedConfiguration
            }
            set {
                guard let newConfiguration = newValue as? TextFieldCell.ContentConfiguration else {
                    return
                }

                apply(configuration: newConfiguration)
            }
        }

        let nameTextField: UITextField = UITextField()

        init(configuration: TextFieldCell.ContentConfiguration) {
            super.init(frame: .zero)
            setupInternalViews()
            apply(configuration: configuration)
        }

        required init?(coder: NSCoder) {
            fatalError()
        }

        private func setupInternalViews() {
            addSubview(nameTextField)

            nameTextField.delegate = self
            nameTextField.clearButtonMode = .always
            nameTextField.autocapitalizationType = .sentences
            
            nameTextField.addAction(UIAction(handler: { [unowned self] action in
                textChanged()
            }), for: .editingChanged)

            NSLayoutConstraint.activate([
                nameTextField.leadingAnchor.constraint(equalTo: leadingAnchor),
                nameTextField.topAnchor.constraint(equalTo: topAnchor),
                nameTextField.trailingAnchor.constraint(equalTo: trailingAnchor),
                nameTextField.bottomAnchor.constraint(equalTo: bottomAnchor),
                nameTextField.heightAnchor.constraint(equalToConstant: 200) // Example height
            ])
        }

        /// Apply a new configuration.
        /// - Parameter configuration: The new configuration
        private func apply(configuration: TextFieldCell.ContentConfiguration) {
            guard appliedConfiguration != configuration else { return }
            appliedConfiguration = configuration
            
            nameTextField.text = appliedConfiguration.text
            nameTextField.placeholder = appliedConfiguration.placeholder
            nameTextField.keyboardType = appliedConfiguration.keyboardType ?? .default
            nameTextField.autocapitalizationType = .sentences
        }
        
        private func textChanged() {
            appliedConfiguration.handlers?.onTextChanged?(nameTextField.text ?? "")
        }

        func textFieldShouldReturn(_ textField: UITextField) -> Bool {
            textField.resignFirstResponder()
            return true
        }
    }
}

Run Code Online (Sandbox Code Playgroud)

重要的部分是设置文本字段的布局约束:

NSLayoutConstraint.activate([
    nameTextField.leadingAnchor.constraint(equalTo: leadingAnchor),
    nameTextField.topAnchor.constraint(equalTo: topAnchor),
    nameTextField.trailingAnchor.constraint(equalTo: trailingAnchor),
    nameTextField.bottomAnchor.constraint(equalTo: bottomAnchor),
    nameTextField.heightAnchor.constraint(equalToConstant: 200) // Example height
])
Run Code Online (Sandbox Code Playgroud)

我将高度设置为 200(作为示例)。当我运行这个时,我得到这个:

2020-11-08 11:12:01.805610+0100 Sophia[11924:720407] [LayoutConstraints] Unable to simultaneously satisfy constraints.
    Probably at least one of the constraints in the following list is one you don't want. 
    Try this: 
        (1) look at each constraint and try to figure out which you don't expect; 
        (2) find the code that added the unwanted constraint or constraints and fix it. 
    (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 
(
    "<NSAutoresizingMaskLayoutConstraint:0x600001111f40 h=--& v=--& _TtCC6Sophia13TextFieldCell11ContentView:0x7fc0ed27a1c0.height == 44   (active)>",
    "<NSLayoutConstraint:0x6000011198b0 UITextField:0x7fc0ed27a370.height == 200   (active)>",
    "<NSLayoutConstraint:0x600001119810 V:|-(0)-[UITextField:0x7fc0ed27a370]   (active, names: '|':_TtCC6Sophia13TextFieldCell11ContentView:0x7fc0ed27a1c0 )>",
    "<NSLayoutConstraint:0x600001119b80 UITextField:0x7fc0ed27a370.bottom == _TtCC6Sophia13TextFieldCell11ContentView:0x7fc0ed27a1c0.bottom   (active)>"
)

Will attempt to recover by breaking constraint 
<NSLayoutConstraint:0x6000011198b0 UITextField:0x7fc0ed27a370.height == 200   (active)>

Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.
The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKitCore/UIView.h> may also be helpful.
Run Code Online (Sandbox Code Playgroud)

如您所见,有一个自动生成的高度约束将高度设置为44,这会产生冲突。为什么会在那里?我该如何改变它?

Den*_*nis 5

我遇到了同样的问题。我现在可以为自己描述这一点的最好方法是,涉及的约束UIContentView,其中您希望它拥有的解决方案只是所有可能解决方案中的“最佳”解决方案。

因此,在与您的情况几乎相同的情况下,我通过将底部约束的优先级降低到 来解决这个问题.defaultHigh。最初我认为也许将高度的优先级设置为较低的值就足够了,但随后它使用了该视图intrinsicContentSize(在我的例子中它是 a UIImageView)。这不是我想要的。

总结来说:

let bottomConstraint = nameTextField.bottomAnchor.constraint(equalTo: bottomAnchor)
bottomConstraint.priority = .defaultHigh
NSLayoutConstraint.activate([
    nameTextField.leadingAnchor.constraint(equalTo: leadingAnchor),
    nameTextField.topAnchor.constraint(equalTo: topAnchor),
    nameTextField.trailingAnchor.constraint(equalTo: trailingAnchor),
    bottomConstraint,
    nameTextField.heightAnchor.constraint(equalToConstant: 200) // Example height
])
Run Code Online (Sandbox Code Playgroud)

应该修复它。