在启用滚动的堆栈视图中展开UITextView [英] Expanding UITextView inside a Stack View with scrolling enabled

查看:65
本文介绍了在启用滚动的堆栈视图中展开UITextView的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过自动布局"和"Stackview"实现某些目标.我有一个带有UIView,UITextView和UIView的Vertical Stackview,如下所示.

我已经在这里签出了以前的答案,但是找不到一个干净的解决方案来实现这一目标.

UITextView是可编辑的,并且必须随用户键入而扩展-为此,我在IB中禁用了UITextView的滚动.我还在UITextView上设置了高度限制,将其设置为大于或等于" 10,并将行数设置为0,以便UITextView在用户键入时在运行时获取固有高度.我还希望继续扩展UITextView,直到UIStackView底部边缘到达键盘配件的顶部边缘为止.通过将堆栈视图固定在Superview的顶部,底部和前端,我已经能够实现扩展的UITextView部分,但是我不断收到一个错误,该错误stackview needs Y position or height是可以理解的,但是如果我给它一个固定高度或底部约束,则UITextView根本不会扩展.

当UITextView到达Keyboard附件视图的顶部边缘时,我也不知道如何停止它的扩展.

到目前为止,我的代码是

let allowedHeight = self.view.frame.height - (self.keyboardHeight! + self.accessory.frame.height)

通过减去keyboardheight + Accessory视图高度,基本在视图框架中找到允许的高度.此计算正确进行.接下来,我希望这样做(在textViewDidChange内部),希望只是启用/禁用UITextView上的滚动会起作用,但显然不起作用,因为整个文本视图然后每次按键都会怪异地上下跳动.

func textViewDidChange(_ textView: UITextView) {
   if stackView.frame.height >= allowedHeight{
            textView.isScrollEnabled = true
        }

   if stackView.frame.height < allowedHeight{
            textView.isScrollEnabled = false
        }
}

实现我想要做的最好的方法是什么?

解决方案

夫妇笔记...

我认为最好设置UITextView的最大高度",而不是设置UIStackView的最大高度".文本视图将根据其内容展开/收缩,因此您可以设置<=高度限制.

计算"elementsHeight"(顶视图和底视图使用的垂直大小,加上任何间距),然后将最大文本视图高度"设置为视图高度减去elementsHeight ...,并在可见时减去键盘高度./p>

当最大文本视图高度"更改时,更新文本视图的高度约束常数.

然后为文本视图的.contentSize ...设置观察者,并根据"c12>"(相对于最大文本视图高度")启用/禁用滚动.

需要一些跳跃,以确保在布置子视图时更新大小,并确保不陷入递归循环.

这是我的设置方式:

文本视图的初始高度限制为<= 40-但这并不重要,因为每次视图布局不同时,都会通过代码进行更改.

我在GitHub上举了一个例子-它可以工作,但实际上只是一个起点.看看是否有兴趣,然后将其分开. https://github.com/DonMag/ExpandingTextView

I am trying to achieve something with Auto Layout and Stackview. I have a Vertical Stackview with a UIView, UITextView, and UIView in it as shown below.

I have checked out the previous answers here but couldn't find a clean solution to achieve this.

The UITextView is editable and must expand as the user types in it - for this I have disabled the scroll for the UITextView in the IB. I also have a height constraint set on the UITextView set to "Greater than or equal to" 10 and number of lines set to 0, so that the UITextView takes the intrinsic height at run time while the user types. I also want the expansion of the UITextView to continue until the UIStackView bottom edge reaches the Keypad accessory's top edge. I have been somewhat able to achieve the expanding UITextView part with my stack view pinned to the top, trailing, and leading edges of the Superview but I keep getting an error that the stackview needs Y position or height which is understandable but if I give it a fixed height or bottom constraint then the UITextView simply won't expand.

I also am not sure how to stop the expansion of the UITextView when it reaches the top edge of the Keyboard accessory view.

The code that I have so far is

let allowedHeight = self.view.frame.height - (self.keyboardHeight! + self.accessory.frame.height)

Basically find the allowed height in the view frame by subtracting the keyboardheight+Accessory view height. This calculation happens correctly. Next I do this (inside textViewDidChange) in hopes that just enabling/disabling the scroll on the UITextView would work but it clearly doens't since the whole text view then weirdly jumps up and down with every key stroke.

func textViewDidChange(_ textView: UITextView) {
   if stackView.frame.height >= allowedHeight{
            textView.isScrollEnabled = true
        }

   if stackView.frame.height < allowedHeight{
            textView.isScrollEnabled = false
        }
}

What is the best way to achieve what I am looking to do?

解决方案

Couple notes...

I think you'll be better off setting the Max Height of your UITextView rather than of your UIStackView. The Text View will expand / contract based on its content, so you can set a <= height constraint.

Calculate the "elementsHeight" - the vertical size used by your top and bottom views, plus any spacing - and set the "max text view height" to the view height minus elementsHeight ... and subtract keyboard height when visible.

Update the text view's height constraint constant when "max text view height" changes.

Then set up an Observer for the text view's .contentSize ... and enable / disable scrolling based on .contentSize.height compared to "max text view height".

Needs a bit of hoop-jumping, to make sure you update sizes when subviews are laid-out, and to make sure you don't get in a recursion loop.

This is how I set it up:

The initial height constraint on the text view is <= 40 - but that doesn't really matter, as it will be changed via code every time the views layout differently.

I put up an example on GitHub -- it works, but is really just a starting-point. Take a look if you're interested, and pick it apart. https://github.com/DonMag/ExpandingTextView

这篇关于在启用滚动的堆栈视图中展开UITextView的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆