如何解决键盘折叠时 inputAccessoryView 不尊重 safeAreaLayoutGuide
我正在尝试使 inputAccessoryView 正常工作。也就是说,在这种情况下,我希望能够以两种可能的状态显示 UIToolbar:
我对这个主题进行了广泛的研究,但我能找到的每一个建议都有一堆似乎与 Apple 工程建议的解决方案不一致的解决方法。基于 openradar 票证,Apple 工程部提出了以下解决方案:
您有责任尊重输入附件视图的 安全区域插入。我们以这种方式设计它,以便开发人员可以提供 背景视图(即,请参阅 Safari 的 Find on Page 输入附件视图) 并根据 safeAreaInsets 布置内容视图。这是 实现起来相当简单。有一个视图层次结构,你 有一个容器视图和一个内容视图。容器视图可以有 背景颜色或包含其整个背景的背景视图 bounds,它基于 safeAreaInsets 布局它的内容视图。如果 您正在使用自动布局,这就像设置内容一样简单 视图的底部锚点等于它的超级视图的 安全区域布局指南。
以上链接是: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,height: 50)
containerView.backgroundColor = .systemYellow
containerView.translatesAutoresizingMaskIntoConstraints = false
// CONTENT VIEW
contentView.frame = CGRect(x: 0,height: 50)
contentView.backgroundColor = .systemPink
contentView.translatesAutoresizingMaskIntoConstraints = false
containerView.addSubview(contentView)
// TOOLBAR
toolbar = UIToolbar(frame: CGRect(x: 0,height: 50))
let flexibleSpace = UIBarButtonItem(barButtonSystemItem: .flexibleSpace,target: self,action: nil)
let doneButton = UIBarButtonItem(title: "Done",style: .done,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)])
}
}
,
我能够通过包装工具栏(在我的例子中为聊天输入栏)并将其限制为 top/right/left
+ bottom
到包装器的安全区域来实现效果。
我会在下面留下一个大概的食谱。
在您的视图控制器中:
override var inputAccessoryView: UIView? {
keyboardHelper
}
override var canBecomeFirstResponder: Bool {
true
}
lazy var keyboardHelper: InputBarWrapper = {
let wrapper = InputBarWrapper()
let inputBar = InputBar()
helper.addSubview(inputBar)
inputBar.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
inputBar.topAnchor.constraint(equalTo: helper.topAnchor),inputBar.leftAnchor.constraint(equalTo: helper.leftAnchor),inputBar.bottomAnchor.constraint(equalTo:
helper.safeAreaLayoutGuide.bottomAnchor),inputBar.rightAnchor.constraint(equalTo: helper.rightAnchor),])
return wrapper
}()
工具栏包装子类:
class InputBarWrapper: UIView {
var desiredHeight: CGFloat = 0 {
didSet { invalidateIntrinsicContentSize() }
}
override var intrinsicContentSize: CGSize {
CGSize(width: 0,height: desiredHeight)
}
required init?(coder aDecoder: NSCoder) {
fatalError()
}
override init(frame: CGRect) {
super.init(frame: frame);
autoresizingMask = .flexibleHeight
backgroundColor = UIColor.systemGreen.withAlphaComponent(0.2)
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。