作为我的应用程序的一部分,我正在进行简单的聊天。 我在表视图控制器和聊天视图控制器中有一个聊天列表(即朋友),显示每个聊天的消息。它们都嵌入在NavigationController中,它嵌入在TabBarController中。
我想将UITextView消息文本输入字段放在我的UITableVeiw下面的ChatViewController中,该字段显示该聊天的消息。我还希望UITextView看起来像是嵌入在标签栏中。 我已经阅读了数十本手册教程和指南,以及我到目前为止的所在地。
App模拟器截图:顶部很好,底部有错误
Main.storyboard截图在这里
我所做的是在ChatViewController中隐藏TabBar viewWillAppear:
override func viewWillAppear(_ animated: Bool) {
tabBarController?.tabBar.isHidden = true
}
我在父ChatsTableViewController中再次显示它:
override func viewWillAppear(_ animated: Bool) {
tabBarController?.tabBar.isHidden = false
}
一旦TabBar被隐藏,我的自定义stackView嵌入textView和sendButton就会取而代之,并按照我的意愿运行。
为了正确处理键盘行为,我有一个输入我的inputStackView底部约束(在屏幕截图中选择),我在keyboardWillShow / Hide Notifications上更新。代码如下:
@IBOutlet weak var inputBottomConstraint: NSLayoutConstraint!
var inputBottomConstraintInitialValue: CGFloat!
//MARK: - Keyboard handling
private func enableKeyboardHideOnTap(){
NotificationCenter.default.addObserver(self, selector: #selector(ChatTableViewController.keyboardWillShow(notification:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(ChatTableViewController.keyboardWillHide(notification:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(ChatTableViewController.hideKeyboard))
self.view.addGestureRecognizer(tap)
}
@objc func hideKeyboard() {
textView.resignFirstResponder()
}
@objc func keyboardWillShow(notification: NSNotification) {
let info = notification.userInfo!
let keyboardFrame: CGRect = (info[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
let duration = info[UIKeyboardAnimationDurationUserInfoKey] as! Double
UIView.animate(withDuration: duration) { [weak self] () -> Void in
self?.inputBottomConstraint.constant = keyboardFrame.size.height + 8
self?.view.layoutIfNeeded()
}
}
@objc func keyboardWillHide(notification: NSNotification) {
let duration = notification.userInfo![UIKeyboardAnimationDurationUserInfoKey] as! Double
UIView.animate(withDuration: duration) { [weak self] () -> Void in
guard let `self` = self else { return }
self.inputBottomConstraint.constant = self.inputBottomConstraintInitialValue
self.view.layoutIfNeeded()
}
}
此时似乎一切正常:
当我在ChatViewController和ChatsTableViewController之间轻扫而不是使用NavigationControllers时,会出现BUG
当我开始刷回ChatsTableViewController时,它会执行viewWillAppear方法,因此tabBarController的tabBar变得可见。如果我没有完成向ChatsTableViewController的滑动并返回ChatViewController,则ChatViewController的viewWillAppear将其设置为不可见,但输入stackView不会回到它的初始位置。它只是悬挂在隐形tabBar上方。
我尝试过移动
tabBarController?.tabBar.isHidden = false
从viewWillAppear到ChatsTableViewController中的viewDidAppear。 它修复了"浮动输入"问题,但是当ChatsTableViewController显示没有tabBar时,它会增加大约一秒的延迟。看起来也不太好。
任何想法如何正确修复? 我已经在这个问题上挣扎了大约一个星期))
答案 0 :(得分:0)
由于您的ChatsTableViewController
已嵌入UINavigationController
并且ChatViewController
被推送,您可以覆盖hidesBottomBarWhenPushed
中的ChatViewController
,这将决定显示您的观点控制器与否:
public override var hidesBottomBarWhenPushed: Bool {
get { return true }
set { super.hidesBottomBarWhenPushed = newValue }
}
这是隐藏标签栏的更好方法,因为视图控制器的框架将被调整。
答案 1 :(得分:0)
为什么要改变键盘显示/隐藏的约束。尝试Google inputAccesoryView,很多聊天都使用它。它的自然行为是使用键盘。以TryBook Messenger为例,看看刷卡如何将键盘和Textfield隐藏在一起,你无法用常规视图完成这种od行为。