• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    迪恩网络公众号

ios - Messenger 风格的 UITextView 输入

[复制链接]
菜鸟教程小白 发表于 2022-12-11 18:56:30 | 显示全部楼层 |阅读模式 打印 上一主题 下一主题

我正在将一个简单的聊天作为我的应用程序的一部分。 我在 TableView Controller 和聊天 View Controller 中有一个聊天列表(即 friend ),显示每个聊天的消息。它们都嵌入在 NavigationController 中,而 NavigationController 嵌入在 TabBarController 中。

我想将 UITextView 消息文本输入字段放在我的 UITableVeiw 下方的 ChatViewController 中,以显示该聊天的消息。我还希望 UITextView 看起来像嵌入在标签栏中。 我已经浏览了几十个手册教程和指南,这就是我目前所了解的。

此处的应用模拟器屏幕截图:顶部不错,底部有问题

App simulator screenshots here: nice at the top, buggy at the bottom

此处为 Main.storyboard 截图

Main.storyboard screenshot here

  1. 我使用 UITextView 而不是 UITextField,因为我希望它能够根据内容大小更改其大小
  2. 我使用 UIViewController 而不是 UITableViewController 来添加另一个 UIView 和 UITableView
  3. 我不使用实际的 UITabBar 来嵌入我的 UITextView,因为当 UITextView 需要更改其高度时,它的行为非常奇怪。据我了解,Apple 不支持将 UI 元素嵌入到 UITabBar
  4. 我所做的是在 ChatViewController viewWillAppear 中隐藏 TabBar:

    override func viewWillAppear(_ animated: Bool) {
        tabBarController?.tabBar.isHidden = true
    }       
    

    我在父 ChatsTableViewController 中再次显示它:

    override func viewWillAppear(_ animated: Bool) {
        tabBarController?.tabBar.isHidden = false
    }
    
  5. 一旦 TabBar 被隐藏,我嵌入 textView 和 sendButton 的自定义 stackView 就会取而代之,并按照我的意愿正常运行。

  6. 为了正确处理键盘行为,我为 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-推荐答案


因为您的 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/

回复

使用道具 举报

懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关注0

粉丝2

帖子830918

发布主题
阅读排行 更多
广告位

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap