使用键盘使带有 TextField 的 UIToolbar 向上移动
Posted
技术标签:
【中文标题】使用键盘使带有 TextField 的 UIToolbar 向上移动【英文标题】:Making UIToolbar with TextField move up with keyboard 【发布时间】:2015-10-13 21:27:34 【问题描述】:我有一个带有 TextField 的 UIToolbar 和一个作为 UIBarButtonItem 的按钮。当用户点击工具栏中的 TextField 时,我正在尝试将此工具栏用作键盘的 inputAccessory。
我发现this question 试图解决同样的问题。不幸的是,该解决方案无效。
我正在尝试的是:
class ChatViewController: UIViewController, CLLocationManagerDelegate, UITableViewDelegate, UITableViewDataSource
@IBOutlet weak var chatTableView: UITableView!
@IBOutlet weak var chatToolbar: UIToolbar!
@IBOutlet weak var textFieldBarButtonItem: UIBarButtonItem!
override func viewDidAppear(animated: Bool)
super.viewDidLoad()
self.chatTableView.delegate = self
self.chatTableView.dataSource = self
self.chatToolbar.removeFromSuperview()
override var inputAccessoryView: UIView
get
return self.chatToolbar
override func canBecomeFirstResponder() -> Bool
return true
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
let cell = UITableViewCell()
return cell
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return 0
而我得到的是:
*** Terminating app due to uncaught exception 'UIViewControllerHierarchyInconsistency', reason:
'child view controller:<UICompatibilityInputViewController: 0x13ff34e00> should have parent view controller:
<App.ChatViewController: 0x13ff21cc0> but requested parent is:<UIInputWindowController: 0x1400b4600>'
有什么想法吗?
【问题讨论】:
这个方法不错,问题应该是inputAccessoryView:
在viewDidAppear
之前被调用了。附件视图不应属于任何视图层次结构。顺便说一句:接受的答案也可以
@Omer 太好了,你有什么建议?
我认为这两种方法都很好,我更喜欢accessoryInputView,因为它在其他好处之间更清晰(即:使用UIScrollViewKeyboardDismissModeInteractive
的更简单方法,独立于故事板/xib,无约束=D)。以下链接包含一个 obj-c 项目,它使用附件视图方法进行了基本实现,以防万一你想尝试一下:dropbox.com/s/a4bsvz0ie95i3qn/KeyboardAccessory.zip?dl=0 |||不是我在使用工具栏,但你可以使用任何你想要的 UIView 子类
我的意思是,我应该如何继续强制在 viewDidAppear
之后调用 inputAccessoryView
?
不知道你为什么需要它,inputAccessoryView
是 UIResponder 的一个属性(因此,也是 UIViewController 的一个属性)。此类的基本实现使用此属性以便在需要时提供自定义行为。检查我分享的项目。
【参考方案1】:
第一件事:
-
您应该为 Storyboard 中的工具栏创建约束(左、下、右)。
在视图控制器中为底部约束创建一个出口(从情节提要中拖动)。保存初始约束值(键盘消失时恢复)
创建观察者以了解您的键盘何时出现和消失(3.1 并创建轻击手势以隐藏您的键盘)
当键盘 4.1 出现而 4.2 消失时,您只会更改底部约束值(键盘大小)。您也可以为工具栏设置动画。
类似:
class ChatViewController: UIViewController, CLLocationManagerDelegate, UITableViewDelegate, UITableViewDataSource
@IBOutlet weak var chatTableView: UITableView!
@IBOutlet weak var chatToolbar: UIToolbar!
@IBOutlet weak var textFieldBarButtonItem: UIBarButtonItem!
//2
@IBOutlet weak var toolbarBottomConstraint: NSLayoutConstraint!
var toolbarBottomConstraintInitialValue: CGFloat?
override func viewDidAppear(animated: Bool)
super.viewDidAppear(animated)
self.chatTableView.delegate = self
self.chatTableView.dataSource = self
self.chatToolbar.removeFromSuperview()
//2
self.toolbarBottomConstraintInitialValue = toolbarBottomConstraint.constant
//3
enableKeyboardHideOnTap()
// 3
// Add a gesture on the view controller to close keyboard when tapped
private func enableKeyboardHideOnTap()
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillShow:"), name: UIKeyboardWillShowNotification, object: nil) // See 4.1
NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("keyboardWillHide:"), name: UIKeyboardWillHideNotification, object: nil) //See 4.2
// 3.1
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "hideKeyboard")
self.view.addGestureRecognizer(tap)
//3.1
func hideKeyboard()
self.view.endEditing(true)
//4.1
func keyboardWillShow(notification: NSNotification)
let info = notification.userInfo!
let keyboardFrame: CGRect = (info[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue()
let duration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
UIView.animateWithDuration(duration) () -> Void in
self.toolbarBottomConstraint.constant = keyboardFrame.size.height + 5
self.view.layoutIfNeeded()
//4.2
func keyboardWillHide(notification: NSNotification)
let duration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
UIView.animateWithDuration(duration) () -> Void in
self.toolbarBottomConstraint.constant = self.toolbarBottomConstraintInitialValue!
self.view.layoutIfNeeded()
override var inputAccessoryView: UIView
get
return self.chatToolbar
override func canBecomeFirstResponder() -> Bool
return true
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
let cell = UITableViewCell()
return cell
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
return 0
希望对你有帮助!
【讨论】:
以上是关于使用键盘使带有 TextField 的 UIToolbar 向上移动的主要内容,如果未能解决你的问题,请参考以下文章
使用带有 TextField 的自定义表格视图单元格关闭数字键盘
键盘出现/消失时调整带有 TextField 的 SwiftUI 列表