菜鸟教程小白 发表于 2022-12-11 18:56:30

ios - Messenger 风格的 UITextView 输入


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

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

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

<p> <img src="/image/AgSgA.jpg" alt="App simulator screenshots here: nice at the top, buggy at the bottom"/> </p>

<p>此处为 Main.storyboard 截图</p>

<p> <img src="/image/lDeT6.png" alt="Main.storyboard screenshot here"/> </p>

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

<pre><code>override func viewWillAppear(_ animated: Bool) {
    tabBarController?.tabBar.isHidden = true
}      
</code></pre>

<p>我在父 ChatsTableViewController 中再次显示它:</p>

<pre><code>override func viewWillAppear(_ animated: Bool) {
    tabBarController?.tabBar.isHidden = false
}
</code></pre> </li>
<li><p>一旦 TabBar 被隐藏,我嵌入 textView 和 sendButton 的自定义 stackView 就会取而代之,并按照我的意愿正常运行。</p></li>
<li><p>为了正确处理键盘行为,我为 inputStackView 底部约束(在屏幕截图中选择)提供了一个导出,我在 keyboardWillShow/Hide Notifications 上进行了更新。代码如下所示:</p>

<pre><code>@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 as! NSValue).cgRectValue
    let duration = info as! Double

    UIView.animate(withDuration: duration) { () -&gt; Void in
      self?.inputBottomConstraint.constant = keyboardFrame.size.height + 8
      self?.view.layoutIfNeeded()
    }
}

@objc func keyboardWillHide(notification: NSNotification) {

    let duration = notification.userInfo! as! Double

    UIView.animate(withDuration: duration) { () -&gt; Void in
      guard let `self` = self else { return }
      self.inputBottomConstraint.constant = self.inputBottomConstraintInitialValue
      self.view.layoutIfNeeded()
    }
}
</code></pre> </li>
</ol>

<p>此时似乎一切正常:</p>

<ul>
<li>TabBar 隐藏在 ChatViewController 中,并显示在 ChatsTableViewController 中</li>
<li>嵌入在 stackView 中的 textView 和 sendButton 将上下滑动键盘,如上面的模拟器屏幕截图所示。</li>
</ul>

<p>当我在 ChatViewController 和 ChatsTableViewController 之间<i>滑动</i>而不是使用 NavigationControllers 时出现 BUG

</p><p>当我开始滑回 ChatsTableViewController 时,它会执行 viewWillAppear 方法,因此 tabBarController 的 tabBar 变得可见。如果我没有完成对 ChatsTableViewController 的滑动并返回 ChatViewController,ChatViewController 的 viewWillAppear 会将其设置回不可见,但输入 stackView 不会回到它的初始位置。它只是卡在不可见的 tabBar 上方。 </p>

<p>我试过移动</p>

<pre><code>tabBarController?.tabBar.isHidden = false
</code></pre>

<p>ChatsTableViewController 中从 viewWillAppear 到 viewDidAppear。
它修复了“ float 输入”问题,但是当 ChatsTableViewController 显示没有 tabBar 时,它增加了大约一秒钟的延迟。看起来也不太好。</p>

<p>任何想法如何正确修复?
我已经在这个问题上苦苦挣扎了大约一周))</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>因为您的 <code>ChatsTableViewController</code> 嵌入在 <code>UINavigationController</code> 并且您的 <code>ChatViewController</code> 被推送,所以您可以覆盖此 <code>hidesBottomBarWhenPushed</code> <code>ChatViewController</code> 将决定是否显示您的 ViewController :</p>

<pre><code>public override var hidesBottomBarWhenPushed: Bool {
    get { return true }
    set { super.hidesBottomBarWhenPushed = newValue }
}
</code></pre>

<p>这是在我的脑海中隐藏标签栏的更好方法,因为 ViewController 的框架将被调整。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - Messenger 风格的 UITextView 输入,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/46632270/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/46632270/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - Messenger 风格的 UITextView 输入