problem getting the height of a UIScrollView - iphone

i am setting the size of a UIScrollView in viewDidLoad: but when I try to get the height of it, i am getting 0 in the console
here is my code:
- (void)viewDidLoad {
[scrollView setContentSize:CGSizeMake(320,500)];
NSLog(#"scrollView: %#", scrollView);
NSLog(#"scrollView.contentSize.height: %i", scrollView.contentSize.height);
[super viewDidLoad];
}
and in the console log i get
scrollView: <UIScrollView: 0x4974110; frame = (0 0; 320 367); clipsToBounds = YES; autoresize = RM+TM; layer = <CALayer: 0x4974010>>
scrollView.contentSize.height: 0
Shouldn't scrollView.contentSize.height be returning 367? On a related note, i specified the height to be 500 via [scrollView setContentSize:], but that doesn't appear to be applied either?

No. The contentSize is the size of the stuff inside the scrollview. Since nothing is inside the scrollview (ie you're not scrolling anything), the height is 0. The only way to get a valid contentSize is after you've added a subview.

Related

Can't get scrollsToTop working on iOS7

I'm targeting iOS7 in my latest app, and tapping on the status bar doesn't seem to scroll a tableView or collectionView to the top.
I've set self.tableView.scrollsToTop = true and still nothing happens.
I know Apple significantly changed the status bar in iOS7, but did those changes break the scrollsToTop functionality?
Update
In response to a comment in one of the answers, I tested to ensure that my collection view was indeed the only scrollView on the screen, and it was:
(lldb) po [self.view recursiveDescription]
<UIView: 0x1092ddf0; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x109357e0>>
| <UICollectionView: 0x11351800; frame = (0 0; 320 568); clipsToBounds = YES; opaque = NO; autoresize = W+H; gestureRecognizers = <NSArray: 0x10966080>; layer = <CALayer: 0x109623a0>; contentOffset: {0, -64}> collection view layout: <UICollectionViewFlowLayout: 0x10940a70>
| | <UIImageView: 0x10965fa0; frame = (0 564.5; 320 3.5); alpha = 0; opaque = NO; autoresize = TM; userInteractionEnabled = NO; layer = <CALayer: 0x10965ee0>> - (null)
| | <UIImageView: 0x10948f60; frame = (316.5 561; 3.5 7); alpha = 0; opaque = NO; autoresize = LM; userInteractionEnabled = NO; layer = <CALayer: 0x10966030>> - (null)
Update #2
Not sure if it matters, but I'm using a standard iOS7 NavigationController where the navigationBar is transparent and applies a blur to my collection/tableViews as they scroll underneath.
Update #3
Figured it out. Turns out I did have more than one scrollView on the screen. My app has a left drawer menu underneath the main part of the app, and that menu has a tableView for the options. I simply set self.menuTable.scrollsToTop = false and everything worked as expected throughout the rest of the app. Didn't have to implement the scrollView Delegate methods or anything.
Do you have more than one scroll view/table view/collection view on screen? If so, only one of them can have scrollsToTop set to YES, otherwise iOS7 will not scroll any of them to the top.
You can also implement the UIScrollViewDelegate method scrollViewShouldScrollToTop: and return YES if the passed in scroll view is equal to the one that you want to scroll to the top:
- (BOOL) scrollViewShouldScrollToTop:(UIScrollView*) scrollView {
if (scrollView == self.myTableView) {
return YES;
} else {
return NO;
}
}
The short answer is there's nothing different in iOS7. As long as there isn't more than one UIScrollView loaded, your tableView or collectionView will scroll to the top when the user taps the status bar. The key here is loaded; another scrollView doesn't necessarily have to be on screen to conflict with another scrollView that is.
Sliding drawers in the left/right are very popular these days, and this was the reason for my problem. I have a menu containing my navigation options, and these are all held by a UITableView. I had to make sure that I set menuTable.scrollsToTop = false before I could get things working in the other parts of my app.
My problem was that I had a UITextView with scrollsToTop set to YES, so my UITableView wasn't responding to the gesture. In short, make check all other scrollable views.
for others :
Remember that the scroll view you are searching can also be a UIWebView..not just UITableView.
Another important thing is that it's not only about VISIBLE scrollViews, but LOADED scrollviews.
If you don't find the scrollView, you can always
insert UITableView test table, immediately when app is starting, check if it's scroll to top,
and then load more and more views, until the test table stop scrolling to top.
If your table cells are dynamic, remove the following:
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView
{
return YES;
}
Create a new function as follows:
- (void) disableScrollsToTopPropertyOnAllSubviewsOf:(UIView *)view {
for (UIView *subview in view.subviews) {
if ([subview isKindOfClass:[UIScrollView class]]) {
((UIScrollView *)subview).scrollsToTop = NO;
}
[self disableScrollsToTopPropertyOnAllSubviewsOf:subview];
}
}
Call the function above in - (void)viewDidLoad
[self disableScrollsToTopPropertyOnAllSubviewsOf:self.view];
Now enable ScrollsToTop for your table view as follows:
[myTableView setScrollsToTop:YES];
This always works for me:
[self.tableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];

zooming in a UIScrollView changing the (zoom-scaled) content size

I've got a vertically scrolling scroll view with frame (1000, 500) and contentSize (1000, 1500). This works fine. However, as soon as I zoom in, it crops the content size to whatever I was looking at before the zoom, so, I can't scroll vertically anymore past the original bounds. That is, if I zoom to 2x from the default view, it now reports contentSize as (2000, 1000) instead of the expected (2000, 3000). I can't scroll past that initial (1000, 500) rectangle I was looking at. When I zoom back out to 1x, I still can no longer scroll vertically; it changes the contentSize to (1000, 500).
How do I fix this? Can I not combine scrolling and zooming in the same UIScrollView? I tried saving the height before zoom, and then correcting the contentSize in the didEndZooming delegate method (contentSize = (width, savedHeight * scale)), but then it displays all sorts of odd behavior, including jumping around on landing.
Shouldn't this just work out of the box? Am I crazy?
- (void)createPage {
self.fullWidthScroller = [[UIScrollView alloc] initWithFrame:CGRectMake(0,0,LANDSCAPE_WIDTH,LANDSCAPE_HEIGHT)];
[self.view addSubview:self.fullWidthScroller];
self.fullWidthScroller.contentSize = CGRectMake(0,0,LANDSCAPE_WIDTH,LANDSCAPE_HEIGHT*2);
self.fullWidthScroller.delegate = self;
self.fullWidthScroller.minimumZoomScale = 1.0;
self.fullWidthScroller.maximumZoomScale = 3.0;
self.fullWidthScroller.bouncesZoom = YES;
self.container = [[UIView alloc] initWithFrame:CGRectMake(0,0,LANDSCAPE_WIDTH,LANDSCAPE_HEIGHT)];
[self.fullWidthScroller addSubview:self.container];
self.page = [[SinglePageViewStretched alloc] init];
[self.container addSubview:self.page]; //container gets another view added elsewhere
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return self.container;
}
- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale {
NSLog(#"size: %#", NSStringFromCGSize(scrollView.contentSize));
NSLog(#"offset: %#", NSStringFromCGPoint(scrollView.contentOffset));
//scrollView.contentSize = CGSizeMake(scrollView.contentSize.width, self.contentSizeHeight * scale);
}

how to paginate UIScrollView with different page sizes?

I'm trying to do a horizontal scroll of UILabels with different widths.
I've already put all labels next to each other inside the UIScrollView, but since the page scrolling, bouncing and snapping is done in scrollview.frame.width "steps", i cannot set it to work as I'd wish.
Can this be done? Thank you so much :)
What happens if you set the size of your width property to be the width of the next label? Something like (in your scroll view delegate) :
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
// Get the label that's going to slide into view
UIView *label = [self getCurrentLabel];
// Get it's width
float width = [label frame].size.width;
// Set our size
CGRect frame = [scrollView frame];
frame.size.width = width;
[scrollView setFrame:frame];
}
PS I've not tried this so it might just fail horribly!

UIScrollView- How far is it scrolled?

I'm using an UIScrollView and I have an image that indicates to the user that there is more content that they can scroll through vertically. I would like this image to be hidden when the scrollview is all the way at the bottom. Is there a way to do this? Would I have to subclass UIScrollView and make my own?
your scroll view's delegate should repsond to scrollViewDidEndScrollingAnimation: and use that to check where you are
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
// Get some details about the view
CGSize size = [scrollView frame].size;
CGPoint offset = [scrollView contentOffset];
CGSize contentSize = [scrollView contentSize];
// Are we at the bottom?
if (-offset.y + size.height <= contentSize.height)
NSLog(#"bottom");
else
NSLog(#"not bottom");
}
NB The if statement was done in my head so it might be the wrong way round ;)

iPhone SDK Scroll View displaying extra space

I've got a scroll view, in which I have an imageview displaying a 960x960 image, but it scrolls to something close to 4x that. I've tried to log the widths of all possible views and everything claims that it's 960x960 (or smaller, I think I logged the screen width once...?)
I need this image to stop scrolling at the bottom right corner of the image rather than entering deadspace. Any help would be greatly appreciated.
Heck, even telling me what the name of the object is that is larger than my scrollView.contentSize would put me on the right track...
//Test-Image is just a 960 by 960 image that's numbered around the edges 1-10 so you can tell if it's being moved
UIImageView *tempImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Test-Image.png"]];
self.imageView = tempImageView;
[tempImageView release];
scrollView.contentSize = CGSizeMake(imageView.frame.size.width, imageView.frame.size.height);
//Tested with this, results the same.
//[scrollView setContentSize:CGSizeMake(960, 960)];
NSLog(#"What is my scrollView's height attribute?...%f", scrollView.contentSize.height);
// Returns 960
NSLog(#"What is in scrollView's width attribute?...%f", scrollView.contentSize.width);
// Returns 960
scrollView.contentOffset = CGPointMake(480, 480);
scrollView.maximumZoomScale = 8.0;
scrollView.minimumZoomScale = 0.25;
// Commenting clipsToBounds out doesn't seem to have any effect
scrollView.clipsToBounds = YES;
scrollView.delegate = self;
[scrollView addSubview:imageView];
Unfortunately, I do not have a specific answer.
Reference. Try [scrollView addSubview: self.imageView]; instead of [...addSubview: imageView];
Content Size. Try setting the content size after adding the ImageView.
[scrollView setContentSize: CGSizeMake(imageView.frame.size.width, imageView.frame.size.height)];
Delegate. Did you use and set the scrollview's delegate property (oIWScroll.delegate = self;)?
Clipping. It should not matter.
ScrollView Frame. Make sure the frame of the scrollview is equal to or smaller than [UIScreen mainScreen].applicationFrame.
Framing. When I had a situation similar to what you described, one of the the things I did was to create a container UIView, add it to the scroll view and stuff the objects into the container view. But you really should not have to do that for one image.
I also set the contentMode = UIViewContentModeTop.
I hope these suggestions help.