How to position my UIScrollView and Text Field inside? - iphone

You may find my question stupid but I'm new to Objective C dev and I'm still learning basic things. I made a form in my app with a text field in the bottom of the view. But when this field get the focus, keyboard shows up and it hides the field so no way to see what I'm typing. I've found solutions online about it especially with the use of UIScrollView to fix the issue.
The issue I've now is with the Scroll View itself. I moved my text field to replace it with a UIScrollView of about same size, then I drag drop my field back but this time as a subview of the ScrollView. But when running the app the text field is going up, that is its position in interface builder is different to what I can see when running the app.
I need your help about the size I need to apply to the Scroll View and its content to make it useful in this case. Should it have the exact size as the text field ? should it have the same size as the whole view ?
Thx for helping,
Stephane

A UIScrollView has two "sizes". The one is that of its own frame (i.e. how much space does it take up). And how large is the contentSize of the scrollview (i.e. how far left/right/up/down can we scroll)
The general Idea would be this:
your UIScrollView has the size of the available screen real estate when the keyboard is hidden (say 320 x 460 or so), it takes up as much space as its content (assuming your content also needs 320 x 460), scrolling isn't enabled.
once the keyboard shows, the scrollView will have to scale down (say 320 x 244), the content obviously doesn't scale down, that way you're now able to scroll.
I'd probably use something like
moveTextViewForKeyboard:(NSNotification*)aNotification up: (BOOL) up
to trigger the frameSize change of the scrollView and enable scrolling.

Related

UIScrollView Controller not scrolling fully

I am pretty sure this has something to do with the dreaded AutoLayout. (been trying since 2days to get hang of it)
So I mastered it somewhat, but now I have problem where my UIScrollView is not scrolling fully down, pictures are much better at explaining these things
this is the scroll view
this is the content view
so the problem is the scrolling is happening but then again it springs back up. So I am not able to click on the signup button
EDIt 1
Edit:
I have created a little example on github for you to look at, here. The project illustrates the answer below and uses the techniques I describe and nothing else.
Original Answer:
couple of things I would advise here.
First, I know you've been trying for a while but remove all the current constraints (painful I know but). Do this for clarity as ....
The view should be the size of the scene, it looks like you want the scrollview to be the full screen so that too needs to be the size of the scene.
e.g. if you are designing at 6Plus by default the scene size is 414x736 so the view and the scrollview it contains should also be 414x736.
Only the content view needs to be the size of the real content you wish to show. Let's say for arguments sake that the content is 414x1000.
Now the constraints for the scrollview are simple. It needs zero spacing to all it's edges.
You can add the content view to the scrollview in a couple of ways. The way I try to do this varies from project to project and depends mostly on how complex the scene is. If it's a really busy scene I keep the content view outside of the scrollview in interface builder so that I can work on it easily and visualize the whole of the view. Then I add the content view to the scrollview in code.
If its a simpler view You can add it inside the scrollview in interface builder. Ultimately whichever way you do it, you can lose visibility of the content view in interface builder because the contentview is larger than the scrollview and the content gets obscured. So play about and find a good way for you.
Define the content view and all it's subviews. The content view needs to be taller than the scrollview otherwise it wont scroll. All of the content view's subviews need to have defined heights from top to bottom and widths from left to right. In your case the scrollview is scrolling vertically not horizontally so all the widths need to add up to the width of the scroll view BUT the heights need to add up to the full height of the content view.
Note: if you do this proportially your life will be easier later. If you do all this with fixed heights the storyboard will break on different device sizes.
Now the "tricky bit" and it's a bit counter intuitive. You need to pin the content view to the scrollview, remember the height of the content view is taller than the scrollview. In all other circumstances in Interface Builder pinning a view to a superview (0 padding) will adjust the height (or width) accordingly. For the relationship between a scrollview and it's content view this doesn't happen.
First pin the contentview
Notice the -400? Remember the content view is taller than the scrollview and we will change this immediately.
Select the bottom constraint (-400) that we have just created:
Select the drop down arrow next to the constant value:
Select Standard Value and type in 0 for the constant.
You should now have a storyboard with no broken constraints and if you build and run you should get a scrollview as desired.
Your bottomspace to superview on your content view is set to -74.0, I don't know if there is a reason you had to do that, but try setting it to -8.0. I think your scroll view is scrolling up to the 0.0 mark automatically

Correct approach for implementing vertical scrolling with UIScrollView

I know that I asked a question a few minutes ago, but I want to make a few points clearer before asking for the community's help. I'm new to iOS development, close to finishing my first app. The only thing standing in my way is this UIScrollView. I simply do not understand it, and could use your help.
This is in the detail view controller of a drill-down app with a tab bar. I have approximately 8 fields (for things like phone numbers and such) drawing from a .plist. Obviously, those take up enough room that I could use a little extra real estate. I would guess that it needs to be about the size of two views vertically, but I do not understand how to allocate that sort of space to a UIScrollView. Some tutorials I have read say that you don't even need to define it in the header, which I doubt and do not understand. Additionally, I do not understand how to simply get the app to smoothly scroll up-and down only. Apple's examples have constant move cycles that flip between horizontal pictures.
I doubt it makes very much a difference, but I have an image that is in the background. I'm going to load the view on top of that.
My question is broad, so I don't expect you to take the time to sit down and write out all of the code for me (and I wouldn't ask you to). Just an outline of quick, helpful tips would help me understand how to get this view to load in the context of my project.
Many thanks!
It's fairly simple. Add a UIScrollView to your view. Add your fields and such to the scrollview. In viewDidLoad or somewhere similar, you need to set the contentSize on your scrollview. This is the "virtual" area that will be scrollable. This will generally be larger than the frame of the scrollview. In your case, you indicated it should be roughly double the width.
For instance, if you had a scrollview with a view inside, and you wanted to make sure the entire view is visible via scrolling:
self.scrollView.contentSize = self.contentView.frame.size;
//setting scrollview zoom level
self._scrollview.minimumZoomScale=0.5;
self._scrollview.maximumZoomScale=6.0;
self._scrollview.contentSize=CGSizeMake(320,500 );
you have to outlet scroll view in .h class and #property #synthesis this scroll view.then you can able to scroll up and down,if u want only vertical scrolling ,then u have to go to interface builder and uncheck the horizontal scrolling.
You can set a few settings for your scrollview to limit the scrolling to horizontal or vertical. A few important ones are:
// pseudcode here, start typing "[scrollView " then press escape to get a intelli-sense of all // the things you can set for the scrollview.
// values could be YES/NO or TRUE/FALSE, I can't remember which one but
// I think it's YES/NO. Once you start scrolling, the phone will determine
// which way you're scrolling then lock it to that direction
[scrollView setDirectionalLockEnabled:YES];
// when you slide the view, if enough of the next part of the view is visible,
// the scrollview will snap or bounce the scrollview to fit this new "page".
// think of swiping feature to navigate the iPhone home screens
// to show different "pages" of iphone apps
[scrollView setPagingEnabled:YES];
// as a safe guard, make sure the width of your scrollview fits snuggly with the content
// it is trying to display. If the width is more than necessary to display your table of
// data vertically, sometimes the scrollview will cause the
// horizontal scrolling that you don't want to happen and you get bi-directional scrolling
Just set the content size of UIScrollView after adding all the controls/button/textfields etc. for example you add 10 textfields in UIScrollview then content size of UIScrollView will be
lastTextField.frame.origin.y+lastTextField.frame.size.height+20; 20 is for margin.
That's it let me know if you want to know something more related to your app.

Hiding elements outside of bounds on iPhone

I'm trying to get a UIView to expand (with animation), sort of like an accordion menu. I can get the animation working fine however the issue is the subviews of the UIView are expanding past the bounds of the UIView.
For example, the view has an UILabel in the top-right corner with a height of 16. Assume the UIView height is 0 at the beginning of the animation. One would expect that the content of the view be hidden and gradually reveal as the UIView grows. Once the height has reached 8, for example, half the label should be visible. However that isn't the case - rather, the label is visible the whole time, regardless if it's height extends outside of that of it's parent view.
Any ideas how to resolve this?
Okay, I had to set the clipsToBounds property to true. I spent some time googling before making the question but didn't have much luck until I saw it in the Related section of my question.

Why can't I tap input elements after I resize a scroll view?

I have a sample project that uses the metrics from notifications for resizing the keyboard when a text field is focused.
http://www.smallsharptools.com/downloads/ObjC/KeyboardSize.zip
The series of text fields are all wrapped inside of a UIScrollView and when the keyboard is shown a notification is sent with the height value. I use that to decrease the height of the UIScrollView so that all of content can scroll inside without being covered by the keyboard.
But I find that when I do this the other text fields sometimes cannot be tapped. They seem to be covered with a layer that I cannot see.
What can I do to ensure that the input elements in the UIScrollView remain accessible when the height is changed?
FYI: You can see in the sample project there is a blue marker on top and another red one at the bottom. The view controller which handles the resizing is CMScrollingViewController which is inherited into KeyboardSizeViewController so that this behavior can be used by multiple view controllers.
I am hoping that this problem can be fixed so this simple code can be reused.
I figured out my problem. I was setting the view which goes inside scroll view to flex the height and width using the autoresizing mask. Once I commented out that line of code this problem went away. It seems it was resizing the view but I could still see the contents of the view but it was outside the bounds of the view so it could not respond to taps.
//self.subView.autoresizingMask = (UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth);

How to have an unbounded UIScrollView

I would like to be able to build a scroll view capable of scrolling an unbounded (infinite) distance (this is question number one, how to do this with the contentSize property). The reason for this is so that I can implement a scrolling calendar view, which the user can use to scroll through time along a single axis.  
Now, I need to put a view/s in there to mark the dates as they scroll by. My second question is how to implement a view like this in a scroll view. I could have a long view, 3 or 4 times wider than the scrollview frame and just reposition and update that every time the scrolling stops, faking a continuous bar. Any other ideas?
Thanks!
I know it's been a while since you posted this question, but just for future reference:
At WWDC 2011, Apple gave a great presentation called "Session 104 - Advanced Scroll View Techniques". The video can be seen from developer.apple.com or from iTunes.
The main concept:
1 - Start off with a subview that is larger than your scrollView's bounds.
2 - In -layoutSubViews from the scrollView, you check whether the contentOffset in the direction you want to scroll infinitely is past some threshold that you specify (this doesn't have to be any specific value, it could be 1 point in the extreme).
3 - If this is the case, you reset the contentOffset to zero, and you adjust the subview's frame by the same amount.
These last two steps happen within the same run loop cycle, hence the transition will not be visible. Beware that the scrollBar will jump, though. But as your scrollView is infinite, there is no visual feedback the scrollBars could give, anyway, so you'd better hide them when you've finished implementing this.
Not sure it can be... You could try CGSizeZero
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIScrollView_Class/Reference/UIScrollView.html#//apple_ref/occ/instp/UIScrollView/contentSize
contentSize
The size of the content view. #property(nonatomic) CGSize contentSize Discussion
The unit of size is points. The default size is CGSizeZero.
The real question is do you truely want "infinate" or do you want mostly infinate and just make the view ungodly large? Or do you want auto-resizing.
Also a continuous bar for an infinite scrollview? The bar would never move as it wouldn't get any closer to the beginning or the end... You could make a bar that dragging to the right would go into the future and dragging it to the left would go back and then just always reposition it in the center.... Other then that I dunno what would make sense here.
Looping UIScrollView Horizontally sounds like the same sort of problem, hopefully my comments there might give you some ideas as well.
Making an 'infinite' scrollview doesn't work - the memory requirements get way too large. The best way to do it is fake it.
3 screen scrollview:
|---|---|---|
| | | |
|---|---|---|
Make a scrollview that is 3 times as large as one screen, then when the user finishes scrolling to the next third of the scrollview, move the scroll position back to the center third and scoot the content over to the left. This happens so fast that there is no visible feedback to the user that the scrollview & content was just recentered.
Similarly, when the user scrolls back to the first third, change the scroll position to the center third and move all the content to the right.
For memory management, you should only load as much content as will fit onto those three screens. When you scroll to the next third, you'll reposition, and load the next screen of content.