【问题标题】:UIView w/UITextView that moves with UIScrollView's dismiss interactiveUIView w/UITextView 随 UIScrollView 的解除交互而移动
【发布时间】:2017-07-14 10:43:11
【问题描述】:

我已经搜索过这个问题并找到了一些零碎的东西,但不是真正的重复。

我正在尝试创建一个 UITextView,它封装在一个 UIView 中,它会根据其内容动态改变它的高度,这很容易通过自动布局和禁用 UITextView 上的滚动来解决。

然后,我希望 UITextView 使用可能会或可能不会关闭的键盘以交互方式移动(通过在 UIScrollView 上设置以交互方式关闭的属性)。

这种整体行为将模仿文本输入在 iOS 消息上的工作方式——它几乎可以通过交互式关闭键盘很好地滚动,并在需要时增加高度。

到目前为止,我的尝试是创建一个占据整个视图的 UITableView,以及另一个封装文本视图的视图,它被水平约束并固定在视图控制器视图的底部。高度被省略,但自动布局可以通过其中的 UITextView 确定大小。

如图:

到目前为止,这在模拟器中运行良好,无需产生键盘:

现在,为了将封装视图固定到键盘上,我尝试将其用作视图控制器上的输入附件视图,为此,我必须首先将其从视图中删除控制器的视图层次结构。我不确定在哪里执行此操作(键盘将显示通知,文本视图应该开始编辑委托等?)因为到目前为止我所做的一切都导致视图作为键盘的附件视图丢失(如果键盘确实显示)。

像这样:

发件人:

import UIKit

class ViewController: UIViewController {

    // MARK: - Outlets
    @IBOutlet weak var inputTextview: UITextView!
    @IBOutlet weak var genericInputContainer: UIView!

    // MARK: - Properites
    fileprivate var shouldAddInputContainerAsAccessory = false
    override var inputAccessoryView: UIView? {
        if shouldAddInputContainerAsAccessory {
            return genericInputContainer
        }
        return nil
    }

    // MARK: - Actions
    @objc fileprivate func keyboardWillShow(sender: Notification) {
    }

    fileprivate func observeNotifications() {
        let keyboardWillShowAction = #selector(keyboardWillShow(sender:))
        NotificationCenter.default.addObserver(
            self,
            selector: keyboardWillShowAction,
            name: Notification.Name.UIKeyboardWillShow,
            object: nil)
    }

    // MARK: - Lifecycle
    override func viewDidLoad() {
        super.viewDidLoad()
        observeNotifications()
        inputTextview.delegate = self
    }
}

extension ViewController: UITextViewDelegate {
    func textViewShouldBeginEditing(_ textView: UITextView) -> Bool {
        genericInputContainer.removeFromSuperview()
        shouldAddInputContainerAsAccessory = true
        return true
    }

    func textViewShouldEndEditing(_ textView: UITextView) -> Bool {
        shouldAddInputContainerAsAccessory = false
        return true
    }
}

我对尝试从已经存在的视图创建新视图犹豫不决,因为我将向封装视图(文本视图旁边)内的元素添加几个不同的动画/变换。

【问题讨论】:

  • 我会将带有文本字段的视图设为视图控制器视图的inputAccessoryView,然后将视图控制器的视图设为viewDidAppear 中的第一响应者。您必须将UIView 子类化以从canBecomeFirstResponder 返回true,然后将视图控制器的根视图的类设置为情节提要中的子类。如果您这样做,则根本不会添加带有添加到视图层次结构中的文本字段的视图,因为当视图成为第一响应者时系统会自行添加它。
  • @Fred 你最终找到解决方案了吗?我在同一条船上。

标签: ios swift uiscrollview uitextview


【解决方案1】:

不要删除输入然后将其分配给您的键盘附件,而是使用键盘观察器获取键盘出现时的高度,然后调整文本输入的底部约束。您可以像这样获得键盘高度:

func keyboardWillShow(notification: NSNotification) {
    if let keyboardSize = (notification.userInfo?[UIKeyboardFrameBeginUserInfoKey] as? NSValue)?.cgRectValue {
        self.keyboardHeight = keyboardSize.height
        //debugPrint(keyboardHeight)
    }
}

【讨论】:

  • 通知,以及我所知道的任何通知,都与键盘一起被触发,因为它被交互地关闭(它可以上下移动,并且可能根本不会关闭)。跨度>
  • 这将是您分配给 UIKeyboardWillShow 观察者的函数。您还可以为 UIKeyboardWillHide 观察者分配一个函数,以在键盘隐藏时重置底部约束。
  • 我认为您不理解关闭交互行为,用户可以通过拖动滚动视图来上下移动键盘,此时,我希望我的输入视图是跟着它一起移动。
  • 我认为您不能滚动键盘本身。我认为这是一个只有 Apple 才能使用的自定义动画。
  • 我不是在尝试滚动键盘本身,键盘是由 iOS 控制的,但是附带了一个辅助输入视图。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多