【发布时间】:2017-10-08 14:35:41
【问题描述】:
我正在将一个简单的聊天作为我的应用程序的一部分。 我在表视图控制器和聊天视图控制器中有一个聊天列表(即朋友),显示每个聊天的消息。它们都嵌入在 NavigationController 中,而 NavigationController 嵌入在 TabBarController 中。
我想将 UITextView 消息文本输入字段放在我的 UITableVeiw 下方的 ChatViewController 中,以显示该聊天的消息。我还希望 UITextView 看起来像嵌入在选项卡栏中。 我已经浏览了几十个手册教程和指南,这就是我目前所了解的。
此处的应用模拟器屏幕截图:顶部不错,底部有问题
此处为 Main.storyboard 截图
- 我使用 UITextView 而不是 UITextField,因为我希望它能够根据内容大小更改其大小
- 我使用 UIViewController 而不是 UITableViewController 来添加另一个 UIView 和 UITableView
- 我不使用实际的 UITabBar 来嵌入我的 UITextView,因为当 UITextView 需要更改其高度时,它的行为非常奇怪。据我了解,Apple 不支持将 UI 元素嵌入到 UITabBar
-
我所做的是在 ChatViewController viewWillAppear 中隐藏 TabBar:
override func viewWillAppear(_ animated: Bool) { tabBarController?.tabBar.isHidden = true }我在父 ChatsTableViewController 中再次显示它:
override func viewWillAppear(_ animated: Bool) { tabBarController?.tabBar.isHidden = false } 一旦 TabBar 被隐藏,我嵌入 textView 和 sendButton 的自定义 stackView 就会取而代之,并按照我的意愿正常运行。
-
为了正确处理键盘行为,我为 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() } }
此时似乎一切正常:
- TabBar 隐藏在 ChatViewController 中并显示在 ChatsTableViewController 中
- 嵌入在 stackView 中的 textView 和 sendButton 将上下滑动键盘,如上面的模拟器屏幕截图所示。
当我在 ChatViewController 和 ChatsTableViewController 之间滑动而不是使用 NavigationControllers 时出现 BUG
当我开始滑回 ChatsTableViewController 时,它会执行 viewWillAppear 方法,因此 tabBarController 的 tabBar 变得可见。如果我没有完成对 ChatsTableViewController 的滑动并返回 ChatViewController,ChatViewController 的 viewWillAppear 会将其设置回不可见,但输入 stackView 不会回到它的初始位置。它只是挂在不可见的 tabBar 上方。
我试过移动
tabBarController?.tabBar.isHidden = false
ChatsTableViewController 中从 viewWillAppear 到 viewDidAppear。 它修复了“浮动输入”问题,但是当 ChatsTableViewController 显示没有 tabBar 时,它增加了大约一秒钟的延迟。看起来也不太好。
任何想法如何正确修复? 我已经在这个问题上苦苦挣扎了大约一周))
【问题讨论】: