UITextField on UIScrollView (iOS 8.x only) - objective-c

I have a view which is a subclass of UIScrollView and UITextField is on the UIScrollView. I'll refer the subclass of UIScrollView as 'CUScrollView'.
The purpose of CUScrollView is when user input a text, a button which has a title of the text will be added on the CUScrollView. The Offset of UITextField will be move at the right of the last added button.
This is how the CUScrollView look like.
Below iOS 8.x, it works perfectly; However it doesn't on iOS 8.x.
When the UITextField resigned first responder, the CUScrollView's contentSize is reset to CUScrollView's frame width.
I finally found a work around. I overrided the setContentSize: and set the contentSize to whatever I want.
Is it a bug? or some kind of auto layout mistake?

First of all don't mix auto layout with setting Frame's manually. If you perform like that then it will be the mistake in your autlayout.

Related

UITextView inside UIScrollView with AutoLayout

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?
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.
Add UIScrollView inside the main view in Storyboard
Add UIView inside the UIScrollView
Add UITextView inside the UIView (the view added in step 2)
Make sure "Scrolling Enabled" of UITextView is unchecked
Add 4 constraints (leading, trailing, top, bottom) on UIScrollView
Add 4 constraints (leading, trailing, top, bottom) on UIView (the view added in step 2)
Add "Width Equally" constraint on UIView (the view added in step 2) and the main view
Add 5 constraints (leading, trailing, top, bottom, height) on UITextView. After this step you shouldn't get any errors and warnings on constraints.
Add UITextView height constraint IBOutlet on the ViewController. #property (nonatomic, weak) IBOutlet NSLayoutConstraint *textViewHeightConstraint; and connect it in Storyboard
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.
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
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.
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.

Having trouble moving an UITextView in a UIScrollView when it's the first responder

I have a view controller that is basically a form with multiple UITextFields and UITextView, embedded in a UIScrollView. When an UITextField becomes first responder, the scroll view automatically move to the focused field, which is believe is the behaviour explained in the first answer in this topic :
Disable UIScrollView scrolling when UITextField becomes first responder
This does not happen when the first responder is an UITextView though, and I'm not sure why and how I should fix it.
The second problem is that when the keyboard is shown, the scroll view does not scroll if the UITextView is not in view (because it's hidden by the newly shown keyboard). I implemented the code of Apple's documentation on how to manage the keyboard :
http://developer.apple.com/library/ios/#DOCUMENTATION/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html
And added another activeField variable named activeView for textViews (initialized in the beginEditing of TextView, set to nil in endEditing, and scrollToVisible according to it's frame when the keyboard is shown). The problem here is that the beginEditing in UITextView is called after the keyboardWasShown, so the activeView is not initialized and thus does not scroll. For some reason, for UITextFields the beginEditing is called before, which is the intended behaviour.
How can I scroll to an UITextView and it's the first responder, and how can I move to it when the keyboard is shown and hide it?
To scroll to show anything in a UIScrollView do
scrollRectToVisible:/*frame of object you want to show*/ animated:YES
Subscribe to UITextViewTextDidBeginEditingNotification and call the above method when you get it.

Keeping UIButton Stationary on Screen

I have a UIButton on top of a UIWebView. The UIButton is supposed to look like it's native to the webpage. However, when I zoom in on the UIWebView, the button comes with it, obviously looking out of place. Is there a way to keep the button's position relative to the UIWebView rather than its position on screen?
Thanks for any help!
Not sure I've understood your problem, but here goes:
You've likely a view hierarchy like this:
View
UIWebView
UIButton
That is, your button was added as subview to the UIWebView. Since the UIWebView is also a UIScrollView you get the behavior you've observed. To fix it, make the button a sibling, not a child:
View
UIWebView
UIButton
It will still be drawn in front of your UIWebView if it was added after the UIWebView.

Scrolling a UITableView inside a UIScrollView

I have a UITableView which is a subview of a UIView, then that UIView is a subview of a UIScrollView. How do I detect the touches that should scroll the UITableView?
The UITableView can get item selection events (a cell in the table is selected/tapped) just fine, except that you have to hold down on the cell before it fires. But I can't get the UITableView to scroll, its always the UIScrollView that reacts to the pan gesture.
Any help is greatly appreciated. Thanks in advance!
EDIT:
Solved, though I asked the wrong question. It does work by default as Roman K pointed out. I think the problem was related to having a part of the UITableView outside the bounds of the UIScrollView (the UITableView went over the bottom bounds of the UIScrollView). Setting it to correctly fit inside the UIScrollView fixed it.
Please, make sure that UIScrollView's properties delaysContentTouches and canCancelContentTouches are set appropriately. They control how UIScrollView instance passes touch information to its subviews. By default delaysContentTouches is set to YES. Also, make sure that, if you extended UIScrollView, touchesShouldBegin:withEvent:inContentView: allow touches in the subview.
Otherwise, UITableView scrolling should work by default in your scenario. If you create a test project with just the view hierarchy as described you will see that it is the case. So, compare the two and see what difference affects the scrolling.

UITextView when put in a UITableViewCell sometimes do not display the content

I wonder if anyone else is facing the same issue. I have a UITextView field placed in a UITableViewCell. Sometimes it does not displays the text. When i click or scroll the table view, it appears. Any guesses?
Details:
I call a method in viewDidLoad method that calls a web service to retrieve some data. On receiving the data, i set the values of UILabel and UITextView. UILabel values appear fine, but the UITextView (sometimes) do not show the value until i move to subview or scroll up and down to revisit the area contaning UITextView. I'm showing UILabel and UITextView objects in UITableViewCell. I call [tableView reloadData] right after setting values in UILabel and UITextView, but i do not re-create the UITableViewCell.
Thanks for your reply and pointers.
I solved this by calling [myTableView reloadData];
I had this same problem more or less - a UITextView inside a custom UITableViewCell subclass would not display its text until you touched (and thus scrolled) the UITextView. This would only happen with the FIRST cell in the table. I couldn't figure out why it was happening, but the problem was easily fixed by just "nudging" the UITextView's contentOffset programmatically.
problemCell.textView.contentOffset = CGPointMake(0.0, 1.0);
problemCell.textView.contentOffset = CGPointMake(0.0, 0.0);
This might have something to do with the fact that UITextView and UITableView are both subclasses of UIScrollView. So you have a scroll view inside of a scroll view, and it wouldn't surprise me if that was the cause of your problems.
If you don't need to edit the text within the table, just use a multi-line UILabel.
If you absolutely have to have a UITextView inside a UITableView, perhaps disabling scrolling on one of them might also fix the problem. (I think the property name is scrollEnabled or scrollingEnabled.)
Make sure that you're calling [super viewWillAppear:] and [super viewDidAppear:] in all the places where you override viewWillAppear or viewDidAppear.
Probably true of all the other viewDidWhatever and viewWillWhatever methods as well.
The problem you're having suggests that the UITextView isn't getting the message to draw itself on the screen when you're first displaying the table but does get the message when it needs to refresh.