I have looked at UIScrollView. Any thoughts on implementing "infinite" scroll/zoom?, but it didn't exactly address my issue. I'm puzzled, though, because I would guess that other folks haven't seen my problem, so maybe it has to do with the details of my code. The sample code provided by Allisone is similar to mine, although I use scrollViewDidScroll to monitor the contentOffset instead of custom KVO approach.
When my UIScrollView is decelerating, if I insert a subview to the left of the UIScrollView's bounds and increase contentOffset by the width of my inserted subview, my change to contentOffset is ignored; the content "jumps" by the width of the inserted subview, and the contentOffset value stream continues on its current trajectory in subsequent invocations of scrollViewDidScroll. While simply tracking, there is no problem. Is there something I'm likely to be doing wrong? It's almost as if the bounds or contentOffset is sticky with regard to the deceleration events.
Use case: the UIScrollView has very large virtual content that is dynamically paged in and out, and when the user is smoothly scrolling through content in the UIScrollView (toward the left, say), additional content should be inserted on the far left of the scrollview without disrupting the smooth scrolling that is currently going on. As I said, this works fine if deceleration is disabled or I rely on dragging rather than flicking.
At first I hoped that the problem was caused by changing the contents of the UIScrollView from within the callout to scrollViewDidScroll, so I double-checked by doing a delayed performSelector, but the problem remained.
Thanks,
Kevin
Even though not exactly what you had in mind, but using setContentOffset:animated will have the desired outcome ( alter the content offset to the right coordinates ) although it will be animated.
Faced up with the same issue. Seems like strange UIScrollView bug. I fixed it on the base of StreetScroller example from Apple. InfiniteScrollView inherits from UIScrollView and works good in there. But if you want to create custom class which uses UIScrollView inside itself, you can subclass this UIScrollView and call delegate when it needs to recenter content like this:
tScrollView : UIScrollView
In tScrollView.m:
- (void)recenterIfNecessary {
if (_tDelegate && [_tDelegate respondsToSelector:#selector(offsetForRecenterScrollView:)])
self.contentOffset = [_tDelegate offsetForRecenterScrollView:self];
}
- (void)layoutSubviews {
[super layoutSubviews];
[self recenterIfNecessary];
}
Implement offsetForRecenterScrollView: in delegate and return new CGPoint to set in scrollView.contentOffset.
Related
I can't figure out a solution. I have a UIScrollView, and on each scroll towards right, I will increase the contentSize of the scrollView and add a View at that place. The problem is I have managed to save the last content offset by delegation when scrollview start dragging but I don't understand which delegate method to use for measuring where the gesture stopped. If I use scrollViewDidEndDecelerating, will be called immediately after the scrollViewWillBeginDragging because the content is settled to the same size of the frame.
Does anybody have any solution on it?
I have a UIScrollView with a tableview inside. Long story short, my UIScrollView's frame is being adjusted despite the fact that I'm not physically setting the frame anywhere. What I'm specifically wondering is are there any other changes you can make to a UIScrollView that will adjust the frame w/o actually manually setting the frame. I'd post some code, but I'm working on a very large codebase and I can't drop in any specific code. The reason why I'm confident that the frame isn't being programatically set is that within the ~3k or so lines of code that are being executed, setFrame or .frame = for the scrollView isn't being called. Anyways, any insight into anything else adjusting the frame as a side effect would be great. Thanks guys.
I'm experiencing something considered a bug in my situation. Probably this is not a bug but a feature ;).
Here's my case:
I load a UIScrollView with my content. A part of my content is loaded asynchrone after the view is already loaded. This works great and without issue.
Some of these controls however are UITextView controls. Once I set the content (text property) of these controls after the viewDidLoad my UIScrollView scrolls down to the last UITextView that was set. I want to prevent this and want the UIScrollView to maintain it's top scrolled position.
In summary:
If I set the Text property in the viewDidLoad method no scroll occurs. If I set the Text property on the UITextView after the viewDidLoad method (because I load the data asynchronous) the UIScrollView will scroll to the last UITextView that was set. I want to prevent this scroll.
How do I achieve this ? I have a feeling this is just a property which is set wrong but I can't seem to find it.
Thanks in advance.
EDIT:
I've tried setting the "scrollEnabled" property to NO before setting the values and to YES after but this didn't have any effect. The ScrollView will still scroll when the text property of the UITextView is set.
I Fixed the issue with a work-around:
I set the scroll view content size to something small, like 320 x 300 or whatever the height of the scrollview frame is, then did my work, then put the content size back to normal.
This prevents the scrolling while the data is loaded and enables it as soon as the loading is finished.
This would not change the scrolling problem but maybe make it "hidden" for the user:
yourTextView.text = #"Eat more bananas!";
yourScrollView.contentOffset = CGPointMake(0.0, 0.0);
Some snippets of your code would help to face the problem more specific.
EDIT:
Or try to add the UITextViews to a UIView, then add the UIView to the UIScrollView. Make sure that the UIScrollView's contentSize is the same as the Size of the UIView.
This worked for me too :p but i had to set the height to something less then 300 (in my case i just used 10).
Basically the idea is to make the text view not part of the visible area of the UIScrollView wile you are changing the text of th UITextView.
I have a UIScrollView contained within a custom UIView with a content size larger than the ScrollView's frame.
I am able to drag scroll as I expect, but the thing doesn't give me the rubber banding effect that you get with the UITableView or UIWebView. It just stops when you get to one of the extremes.
I have set bounce = YES, is there something else I'm supposed to do?
I read the docs, and they say I have to implement the delegate. I did that.
They also say I should change the zoom levels, but I don't want the user to actually be able to zoom so I haven't set these.
For anyone that finds this thread later, if you are subclassing UIView and re-setting the UIScrollView's frame on every layoutSubviews, that is the problem - it cancels the bounce:
http://openradar.appspot.com/8045239
You should do something similar to this:
- (void)layoutSubviews;
{
[super layoutSubviews];
CGRect frame = [self calculateScrollViewFrame];
if (!CGRectEqualToRect(frame, self.scrollView.frame))
self.scrollView.frame = frame;
}
I had the same problem, on a UIScrollView that wasn't all filled up (but I still wanted it to bounce). Just setted:
scroll.alwaysBounceVertical/Horizontal = YES;
And it worked as expected
It turns out that keeping the UIScrollView within my custom UIView was causing the trouble.
Once I switched my custom UIView to instead inherit from UIScrollView, then the bouncing started working.
That is interesting... Is there a lot going on while the user scrolls the scroll view? Maybe that could cause the problem. The iPhone can multitask, but not too much. Can I see your entire code having to do with the scroll view?
I'm contemplating subclassing UIScrollView (the way UITextView does) to draw a fairly large amount of text (formatted in ways that NSTextView can't).
So far the view won't actually scroll. I'm setting contentSize, and when I drag, I see the scroll indicator. But nothing changes (and I don't get a drawRect: message).
An alternate approach is to use a child view, and I've done this. The view can be over 5000 pixels high, however, and I'm a bit concerned about performance on an actual device.
(The other approach, be like UITableView, would be a huge pain -- I'm "porting" Mac Cocoa code, and a collection of views would be a huge architecture change.)
I've done some searching, but haven't found anyone who is using UIScrollView to do the drawing. Has anyone done this and know of any pitfalls?
All that UIScrollView does when the user scrolls is update its bounds rectangle, which causes the scroll views subviews to move. You could try setting the scroll view's contentMode to UIViewContentModeRedraw. From the docs:
UIViewContentModeRedraw
Redisplays the view when the bounds change by invoking the setNeedsDisplay method.