36

I am trying to place UITextView inside UIScrollView with AutoLayout with no luck. What I have tried is,

  • I placed UIScrollView inside the main view in Storyboard
  • I placed UITextView inside UIScrollView in Storyboard and disabled Scrolling Enabled
  • I set constraints (leading, trailing, top, bottom) on UIScrollView
  • I set constraints (top, leading, trailing, height) on UITextView
  • I created IBOutlet of height constraint of UITextView
  • I set a text (a lot of text which can cause scrolling) on UITextView in viewDidLoad()
  • I set a height constraint of UITextView with the code below. I have tried it right after setting text in viewDidLoad() and viewDidLayoutSubviews() with no luck

self.textViewHeightConstraint.constant = [self.textView sizeThatFits:CGSizeMake(self.textView.frame.size.width, FLT_MAX)].height;

UITextView is getting its height, but UIScrollView isn't. Is there anything I've missed?

Sodbileg Gansukh
  • 1,730
  • 2
  • 13
  • 19
  • Another thing to note is that you may want `UITextView.scrollEnabled = false` – onmyway133 Jul 08 '16 at 09:14
  • I have working example of how to calculate height for UITextView dynamic height + it's inside UIStackView which is inside UIScrollView here: https://github.com/fassko/ScrollStackViewExample – Kristaps Grinbergs Sep 19 '17 at 07:28

4 Answers4

90

After a few days of research and getting my hands dirty with UIScrollView + UITextView + Auto Layout, I successfully got a fully working UIScrollView. I want to share my solution just in case someone might stuck on the same situation.

  1. Add UIScrollView inside the main view in Storyboard
  2. Add UIView inside the UIScrollView
  3. Add UITextView inside the UIView (the view added in step 2)
  4. Make sure "Scrolling Enabled" of UITextView is unchecked
  5. Add 4 constraints (leading, trailing, top, bottom) on UIScrollView
  6. Add 4 constraints (leading, trailing, top, bottom) on UIView (the view added in step 2)
  7. Add "Width Equally" constraint on UIView (the view added in step 2) and the main view
  8. Add 5 constraints (leading, trailing, top, bottom, height) on UITextView. After this step you shouldn't get any errors and warnings on constraints.
  9. Add UITextView height constraint IBOutlet on the ViewController. @property (nonatomic, weak) IBOutlet NSLayoutConstraint *textViewHeightConstraint; and connect it in Storyboard
  10. Change the UITextView height constraint programmatically. self.textViewHeightConstraint.constant = [self.textView sizeThatFits:CGSizeMake(self.textView.frame.size.width, CGFLOAT_MAX)].height;

After all of these 10 steps, you'll get fully working UIScrollView with UITextView inside and be happy.

Sodbileg Gansukh
  • 1,730
  • 2
  • 13
  • 19
  • if you have a many views and if you don't want to always create a viewcontroller class files. You can change the textView Height = Greater than or Equal 600 from Equal 600 ! – emresancaktar Mar 20 '15 at 19:19
  • 3
    In short, the important part here is, as I can confirm when I had the same problem, that one needs to add a plain UIView inside the UIScrollView, and then place all items inside that UIView instead of into the UIScrollView. Otherwise, multi-line UITextViews inside the Scrollview won't auto-adjust their width and height correctly. – Thomas Tempelmann Apr 09 '15 at 15:12
  • Im not able to edit the textField with this approach, seems the scrollview is overriding touch events :/ – OxenBoxen Jun 30 '15 at 16:38
  • I cannot get Step 7 to work. The main view doesn't allow constraints to be linked via control-drag. – jowie Jul 06 '15 at 08:33
  • Upon further investigation, these constraints can only be set up in IB if you are using a Storyboard file. Connecting constraints between a top view and a UIScrollView subview is prohibited in a .xib file. – jowie Jul 06 '15 at 09:29
  • 5
    Also, you don't need the text view height constraint and any of the IBOutlet constraint code. A UITextView will automatically size to fit the text. Remove the constraint and `textViewHeightConstraint` code, and it still works just as well. – jowie Jul 06 '15 at 12:13
  • Using another UIView inside the UIScrollView isn't mandatory, it is possible to customize your storyboard without UIView as a sub-view. – OhadM Nov 15 '15 at 09:41
  • But...if you do need a dynamic text view that can change during runtime embedded only it with UIView and set the bottom constraint to "Standard" size in the IB. – OhadM Nov 15 '15 at 13:09
  • I am facing one problem , i have scrollview => inside one UIView => inside one UIButton. Now problem is that when ever i am trying to run my app in iPhone 6 or later then my UIButton move little bit left side from trailing. I tried a lot but not get success till. Please help me out – Birju Dec 07 '15 at 18:19
  • @SodbilegGansukh I would like to invite you to answer this question http://stackoverflow.com/questions/34392541/need-assistance-regarding-uiscrollview – S.J Dec 21 '15 at 11:25
  • 2
    "Make sure "Scrolling Enabled" of UITextView is unchecked" - This was my issue. The text view simply did not show up at all before. I set scrolling enabled to false, and boom - there it was! Unexpected! – n13 Feb 13 '16 at 08:56
  • BTW you don't need to set the text view height. At least I didn't have to. When you attach the text view to the bottom of the scroll view, the text view will resize to fit its text, and the scrollview's content size will adjust to fit the text view! It all works. – n13 Feb 13 '16 at 08:57
  • If the text view is designed to be editable, will it be highly inefficient, if we need to calculate the `textViewHeightConstraint` whenever there is a text change? Will there be a more efficient way to accomplish? – Cheok Yan Cheng Jan 07 '21 at 16:59
8

It seems that this question has an answer that has worked for a number of people. However, it should be noted that the documentation states:

Placing a text view inside of a scroll view. Text views handle their own scrolling. You should not embed text view objects in scroll views. If you do so, unexpected behavior can result because touch events for the two objects can be mixed up and wrongly handled.

Before trying to put a UITextView in a UIScrollView you should consider if this is really necessary. If the text view is part of a complex layout within the scroll view, then note the use of the UIView container in the accepted answer.

See also: Scroll Views Inside Scroll Views

Suragch
  • 484,302
  • 314
  • 1,365
  • 1,393
5

If you noticed that the Auto Layout is still complaining about the height of the UIScrollView-

The problem here is that by default UITextView has checked the “Scrolling Enabled” in the IB.

So find that checkbox and uncheck it.

enter image description here

Vitya Shurapov
  • 2,200
  • 2
  • 27
  • 32
0

Sodbileg's solution above works, but you do not need all of his steps. I got my scrollview to scroll with a text view inside by following his steps through step 7. For step 8, I added the 4 constraints but not the height (Don't forget the bottom constraint!!). I did not do the rest.

I am not sure, but it seems that the height of the textview adjusts automatically instead of us having to manually change it.

Noor
  • 13
  • 1
  • 4