问题
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?
回答1:
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
来源:https://stackoverflow.com/questions/46965439/expanding-uitextview-inside-a-stack-view-with-scrolling-enabled