UIScrollView - setting proper contentOffset for new contentSize yields undesirable empty space - iphone

I have been juggling for a while with UIScrollView now. What I am trying is to insert subviews into the scrollView based on various factors. Since I have scrollview to scroll only in vertical direction, I would insert the subview before or after the current visible view.
So, lets say my current visible view's frames are (0,0,320,480), the contentSize of scrollView is (320,480) and current contentOffset is (0,0)
When I want to insert subview above the currentView and yet keep the currentView in focus, I insert the new subview at the position (0,-480,320,480) and change the contentSize of scrollView to (320, 960) while keeping the contentOffset same as (0,0).
The surprising thing which happens is, UIScrollView adds "extra" space after the currentView instead of inserting it above the currentView. While the newly inserted view above can never be brought into focus coz UIScrollView is assuming the contentSize from a wrong contentOffset perhaps!
I googled and found that there are some others facing similar problems, but did not yield results yet:
Set starting point of content size for UIScrollView
Please let me know if I am doing anything wrong? Or is this some kind of limitation etc?
Thanks!
Edit: Some threads suggests that changing the contentSize will affect contentOffset property, so to make sure that this is not causing problem, I am updating the contentOffset property only after I change the contentSize. Even then I am facing same problems.

You could solve this by :
adding your new subview with frame (0,0,320,480)
setting the frame of your existing subview to (0,480,320,480)
setting the contentSize to (320,960)
setting the content offset to (0,480) - not animated, of course.
So, in effect, moving everything down 480 points

The origin is always (0,0). If you want to insert something above the current offset you'll want to move the current views down by 480 points, add the new view at (0,0) and set the contentOffset to (0,480) (and the contentSize to (320,960).

Related

iOS UIScrollView in UIWindow

I currently am making an iOS project in which I have a UIScrollView as a direct subview of a UIWindow (using [window addSubview:scrollView];). The window's frame and its content are being set properly, and the contentSize is set to be bigger than the window's frame. When I try to scroll the UIScrollView, it doesn't scroll at all. Both scrollEnabled and pagingEnabled are set to YES, but the scrollview doesn't scroll, which leads me to believe that the touch/scroll events are not even being received by the scroll view. The window has a UITapGestureRecognizer added to it if it makes any difference. Do I need to somehow forward the swipe events to the UIScrollView, or is there a different reason that it's not scrolling?
EDIT: Here's some code.
float count=ceil([self.msgArray count]/2); //msgArray has length of 3+, NSLog()'d and confirmed.
float contentHeight=97.5 * count;
[dataScrollView setContentSize:CGSizeMake(320,contentHeight)];
dataScrollView.userInteractionEnabled=YES;
dataScrollView.pagingEnabled=YES;
dataScrollView.scrollEnabled=YES;
dataScrollView.clipsToBounds=YES; //Have also tried with this set to NO, or not set at all.
//Add subviews to dataScrollView.
EDIT: Here's some more info.
contentHeight is 195.00 when logged. I've removed the delegate method and I am back to using direct subviews of the scroll view. The window's height is 97.50.
EDIT: I've also removed the UITapGestureRecognizer from the UIWindow, but the scrollview still doesn't scroll.
Ah, the UITapGestureRecognizer! This might be a bug that took me hours to figure out in my own project. Is its cancelsTouchesInView property set to NO like it should be? (YES is the default... It can really throw you off if you're not expecting it.)
Just log the scrollview bounds width/height. The content height you are setting should be greater than the scrollview height. If its more then the scroll view automatically enables its scrolling.

iOS How to get the content offset of a view inside a scrollview

Lets say I add 10 views to a scrollview. I obviously give them a rect inside of the scrollview. Is there any way to figure out what each item's offset is in the scrollview?
I'm guessing that probably isn't applicable here. What I need in essence is, "If this item is at this content offset in the scrollview (meaning visible to the user in a certain area of the scrollview), then do this".
Each view's frame is expressed in its superview coordinate system (bounds). That is, in your case for each view its content offset is CGRectGetMinY(view.frame).
You might want to find the current scroll position by looking at UIScrollView contentOffset
The point at which the origin of the content view is offset from the origin of the scroll view.
With the contentOffset, you can then compare this with the frame x and y coordinates of the content views and determine if they are onscreen or not.

how to set current scrolling values

If I have a UIScrollView and move it around to a specific location, is there any way to get that position it has moved too?
Check UIScrollView's contentOffset property:
contentOffset - The point at which the origin of the content view is offset from the origin of the scroll view.
Get the current UIScrollView scroll values on the iPhone

UIScrollView Updating contentSize Causes Scroll

I have a UIScrollView that has a single child view within it. If I set the contentSize of the UIScrollView immediately after creation, everything works as I expect and I get scrolling.
The challenge is the view within the UIScrollView is dynamically sized. The width is fixed, but the height is unknown at the time I set up the scrollview.
When I do a [scrollView setContentSize:CGRectMake(...)] after the inner view does it's thing, the scrollview updates to the proper size and scrolling works. So basic scrolling works fine.
However, the major problem is that when I setContentSize at a later point, the UIScrollView decides to scroll down(with animation) towards the end of the scrollview, which is not what I want, I want the scroll to stay at the top, and let the contents within the scrollview either get bigger or smaller, without changing the apparent scroll position.
What am I missing?
Why don't you also call [scrollview setContentOffset:CGPointMake(0,0)]; when you call the setContentSize?
To force UIScrollView to scroll only e.g. horizontally, I always set non-scrollable value for contentSize to 0, using:
CGSizeMake(contentSize.width, 0).

How much contentOffset changes in UIScrollview for zooming?

In UIScrollview, when I scroll/drag, I got changes in scrollview contentOffset which represent how much I had scrolled/dragged in the scrollview. By this way, I have updated the subview of scrollview for scrolling.
But, when I zoom the scrollview (using pinch zooming), the contentOffsets of the scrollview is also changed. I do not understand how much contentOffset has changed because I can not relate the changes with zoomScale value. So, is there anyway to know changes in contentOffset for zooming?
My intention is get the value of contentOffset changes for dragging while zooming (which is not I am getting because of zooming content offset changes) so that I can update my scrollview's subview accordingly.
I am stuck in here. Any help will be very much appreciated.
thanks
Shaikot
I've set up a small test project, and it looks like the contentOffset is multiplied by the zoomScale. So if you want to account for that, just divide it by the zoomScale before using it.
Maybe it's best to illustrate with a small example:
I've set up a scrollView, and added a view that's big enough to pan around and zoom a bit. To that view, I've added a small red view that I want to keep in the same position, no matter what.
I'm observing the contentOffset property of the scrollView, and I've implemented it like this:
CGPoint contentOffset = self.scrollView.contentOffset;
CGFloat zoomScale = self.scrollView.zoomScale;
self.moveView.frame = CGRectMake((contentOffset.x+10)/zoomScale,
(contentOffset.y+10)/zoomScale,
10,
10);
This keeps the moveView in the same position on the screen, only scaling it when the user zooms.
I hope this clears thing up a bit, but let me know if I can do more to help.