ios - 键盘折叠时 inputAccessoryView 不遵守 safeAreaLayoutGuide
问题描述
我正在尝试让 inputAccessoryView 正常工作。也就是说,在这种情况下,我希望能够以两种可能的状态显示 UIToolbar:
- 键盘上方 - 标准和预期行为
- 当键盘被关闭时在屏幕底部(例如模拟器中的 command + K) - 在这种情况下,让bottomAnchor 尊重底部的safeAreaLayoutGuide。
我已经广泛研究了这个主题,但我能找到的每一个建议都有一堆似乎与 Apple 工程建议的解决方案不一致的解决方法。基于 openradar 票证,Apple 工程师提出了这个解决方案,方法如下:
尊重输入附件视图的 safeAreaInsets 是您的责任。我们以这种方式设计它,以便开发人员可以提供背景视图(即,参见 Safari 的 Find on Page 输入辅助视图)并根据 safeAreaInsets 布置内容视图。这很容易实现。有一个视图层次结构,其中有一个容器视图和一个内容视图。容器视图可以具有背景颜色或包含其整个边界的背景视图,并且它基于 safeAreaInsets 布置其内容视图。如果您使用自动布局,这就像将内容视图的底部锚点设置为等于它的超级视图的 safeAreaLayoutGuide 一样简单。
以上链接为:http ://www.openradar.me/34411433
因此,我构建了一个简单的 xCode 项目(iOS App 模板),其中包含以下代码:
class ViewController: UIViewController {
var field = UITextField()
var containerView = UIView()
var contentView = UIView()
var toolbar = UIToolbar()
override func viewDidLoad() {
super.viewDidLoad()
// TEXTFIELD
field = UITextField(frame: CGRect(x: 20, y: 100, width: view.frame.size.width, height: 50))
field.placeholder = "Enter name..."
field.backgroundColor = .secondarySystemBackground
field.inputAccessoryView = containerView
view.addSubview(field)
// CONTAINER VIEW
containerView.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: 50)
containerView.backgroundColor = .systemYellow
containerView.translatesAutoresizingMaskIntoConstraints = false
// CONTENT VIEW
contentView.frame = CGRect(x: 0, y: 0, width: view.frame.size.width, height: 50)
contentView.backgroundColor = .systemPink
contentView.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(contentView)
// TOOLBAR
toolbar = UIToolbar(frame: CGRect(x: 0, y: 0, width: view.frame.size.width, height: 50))
let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace, target: self, action: nil)
let doneButton = UIBarButtonItem(title: "Done", style: .done, target: self, action: #selector(didTapDone))
toolbar.setItems([flexibleSpace, doneButton], animated: true)
toolbar.backgroundColor = .systemGreen
toolbar.translatesAutoresizingMaskIntoConstraints = false
contentView.addSubview(toolbar)
NSLayoutConstraint.activate([
contentView.topAnchor.constraint(equalTo: containerView.topAnchor),
contentView.leadingAnchor.constraint(equalTo: containerView.leadingAnchor),
contentView.trailingAnchor.constraint(equalTo: containerView.trailingAnchor),
contentView.bottomAnchor.constraint(equalTo: contentView.superview!.safeAreaLayoutGuide.bottomAnchor),
toolbar.topAnchor.constraint(equalTo: contentView.topAnchor),
toolbar.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
toolbar.trailingAnchor.constraint(equalTo: contentView.trailingAnchor),
toolbar.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
])
}
@objc private func didTapDone() {
print("done tapped")
}
}
结果在键盘可见时有效,但在键盘关闭后无效:
我玩弄了各种视图的高度,结果混合在一起,并使容器视图框架的高度更大(例如 100),当键盘折叠时确实显示工具栏,它也使工具栏太高,不适合键盘可见的。
显然,我正在解决一些自动布局约束问题,但我无法解决,并且希望任何提供符合 Apple 建议的可行解决方案的反馈。
提前致谢。
解决方案
就我而言,我使用以下方法:
import UIKit
extension UIView {
func setDimensions(height: CGFloat, width: CGFloat) {
translatesAutoresizingMaskIntoConstraints = false
heightAnchor.constraint(equalToConstant: height).isActive = true
widthAnchor.constraint(equalToConstant: width).isActive = true
}
func setHeight(_ height: CGFloat) {
translatesAutoresizingMaskIntoConstraints = false
heightAnchor.constraint(equalToConstant: height).isActive = true
}
}
class CustomTextField: UITextField {
override init(frame: CGRect) {
super.init(frame: frame)
}
convenience init(placeholder: String) {
self.init(frame: .zero)
configureUI(placeholder: placeholder)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configureUI(placeholder: String) {
let spacer = UIView()
spacer.setDimensions(height: 50, width: 12)
leftView = spacer
leftViewMode = .always
borderStyle = .none
textColor = .white
keyboardAppearance = .dark
backgroundColor = UIColor(white: 1, alpha: 0.1)
setHeight(50)
attributedPlaceholder = NSAttributedString(string: placeholder, attributes: [.foregroundColor: UIColor(white: 1, alpha: 0.75)])
}
}
推荐阅读
- c++ - 是否观察到此获取围栏?
- pointers - Printf 无法使用返回的字符串指针正确打印
- macos - 如何在 Mac 上使用 VSCode 键盘快捷键?
- react-native - 选择器值不断被重置
- html - 如何为我的 youtube 视频添加最大尺寸?
- default-constructor - 默认和值构造的对象具有不同的类型
- php - 带有 index.php 异常的 Htaccess 重写规则
- node.js - 无法读取未定义 node.js discord.js 的属性“表情符号”
- maven-plugin - 如何在 Quarkus 中为 Gradle 的外部模块中的类创建 Jandex 索引
- android - Android 的第一步?