【问题标题】:How to resolve "API error: returned 0 width, assuming UIViewNoIntrinsicMetric" when sizing inputAccessoryView?如何在调整 inputAccessoryView 大小时解决“API 错误:返回 0 宽度,假设 UIViewNoIntrinsicMetric”?
【发布时间】:2020-04-11 13:21:58
【问题描述】:

我将此处的代码示例:https://stackoverflow.com/a/46510833/784637 粘贴到新的单一视图应用程序中,将inputAccessoryView 固定在屏幕底部:


class ViewController: UIViewController {

    override var canBecomeFirstResponder: Bool { return true }

    var _inputAccessoryView: UIView!

    override var inputAccessoryView: UIView? {

        if _inputAccessoryView == nil {

            _inputAccessoryView = CustomView()
            _inputAccessoryView.backgroundColor = UIColor.groupTableViewBackground

            let textField = UITextField()
            textField.borderStyle = .roundedRect

            _inputAccessoryView.addSubview(textField)

            _inputAccessoryView.autoresizingMask = .flexibleHeight

            textField.translatesAutoresizingMaskIntoConstraints = false

            textField.leadingAnchor.constraint(
                equalTo: _inputAccessoryView.leadingAnchor,
                constant: 8
            ).isActive = true

            textField.trailingAnchor.constraint(
                equalTo: _inputAccessoryView.trailingAnchor,
                constant: -8
            ).isActive = true

            textField.topAnchor.constraint(
                equalTo: _inputAccessoryView.topAnchor,
                constant: 8
            ).isActive = true

            // this is the important part :

            textField.bottomAnchor.constraint(
                equalTo: _inputAccessoryView.layoutMarginsGuide.bottomAnchor,
                constant: -8
            ).isActive = true
        }

        return _inputAccessoryView
    }

    override func loadView() {

        let tableView = UITableView()
        tableView.keyboardDismissMode = .interactive

        view = tableView
    }
}

class CustomView: UIView {

    // this is needed so that the inputAccesoryView is properly sized from the auto layout constraints
    // actual value is not important

    override var intrinsicContentSize: CGSize {
        return CGSize.zero
    }
}

当我运行模拟器时,一切看起来都很好,但是当我点击 UITextField 时控制台会报告此错误:

API error: <_UIKBCompatInputView: 0x7fc725f20520; frame = (0 0; 0 0); layer = <CALayer: 0x60000232e6c0>> returned 0 width, assuming UIViewNoIntrinsicMetric

我尝试将intrinsicContentSize 覆盖为非零值,例如CGSize(width: 50, height: 50),但仍然出现此错误。我该如何解决这个问题?

【问题讨论】:

    标签: ios swift iphone inputaccessoryview


    【解决方案1】:

    发生这种情况是因为您拥有所有 required 约束,但最初返回的内部大小为 zero。因此布局系统试图以零大小布置您的视图,无法满足您的约束,因此破坏了文本字段的大小。解决此问题的最简单(也许是最好的?)方法是将约束的优先级降低到略低于required 的值,以便系统可以暂时中断它们。

    但是在我们查看代码之前,有一个架构建议怎么样:如果您需要CustomView,为什么不直接在其中创建您的文本字段,而不是您的视图控制器负责将文本字段注入本质上是虚拟视图。

    class CustomView: UIView {
    
      private let textField = UITextField(frame: .zero)
    
      init(frame: CGRect) {
        backgroundColor = .groupTableViewBackground
    
        // do your textfield setup here
        addSubview(textField)
        textField.translatesAutoresizingMaskIntoConstraints = false
        textField.borderStyle = .roundedRect
    
        // set up your constraints
        let constraints: [NSLayoutConstraint] = [
          textField.topAnchor.constraint(equalTo: topAnchor, constant: 8),
          textField.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -8),
          textField.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 8),
          textField.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -8),
        ]
    
        // slightly reduce the priority of all of your constraints
        constraints.forEach { $0.priority = UILayoutPriority(rawValue: 999) }
    
        // activate them
        NSLayoutConstraint.activate(constraints)
      }
    }
    

    现在,在您的视图控制器中,您只需将附件视图声明为:

    override var inputAccessoryView = CustomView()
    

    不需要私有存储、隐式解包选项等。

    【讨论】:

    • 感谢您的建议 - 我继续并降低了约束的优先级,但仍然遇到同样的错误。
    猜你喜欢
    • 2017-12-28
    • 2018-04-15
    • 1970-01-01
    • 2021-10-16
    • 1970-01-01
    • 2011-12-29
    • 2019-05-23
    • 1970-01-01
    • 2022-09-14
    相关资源
    最近更新 更多