我正在将一个简单的聊天作为我的应用程序的一部分。
我在 TableView Controller 和聊天 View Controller 中有一个聊天列表(即 friend ),显示每个聊天的消息。它们都嵌入在 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。
它修复了“ float 输入”问题,但是当 ChatsTableViewController 显示没有 tabBar 时,它增加了大约一秒钟的延迟。看起来也不太好。
任何想法如何正确修复?
我已经在这个问题上苦苦挣扎了大约一周))
Best Answer-推荐答案 strong>
因为您的 ChatsTableViewController 嵌入在 UINavigationController 并且您的 ChatViewController 被推送,所以您可以覆盖此 hidesBottomBarWhenPushed ChatViewController 将决定是否显示您的 View Controller :
public override var hidesBottomBarWhenPushed: Bool {
get { return true }
set { super.hidesBottomBarWhenPushed = newValue }
}
这是在我的脑海中隐藏标签栏的更好方法,因为 View Controller 的框架将被调整。
关于ios - Messenger 风格的 UITextView 输入,我们在Stack Overflow上找到一个类似的问题:
https://stackoverflow.com/questions/46632270/
|