UIScrollView Always Bounces back to Top - ios

I've seen a couple of other posts on this, and have attempted to implement their suggestions, but I'm still having the same problem. I have a UIScrollView the contains a UIContentView that in turn contains various labels and a UIWebView. The content scrolls well enough, but it's too long for the screen (by design - that's why I am using a scroll view). As my finger slides to the top of the screen, I need to let go and move my finger to the bottom to continue scrolling. The instant that I let go of the screen, the content bounces right back to the top, thereby negating the scrolling that I have done. This makes it impossible to see the remaining information farther down.
I know that my UIContentView has a height that is greater than the maximum y-value of the last object. I verified this with some NSLog statements to print out what the last y value is. What else might I be missing? I've made many other UIScrollViews work, so I don't know what I am overlooking here.
Thanks!
- (void) viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
[self.scrollView layoutIfNeeded];
self.scrollView.contentSize = self.contentView.bounds.size;
}

You shouldn't be doing that in viewDidLayoutSubviews. Assuming that contentView has a fixed size, and isn't being autoresized or changed by auto-layout, then you can put the line
self.scrollView.contentSize = self.contentView.bounds.size;
in the viewDidLoad method.
The layoutIfNeeded line serves no purpose and should be removed.

Related

UIScrollView includes extra space at bottom

I have a UIScrollView which continually adds extra space at the bottom of its scroll area on iOS 7. If I rotate the device, the problem fixes itself, however, before rotating after first navigating to the view controller, the extra space always appears. I've included an image below:
What I've tried:
Set automaticallyAdjustScrollViewInsets to NO
Checked contentSize, contentOffset and contentInset. All appear fine.
I'm not sure what else to try to solve this issue, and would greatly appreciate any help or direction here!
Edit: As another layer of complexity to this issue... I call a method, updateScrollViewContentSize in my viewDidAppear: method. When I rotate, and it somehow fixes itself, this same method is called. So my contentSize is being set when my view appears and when I rotate.
To make things worse, the content size is always set to 638... Whether there is extra space or not. But, for some reason, the scrollView ignores this until we rotate.
Here is the method to update the contentSize:
- (void)updateScrollViewContentSize {
[self.scrollView setContentSize:CGSizeMake(self.scrollView.frame.size.width, (self.feedbackFooterView.frame.origin.y + self.feedbackFooterView.frame.size.height + 20))];
}

UIWebview in UIScrollview send vertical scroll event to scrollview

So i have a UIWebView that is meant to only scroll horizontally, and its in a UIScrollView that is only meant to scroll vertically. I have almost managed to achieve this, but i have a slight problem.
The UIWebiew's scroll content height is set to the height of the webviews frame, so that it wont scroll vertically, but even when this is the case, it still seems to consume the vertical scrolling event (sometimes), since i can see the side scroll bar show, but it wont scroll (and doesnt scroll the scrollview that the webview is contained in).
It needs to be like this because there are some elements that need to scroll vertically with the webview, but not horizontally (think of the safari app how the addressbar scrolls with the webview)
does anyone know how i would pass the vertical scroll event through but keep the horizontal scroll event for the UIWebView?
i had a look at this answer but its not quite what im looking for
update:
so typically just after i ask the question i find a suitable answer on another question... (had been searching for a few hours now) this answer should do the trick for me, ill give it a go and report back
Just set
scrollView.alwaysBounceVertical = NO;
scrollView.contentSize = CGSizeMake(
scrollView.frame.size.width, scrollView.contentSize.height);
scrollView.showsVerticalScrollIndicator = NO;
Edit:
doesn't seems to work. Too bad..
Try implementing
- (BOOL)gestureRecognizer:(UIGestureRecognizer*)gst
shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer*)gst2 {
return YES;
}
..in your view containing the scrollView and webView, or even the scrollView itself (containing the webView).
So the solution i found that i posted in the question works for the most part, it does exactly what i need, but for some reason after a webpage loads, it scrolls the headerbar away showing just the webpage, which isnt the end of the world but its not pretty. it seems the event fires after the webViewDidFinishLoad: so i cant just reposition it back to the top. Ill keep tinkering around, maybe i can find out why its doing it.

UIScrollView gets disabled in one direction - iOS

I have a UIScrollView with no vertical scrolling, and on which I force a particular offset (only x) in case the offset tries to become less that that particular offset.
I use setContentOffset:animated: function, with animated argument as YES. The offset is forced correctly.
After I force the offset, 'sometimes' scrolling in the direction opposite to the initial scroll direction gets blocked. Say, I was scrolling with finger pan from left to right, and forced it to some offset, then I can't scroll from right to left anymore.
But the catch is, if I make any tap on the screen, the scrolling starts happening. I am unable to pan, but if I tap the screen, or tap any button, scrolling starts working. If I try to call the button press method programatically after, say 5 seconds of forcing the offset, then it doesn't work. It seems that I need to touch the screen somehow..
I checked the values of contentOffset, contentSize, they seem fine.
PS: there are times when scrollViewDidEndScrollingAnimation: method is not called after forcing the offset, but that is not necessarily the issue.
Edit: Actually, this thing happens when I take the scroll view beyond the threshold offset using my fingers, and keep panning left. At the threshold point, panning stops, but the next time I try to scroll, it doesn't pan. (i.e., I don't give a jerk to go beyond the threshold).
Edit: One more possible loophole: I make scrollEnabled equal to NO just before forcing the new offfset, and just after giving the command to set the new offset, I set it back to YES. I needs to be done so that if I try to scroll the scrollview with a jerk, it doesn't scroll away to the left while trying to set the new offset, since paging is enabled.
Edit: Could it be because I set scrollEnabled to NO while actually scrolling using touch? I do enable it later, but maybe that is some issue...
Important Edit: If I long press on the scrollView, and then try to move, scroll view starts scrolling!
Edit: This code is in scrollViewDidScroll:
if ((theScrollView.contentOffset.x < theScrollView.frame.size.width)
&& [currentlyDisplayedVC isEqual:VC1])
{
//if this is not done, and this call happens when VC3
//is visible a bit too much, scrollView scrolls till VC3.
scrollView.scrollEnabled = NO;
[scrollView setContentOffset:CGPointMake(scrollView.frame.size.width, 0) animated:YES];
scrollView.scrollEnabled = YES;
//this is done so that this block is not reached everytime during scroll animation.
currentlyDisplayedVC = VC2;
}
Then in scrollViewDidEndWithANimation: I add [self VC2reached]
Have you tried using setUserInteractionEnabled:NO and YES to stop/allowing user to interact with the UIScrollView instead of using the scrollEnabled property?
I subclassed UIScrollView and overrode the method touchesShouldBegin:withEvent:inContentView:. In the method I return NO for that particular moment when I see the view stuck, so that all touches are taken in by the scroll view instead of passing them to any other contentView. That solved the problem.
Edit: That doesn't solve the problem actually. I want to disallow touches on contentView ONLY when an attempt to scroll the scrollview is being made, not when some other event like tap on the contentView is attempted. But in ths olution that I posted, all touches will be kept with the scroll view. Do we have a similar touchMoved: method?
Instead of using setContentOffset:animated:
you should try using scrollRectToVisible:animated:

UIScrollView not working

I have a UIScrollView with a View inside of it. Inside of that view is a bunch of buttons, labels, etc that fit in the View when in Portrait mode...When the iPad is rotated, I want the scrollView to kick in so the user can scroll to the bottom of the view. The app runs, but when I rotate it, the scroller never works...I believe I've wired everything up correctly and I have this code in the viewDidLoad event:
[scrollview addSubview: masterView];
scrollView.contentSize = [masterView sizeThatFits:CGSizeZero];
Is there something else I am missing? Do I need to modify the size when the iPad rotates?
thanks
There may be a problem with the content size of the UIScrollView. Without the contentSize being set larger than the actual scrollView size, scroll bars won't be shown.
You can code this in with something like this:
[scrollView setContentSize:CGSizeMake(2000,2000)];
And then changing the content size to the actual content size of what you are putting in the UIScrollView (scrollView).
If you look at the results of [masterView sizeThatFits:CGSizeZero] (e.g. NSLog or set a breakpoint in your debugger, I think you will find that it's not what you expected it to be. You might find that masterView has autoResize parameters set (which is common for a view that covers the entire screen), which means that it might, itself, be getting resized too short to fit all of its controls and scrollView is simply grabbing this shortened value itself. Take a look at that CGSize and the problem will be obvious.
I faced similar situation but my case was iPhone.
Remember that content should be larger than scroll for scrollView to kick in.
"Why would you want to go down if everything is visible in front of you ?"
use the following code:
[scrollView setContentSize:CGSizeMake(intValue, intValue)];
intValue: Integer values setting width and height of scroll.
Even if it doesn't works, don't worry there are loads of other options to figure out the solution:
1. NSLog
2. Breakpoints
3. Put up errors you are getting from console on stackoverflow

How can I let UIScrollView (pagingEnabled) to move 1.2 page each time?

Ok. here is the story:
I have a UIWebView in full screen, width = 768
It loads several images and those images are in one line, which means the UIWebView will scroll only horizontally.
Now, I set the UIScrollView inside the UIWebView to pagingEnabled = YES. So the scroll on the UIWebView will move page by page.
The problem is that every image's width is about 900. I won't scale them down and if I scroll the UIWebView, from the 2nd page on, always 132points of previous image will show. This is not good for me.
So how can I manipulate the UIWebView or the UIScrollView inside the UIWebView so that each scroll will move a page of 900 points, if the view's frame width is 768?
The constraints are:
I can't change its contentSize
I can't change its bounds or frame
I say these constraints because UIWebView will change them on its own purpose when it loads contents.
Anyone would like to join this brain storming?
Thanks
I'm thinking you're going to need to set a UIScrollView delegate that tracks touches beginning and ending. More specifically, scrollViewDidEndDragging:willDecelerate is what I'm thinking you'll need to use, as it fires the instant a user lifts their hand from the device.
First, pagingEnabled=NO seems obvious, we're going to have to control our own paging. Which, I don't feel is too tough. Track the direction of the scrolling in scrollViewDidScroll:, so that we have some global set:
BOOL isGoingRight = YES or NO (NO means the last movement was to the left)
float PAGESIZE = 900.0;
Here's how my scrollview delegate method would look like that handles paging.
- (void) scrollViewDidEndDragging:(UIScrollView*)_scrollView willDecelerate:(BOOL)willDecelerate {
float offsetProportion = _scrollView.contentOffset.x/_scrollView.frame.size.width;
//depending upon our direction, round up or down
int page = isGoingRight? ceilf(offsetProportion): floorf(offsetProportion);
//manually finish the scroll
[_scrollView scrollRectToVisible:CGRectMake(page*PAGESIZE, 0, _scrollView.frame.size.width, _scrollView.frame.size.height) animated:YES];
}
I didn't test this, you may or may not need to disable touches at points.

Resources