UIScrollView- How far is it scrolled? - iphone

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 ;)

Related

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);
}

Locking UISearchBar on top of TableView

I wanted to lock search bar on top of table view when y boundary reaches 0 ( or beyond - value)
I tried to in scroll view delegate method, but nothing really changed. In fact, the search bar's frame changed, but it still behaved as default.
Any ideas?
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
UISearchBar *searchBar = self.searchDisplayController.searchBar;
CGRect rect = searchBar.frame;
rect.origin.y = MAX(0, scrollView.contentOffset.y);
self.searchDisplayController.searchBar.frame = CGRectMake(0,MAX(0,scrollView.contentOffset.y),320,44);
}
In your viewdidload method you need to offset the table view:
self.tableView.contentOffset = CGPointMake(0.0, 44.0);
Then In IB drag a searchbar above your UITableview in your UINavigation controller
Or prgrammically add it.
You need to call setNeedsLayout if you're running on iOS 6.0+.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
UISearchBar *searchBar = self.searchDisplayController.searchBar;
CGRect rect = searchBar.frame;
rect.origin.y = MAX(0, scrollView.contentOffset.y);
[scrollView setNeedsLayout]; // <-- Call setNeedsLayout here.
self.searchDisplayController.searchBar.frame = CGRectMake(0,MAX(0,scrollView.contentOffset.y),320,44);
}

UITextView - disable vertical scrolling

How can I disable vertical scrolling in my UITextView? I want it to basically just scroll horizontally.
In some circumstances, when trying to clamp down on unwanted UITextView scrolling I have found it helpful to add something like the following to the UITextView delegate (this is a UIScrollView delegate method but, of course, UITextView inherits from UIScrollView). This might work for you.
- (void)scrollViewDidScroll:(id)scrollView
{
CGPoint origin = [scrollView contentOffset];
[scrollView setContentOffset:CGPointMake(origin.x, 0.0)];
}
What about the scrollEnabled property? Setting the scrollEnabled property to NO stops the user from scrolling (in both directions), but there are occasions where the system sends setContentOffset:animated: messages to a UITextView. The scrollEnabled property applies to both vertical and horizontal scrolling. Given your question, you might want to leave scrollEnabled as is.
You can change it from Xcode -
Solution for disabling vertical scrolling for Swift 4:
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let origin: CGPoint = scrollView.contentOffset
scrollView.contentOffset = CGPoint(x: origin.x, y: 0.0)
}
If you have your custom textView subclass, you can override -gestureRecognizerShouldBegin to disable the scroll.
-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]])
{
if (gestureRecognizer.view == self)
{
return NO;
}
else
{
return [super gestureRecognizerShouldBegin: gestureRecognizer];
}
}
}
why not just use a UITextField if you dont want vertical scrolling?
Just set the contentSize to the height of the view.
You'll use this:
CGSize scrollableSize = CGSizeMake(widthOfContent, heightOfView);
[myScrollView setContentSize:scrollableSize];
place your UITextView in a UIScrollView.
Set your UITextView.frame to a Size the complete Text fits in a Line and set the contenSize of the ScrollView to the size of your UITextView.frame.
Cheers
nettz

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 - with paging enabled, can I "change" the page width?

What's the simplest way to have a scroll view (with pagingEnabled set to YES) have a page width set to something other than the scroll view's bounds?
Let me give an example. Suppose I have a scroll view with 10 items, each 150 pixels wide, and my scroll view is 300 pixels wide. If I start with views 1 and 2 visible and scroll horizontally to the right, I want the next "page" to show items 2 and 3. If I scroll one more page to the right, I would see items 3 and 4.
Has anyone done this? If not, what strategy would you use?
Alexander Repty just blogged about this very topic: http://blog.proculo.de/archives/180-Paging-enabled-UIScrollView-With-Previews.html. Short answer: it's not as simple as just changing the width of the 'page', but it's not too hard.
Mike,
use the approach from my blog that Ben linked you to. Make the UIScrollView half the size of the surrounding view (i.e. 150px) and move it to the left instead of leaving it centered.
That should give you exactly the behaviour you wanted.
Cheers,
Alex
It can surely be done with the help of scrollview delegate methods & content-offset.
Below is the detailed code for the same.
int start;
int end;
int k=0;
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView1
{
pageControlUsed = NO;
start = scrollView.contentOffset.x;
}
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView1 willDecelerate:(BOOL)decelerate
{
end = scrollView.contentOffset.x;
}
- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView1{
int diff = end-start;
if (diff>0)
{
k=k+150;
[scrollView setContentOffset:CGPointMake(k, 0) animated:YES];
}
else {
k=k-150;
[scrollView setContentOffset:CGPointMake(k, 0) animated:YES];
}
}
Simply override scrollViewWillEndDragging
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
CGFloat pageWidth = 160;
targetContentOffset->x = pageWidth * (int)(targetContentOffset->x / pageWidth);
}
UIScrollView *album = [[UIScrollView alloc] init];
album.translatesAutoresizingMaskIntoConstraints = NO;
album.pagingEnabled = YES;
album.clipsToBounds = NO;
album.showsHorizontalScrollIndicator = NO;
album.contentInset = UIEdgeInsetsMake(0, -50, 0, -50);
[view addSubview:album];
[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"H:|-50-[_album(220)]" options:0 metrics:metrics views:views]];
[view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:#"V:|[_album(300)]" options:0 metrics:metrics views:views]];
this works fine on iOS 7.1~ 8.2