iPhone X如何处理View Controller inputAccessoryView?
iPhone X how to handle View Controller inputAccessoryView?
我有一个消息传递应用程序,它在全屏 table 视图的底部具有典型的 UI 文本字段设计。我将该文本字段设置为视图控制器的 inputAccessoryView
并调用 ViewController.becomeFirstResponder()
以使该字段显示在屏幕底部。
我知道这是 Apple 推荐的实现此 UI 结构的方法,它在 "classic" 设备上完美运行,但是当我在 iPhone X 模拟器上测试时,我注意到使用这种方法,文本字段不尊重新 "safe areas"。文本字段呈现在主屏幕指示器下方屏幕的最底部。
我查看了 HIG 文档,但没有发现任何关于视图控制器上的 inputAccessoryView
的有用信息。
这很困难,因为使用这种方法我实际上并不能直接控制任何约束,我只是设置 inputAccessoryView
并让视图控制器从那里处理 UI .所以我不能只将字段限制在新的安全区域。
有没有人找到这方面的好文档或知道在 iPhone X 上运行良好的替代方法?
我只是将安全区域添加到 inputAccessoryView(Xcode 处的复选框)。并更改底部 space 约束等于安全区域底部而不是 inputAccessoryView 根视图底部。
Constraint
And result
这似乎是一个 iOS 错误,并且有一个 rdar 问题:inputAccessoryViews should respect safe area inset with external keyboard on iPhone X
我想这应该在 iOS 更新中修复,当 iPhone X 出现时。
这是 iPhone X 上 inputAccessoryViews 的一个普遍问题。
inputAccessoryView 忽略其 window.
的 safeAreaLayoutGuides
要修复它,我们必须在视图移动到其 window 时在您的 class 中手动添加约束:
override func didMoveToWindow() {
super.didMoveToWindow()
if #available(iOS 11.0, *) {
if let window = self.window {
self.bottomAnchor.constraintLessThanOrEqualToSystemSpacingBelow(window.safeAreaLayoutGuide.bottomAnchor, multiplier: 1.0).isActive = true
}
}
}
PS: 这里的self指的是inputAccessoryView。
我在这里写的很详细:http://ahbou.org/post/165762292157/iphone-x-inputaccessoryview-fix
直到安全插图由 iOS 自动引导,简单的解决方法是将您的附件包装在容器视图中并在附件视图和容器视图之间设置底部 space 约束以匹配安全区域插图window。
注意:当然,当 iOS 更新修复了附件视图的底部间距时,此变通方法可以将附件视图距底部的间距加倍。
例如
- (void) didMoveToWindow {
[super didMoveToWindow];
if (@available(iOS 11.0, *)) {
self.bottomSpaceConstraint.constant = self.window.safeAreaInsets.bottom;
}
}
inputAccessoryView
和 iPhone X
上的安全区域
当键盘不可见时,inputAccessoryView
固定在屏幕的最底部。没有办法解决这个问题,我认为这是预期的行为。
视图的 layoutMarginsGuide
(iOS 9+) 和 safeAreaLayoutGuide
(iOS 11) 属性设置为 inputAccessoryView
都尊重安全区域,即 iPhone X :
- 当键盘不可见时,
bottomAnchor
占主页按钮区域
- 当显示键盘时,
bottomAnchor
位于inputAccessoryView
的底部,因此在键盘 上方没有留下无用的space
工作示例:
import UIKit
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
}
}
See the result here
我刚刚创建了一个名为 SafeAreaInputAccessoryViewWrapperView 的快速 CocoaPod 来解决这个问题。它还使用自动布局约束动态设置包装视图的高度,因此您不必手动设置框架。支持 iOS 9+.
使用方法如下:
使用 SafeAreaInputAccessoryViewWrapperView(for:)
:
包装任何 UIView/UIButton/UILabel/etc
SafeAreaInputAccessoryViewWrapperView(for: button)
在你的某处存储对此的引用 class:
let button = UIButton(type: .system)
lazy var wrappedButton: SafeAreaInputAccessoryViewWrapperView = {
return SafeAreaInputAccessoryViewWrapperView(for: button)
}()
Return inputAccessoryView
中的参考:
override var inputAccessoryView: UIView? {
return wrappedButton
}
(可选)始终显示 inputAccessoryView
,即使键盘关闭时也是如此:
override var canBecomeFirstResponder: Bool {
return true
}
override func viewDidLoad() {
super.viewDidLoad()
becomeFirstResponder()
}
祝你好运!
在Xib中,在你设计的底部找到一个右约束,并将item设置为Safe Area
而不是Superview
:
之前:
修复:
之后:
-- 对于那些使用 JSQMessagesViewController 库的人 --
我提议基于 JSQ 最新 develop
分支提交的固定分支。
它正在使用 didMoveToWindow
解决方案(我相信来自@jki?)。不理想,但在等待 Apple 关于 inputAccessoryView
的安全区域布局指南附件或任何其他更好的修复的答案时值得尝试。
您可以将其添加到您的 Podfile 中,替换之前的 JSQ 行:
pod 'JSQMessagesViewController', :git => 'https://github.com/Tulleb/JSQMessagesViewController.git', :branch => 'develop', :inhibit_warnings => true
来自代码 (Swift 4)。想法 - 监控 layoutMarginsDidChange
事件并调整 intrinsicContentSize
.
public final class AutoSuggestionView: UIView {
private lazy var tableView = UITableView(frame: CGRect(), style: .plain)
private var bottomConstraint: NSLayoutConstraint?
var streetSuggestions = [String]() {
didSet {
if streetSuggestions != oldValue {
updateUI()
}
}
}
var handleSelected: ((String) -> Void)?
public override func initializeView() {
addSubview(tableView)
setupUI()
setupLayout()
// ...
updateUI()
}
public override var intrinsicContentSize: CGSize {
let size = super.intrinsicContentSize
let numRowsToShow = 3
let suggestionsHeight = tableView.rowHeight * CGFloat(min(numRowsToShow, tableView.numberOfRows(inSection: 0)))
//! Explicitly used constraint instead of layoutMargins
return CGSize(width: size.width,
height: suggestionsHeight + (bottomConstraint?.constant ?? 0))
}
public override func layoutMarginsDidChange() {
super.layoutMarginsDidChange()
bottomConstraint?.constant = layoutMargins.bottom
invalidateIntrinsicContentSize()
}
}
extension AutoSuggestionView {
private func updateUI() {
backgroundColor = streetSuggestions.isEmpty ? .clear : .white
invalidateIntrinsicContentSize()
tableView.reloadData()
}
private func setupLayout() {
let constraint0 = trailingAnchor.constraint(equalTo: tableView.trailingAnchor)
let constraint1 = tableView.leadingAnchor.constraint(equalTo: leadingAnchor)
let constraint2 = tableView.topAnchor.constraint(equalTo: topAnchor)
//! Used bottomAnchor instead of layoutMarginGuide.bottomAnchor
let constraint3 = bottomAnchor.constraint(equalTo: tableView.bottomAnchor)
bottomConstraint = constraint3
NSLayoutConstraint.activate([constraint0, constraint1, constraint2, constraint3])
}
}
用法:
let autoSuggestionView = AutoSuggestionView()
// ...
textField.inputAccessoryView = autoSuggestionView
结果:
如果您已经通过 nib 文件加载了自定义视图。
像这样添加一个方便的构造函数:
convenience init() {
self.init(frame: .zero)
autoresizingMask = .flexibleHeight
}
并覆盖 intrinsicContentSize
:
override var intrinsicContentSize: CGSize {
return .zero
}
In the nib
set the first bottom constraint (of views that should stay above the safe area) to safeArea
and the second one to superview
with lower priority
so it can be satisfied on older iOS.
只需为 JSQMessagesInputToolbar 添加一个扩展
extension JSQMessagesInputToolbar {
override open func didMoveToWindow() {
super.didMoveToWindow()
if #available(iOS 11.0, *) {
if self.window?.safeAreaLayoutGuide != nil {
self.bottomAnchor.constraintLessThanOrEqualToSystemSpacingBelow((self.window?.safeAreaLayoutGuide.bottomAnchor)!,
multiplier: 1.0).isActive = true
}
}
}
}
重复:
我刚刚创建了一个支持 iPhone X 的 project on Github。它符合新的安全区域布局指南。使用:
autoresizingMask = [.flexibleHeight]
截图:
最简单的答案(一行代码)
只需使用继承自 UIToolbar
而不是 UIView
的自定义视图作为您的 inputAccessoryView
。
另外不要忘记将该自定义视图的自动调整大小掩码设置为 UIViewAutoresizingFlexibleHeight
。
就是这样。稍后谢谢我。
对我有效但没有变通办法的解决方案:
我正在使用 UIInputViewController
通过覆盖 inputAccessoryViewController
属性 而不是 "main" 视图控制器中的 inputAccessoryView
来提供输入附件视图。
UIInputViewController
的 inputView
设置为我的自定义输入视图(UIInputView
的子类)。
真正对我有用的是将我的 UIInputView
的 allowsSelfSizing
属性 设置为 true
。输入视图中的约束使用安全区域,并以定义总视图高度的方式设置(类似于自动调整 table 视图单元格)。
经过大量研究和试验,这似乎是 尝试将 UIToolbar
与文本输入 inputAccessoryView
一起使用的有效解决方案。 (现有的大多数解决方案都是使用固定的附件视图,而不是将其分配给文本视图(并在键盘关闭时将其隐藏)。)
代码的灵感来自 。基本上,我们首先创建一个具有工具栏子视图的自定义视图:
class CustomInputAccessoryWithToolbarView: UIView {
public var toolbar: UIToolbar!
override init(frame: CGRect) {
super.init(frame: frame)
//
toolbar = UIToolbar(frame: frame)
// Below is adopted from
self.addSubview(toolbar)
self.autoresizingMask = .flexibleHeight
toolbar.translatesAutoresizingMaskIntoConstraints = false
toolbar.leadingAnchor.constraint(
equalTo: self.leadingAnchor,
constant: 0
).isActive = true
toolbar.trailingAnchor.constraint(
equalTo: self.trailingAnchor,
constant: 0
).isActive = true
toolbar.topAnchor.constraint(
equalTo: self.topAnchor,
constant: 0
).isActive = true
// This is the important part:
if #available(iOS 11.0, *) {
toolbar.bottomAnchor.constraint(
equalTo: self.safeAreaLayoutGuide.bottomAnchor,
constant: 0
).isActive = true
} else {
toolbar.bottomAnchor.constraint(
equalTo: self.layoutMarginsGuide.bottomAnchor,
constant: 0
).isActive = true
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//
// 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
}
}
然后您可以将其设置为 inputAccessoryView
用于正常的文本输入:(您应该指定帧大小以避免在 UIToolbar with UIBarButtonItem LayoutConstraint issue 中看到的警告)
let myAccessoryView = CustomInputAccessoryWithToolbarView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 44))
textView.inputAccessoryView = myAccessoryView
当你想与工具栏交互时(例如,在工具栏上设置项目),你可以简单地引用toolbar
变量:
myAccessoryView.toolbar.setItems(myToolbarItems, animated: true)
演示:(在模拟器中使用硬件键盘/Command+K)
之前:
之后:
我有一个消息传递应用程序,它在全屏 table 视图的底部具有典型的 UI 文本字段设计。我将该文本字段设置为视图控制器的 inputAccessoryView
并调用 ViewController.becomeFirstResponder()
以使该字段显示在屏幕底部。
我知道这是 Apple 推荐的实现此 UI 结构的方法,它在 "classic" 设备上完美运行,但是当我在 iPhone X 模拟器上测试时,我注意到使用这种方法,文本字段不尊重新 "safe areas"。文本字段呈现在主屏幕指示器下方屏幕的最底部。
我查看了 HIG 文档,但没有发现任何关于视图控制器上的 inputAccessoryView
的有用信息。
这很困难,因为使用这种方法我实际上并不能直接控制任何约束,我只是设置 inputAccessoryView
并让视图控制器从那里处理 UI .所以我不能只将字段限制在新的安全区域。
有没有人找到这方面的好文档或知道在 iPhone X 上运行良好的替代方法?
我只是将安全区域添加到 inputAccessoryView(Xcode 处的复选框)。并更改底部 space 约束等于安全区域底部而不是 inputAccessoryView 根视图底部。
Constraint
And result
这似乎是一个 iOS 错误,并且有一个 rdar 问题:inputAccessoryViews should respect safe area inset with external keyboard on iPhone X
我想这应该在 iOS 更新中修复,当 iPhone X 出现时。
这是 iPhone X 上 inputAccessoryViews 的一个普遍问题。 inputAccessoryView 忽略其 window.
的 safeAreaLayoutGuides要修复它,我们必须在视图移动到其 window 时在您的 class 中手动添加约束:
override func didMoveToWindow() {
super.didMoveToWindow()
if #available(iOS 11.0, *) {
if let window = self.window {
self.bottomAnchor.constraintLessThanOrEqualToSystemSpacingBelow(window.safeAreaLayoutGuide.bottomAnchor, multiplier: 1.0).isActive = true
}
}
}
PS: 这里的self指的是inputAccessoryView。
我在这里写的很详细:http://ahbou.org/post/165762292157/iphone-x-inputaccessoryview-fix
直到安全插图由 iOS 自动引导,简单的解决方法是将您的附件包装在容器视图中并在附件视图和容器视图之间设置底部 space 约束以匹配安全区域插图window。
注意:当然,当 iOS 更新修复了附件视图的底部间距时,此变通方法可以将附件视图距底部的间距加倍。
例如
- (void) didMoveToWindow {
[super didMoveToWindow];
if (@available(iOS 11.0, *)) {
self.bottomSpaceConstraint.constant = self.window.safeAreaInsets.bottom;
}
}
inputAccessoryView
和 iPhone X
上的安全区域
当键盘不可见时,
inputAccessoryView
固定在屏幕的最底部。没有办法解决这个问题,我认为这是预期的行为。视图的
layoutMarginsGuide
(iOS 9+) 和safeAreaLayoutGuide
(iOS 11) 属性设置为inputAccessoryView
都尊重安全区域,即 iPhone X :- 当键盘不可见时,
bottomAnchor
占主页按钮区域 - 当显示键盘时,
bottomAnchor
位于inputAccessoryView
的底部,因此在键盘 上方没有留下无用的space
- 当键盘不可见时,
工作示例:
import UIKit
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
}
}
See the result here
我刚刚创建了一个名为 SafeAreaInputAccessoryViewWrapperView 的快速 CocoaPod 来解决这个问题。它还使用自动布局约束动态设置包装视图的高度,因此您不必手动设置框架。支持 iOS 9+.
使用方法如下:
使用
包装任何 UIView/UIButton/UILabel/etcSafeAreaInputAccessoryViewWrapperView(for:)
:SafeAreaInputAccessoryViewWrapperView(for: button)
在你的某处存储对此的引用 class:
let button = UIButton(type: .system) lazy var wrappedButton: SafeAreaInputAccessoryViewWrapperView = { return SafeAreaInputAccessoryViewWrapperView(for: button) }()
Return
inputAccessoryView
中的参考:override var inputAccessoryView: UIView? { return wrappedButton }
(可选)始终显示
inputAccessoryView
,即使键盘关闭时也是如此:override var canBecomeFirstResponder: Bool { return true } override func viewDidLoad() { super.viewDidLoad() becomeFirstResponder() }
祝你好运!
在Xib中,在你设计的底部找到一个右约束,并将item设置为Safe Area
而不是Superview
:
之前:
修复:
之后:
-- 对于那些使用 JSQMessagesViewController 库的人 --
我提议基于 JSQ 最新 develop
分支提交的固定分支。
它正在使用 didMoveToWindow
解决方案(我相信来自@jki?)。不理想,但在等待 Apple 关于 inputAccessoryView
的安全区域布局指南附件或任何其他更好的修复的答案时值得尝试。
您可以将其添加到您的 Podfile 中,替换之前的 JSQ 行:
pod 'JSQMessagesViewController', :git => 'https://github.com/Tulleb/JSQMessagesViewController.git', :branch => 'develop', :inhibit_warnings => true
来自代码 (Swift 4)。想法 - 监控 layoutMarginsDidChange
事件并调整 intrinsicContentSize
.
public final class AutoSuggestionView: UIView {
private lazy var tableView = UITableView(frame: CGRect(), style: .plain)
private var bottomConstraint: NSLayoutConstraint?
var streetSuggestions = [String]() {
didSet {
if streetSuggestions != oldValue {
updateUI()
}
}
}
var handleSelected: ((String) -> Void)?
public override func initializeView() {
addSubview(tableView)
setupUI()
setupLayout()
// ...
updateUI()
}
public override var intrinsicContentSize: CGSize {
let size = super.intrinsicContentSize
let numRowsToShow = 3
let suggestionsHeight = tableView.rowHeight * CGFloat(min(numRowsToShow, tableView.numberOfRows(inSection: 0)))
//! Explicitly used constraint instead of layoutMargins
return CGSize(width: size.width,
height: suggestionsHeight + (bottomConstraint?.constant ?? 0))
}
public override func layoutMarginsDidChange() {
super.layoutMarginsDidChange()
bottomConstraint?.constant = layoutMargins.bottom
invalidateIntrinsicContentSize()
}
}
extension AutoSuggestionView {
private func updateUI() {
backgroundColor = streetSuggestions.isEmpty ? .clear : .white
invalidateIntrinsicContentSize()
tableView.reloadData()
}
private func setupLayout() {
let constraint0 = trailingAnchor.constraint(equalTo: tableView.trailingAnchor)
let constraint1 = tableView.leadingAnchor.constraint(equalTo: leadingAnchor)
let constraint2 = tableView.topAnchor.constraint(equalTo: topAnchor)
//! Used bottomAnchor instead of layoutMarginGuide.bottomAnchor
let constraint3 = bottomAnchor.constraint(equalTo: tableView.bottomAnchor)
bottomConstraint = constraint3
NSLayoutConstraint.activate([constraint0, constraint1, constraint2, constraint3])
}
}
用法:
let autoSuggestionView = AutoSuggestionView()
// ...
textField.inputAccessoryView = autoSuggestionView
结果:
如果您已经通过 nib 文件加载了自定义视图。
像这样添加一个方便的构造函数:
convenience init() {
self.init(frame: .zero)
autoresizingMask = .flexibleHeight
}
并覆盖 intrinsicContentSize
:
override var intrinsicContentSize: CGSize {
return .zero
}
In the
nib
set the first bottom constraint (of views that should stay above the safe area) tosafeArea
and the second one tosuperview
with lowerpriority
so it can be satisfied on older iOS.
只需为 JSQMessagesInputToolbar 添加一个扩展
extension JSQMessagesInputToolbar {
override open func didMoveToWindow() {
super.didMoveToWindow()
if #available(iOS 11.0, *) {
if self.window?.safeAreaLayoutGuide != nil {
self.bottomAnchor.constraintLessThanOrEqualToSystemSpacingBelow((self.window?.safeAreaLayoutGuide.bottomAnchor)!,
multiplier: 1.0).isActive = true
}
}
}
}
重复:
我刚刚创建了一个支持 iPhone X 的 project on Github。它符合新的安全区域布局指南。使用:
autoresizingMask = [.flexibleHeight]
截图:
最简单的答案(一行代码)
只需使用继承自 UIToolbar
而不是 UIView
的自定义视图作为您的 inputAccessoryView
。
另外不要忘记将该自定义视图的自动调整大小掩码设置为 UIViewAutoresizingFlexibleHeight
。
就是这样。稍后谢谢我。
对我有效但没有变通办法的解决方案:
我正在使用 UIInputViewController
通过覆盖 inputAccessoryViewController
属性 而不是 "main" 视图控制器中的 inputAccessoryView
来提供输入附件视图。
UIInputViewController
的 inputView
设置为我的自定义输入视图(UIInputView
的子类)。
真正对我有用的是将我的 UIInputView
的 allowsSelfSizing
属性 设置为 true
。输入视图中的约束使用安全区域,并以定义总视图高度的方式设置(类似于自动调整 table 视图单元格)。
经过大量研究和试验,这似乎是 尝试将 UIToolbar
与文本输入 inputAccessoryView
一起使用的有效解决方案。 (现有的大多数解决方案都是使用固定的附件视图,而不是将其分配给文本视图(并在键盘关闭时将其隐藏)。)
代码的灵感来自
class CustomInputAccessoryWithToolbarView: UIView {
public var toolbar: UIToolbar!
override init(frame: CGRect) {
super.init(frame: frame)
//
toolbar = UIToolbar(frame: frame)
// Below is adopted from
self.addSubview(toolbar)
self.autoresizingMask = .flexibleHeight
toolbar.translatesAutoresizingMaskIntoConstraints = false
toolbar.leadingAnchor.constraint(
equalTo: self.leadingAnchor,
constant: 0
).isActive = true
toolbar.trailingAnchor.constraint(
equalTo: self.trailingAnchor,
constant: 0
).isActive = true
toolbar.topAnchor.constraint(
equalTo: self.topAnchor,
constant: 0
).isActive = true
// This is the important part:
if #available(iOS 11.0, *) {
toolbar.bottomAnchor.constraint(
equalTo: self.safeAreaLayoutGuide.bottomAnchor,
constant: 0
).isActive = true
} else {
toolbar.bottomAnchor.constraint(
equalTo: self.layoutMarginsGuide.bottomAnchor,
constant: 0
).isActive = true
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//
// 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
}
}
然后您可以将其设置为 inputAccessoryView
用于正常的文本输入:(您应该指定帧大小以避免在 UIToolbar with UIBarButtonItem LayoutConstraint issue 中看到的警告)
let myAccessoryView = CustomInputAccessoryWithToolbarView(frame: CGRect(x: 0, y: 0, width: self.view.frame.size.width, height: 44))
textView.inputAccessoryView = myAccessoryView
当你想与工具栏交互时(例如,在工具栏上设置项目),你可以简单地引用toolbar
变量:
myAccessoryView.toolbar.setItems(myToolbarItems, animated: true)
演示:(在模拟器中使用硬件键盘/Command+K)
之前:
之后: