HanXu
HanXu

Reputation: 5597

How to maintain a minimum height of content size of UIScrollView?

I have a UIScrollView A (in fact a UICollectionView) filling the screen inside a UINavigationController B. The controller B's adjustScrollViewInsets is set to true.

I want to hide the navigation bar when user scrolls up, and show it when down. Following is my code:

func scrollViewDidScroll(scrollView: UIScrollView) {
    if (self.lastContentOffset < scrollView.contentSize.height - scrollView.frame.size.height && self.lastContentOffset > scrollView.contentOffset.y) {
        //  dragging down
        if self.navigationController!.navigationBarHidden {
            self.navigationController?.setNavigationBarHidden(false, animated: true)
        }
    } else if (self.lastContentOffset > 0 && self.lastContentOffset < scrollView.contentOffset.y) {
        //  dragging up
        if !self.navigationController!.navigationBarHidden {
            self.navigationController?.setNavigationBarHidden(true, animated: true)
        }
    }

    self.lastContentOffset = scrollView.contentOffset.y
}

Now the problem is, since the screen of iPhone 6+ is too large, the contentSize of the scroll view A is smaller than its frame(i.e. the full screen frame) when the navigation bar is hidden. In such circumstance, the scroll view will not be scrollable, and the navigation bar will never be back again.

I want to manually maintain the height of the contentSize of A to screen at least height + 1, but don't know how to do this. Could anyone help? Or provide a better solution?

BTW, I am using iOS 8 and Swift.

Upvotes: 0

Views: 4271

Answers (5)

SilviuC
SilviuC

Reputation: 1

I stumbled upon a similar problem. I needed a minimum scrollable area for a tableview i was using.

ScrollView might be a bit easier since you can directly modify the contentView size. If you're using autoLayout, try adding equal heights constraint between the contentView and the scrollView itself. Something along the lines of contentView.height = scrollView.height + scrollMin;

For my tableView i had to subclass UITableView and override the contentSize setter.

#define MIN_SCROLL 60

- (void)setContentSize:(CGSize)contentSize {
  //take insets into account
  UIEdgeInsets insets = self.contentInset;
  CGFloat minHeight = self.frame.size.height - insets.top - insets.bottom + MIN_SCROLL;
  if(contentSize.height < minHeight) {
    contentSize.height = minHeight;
  }
  [super setContentSize:contentSize];
}

Upvotes: 0

Paulius Vindzigelskis
Paulius Vindzigelskis

Reputation: 2191

You have to change no offset (which is actually just scrolling position), but contentSize itself. That means, that when you hide navigation bar, increase contentSize by navigation height (don't remember numbers) and when you show navigation bar, decrease contentSize. Or... Use AutoLayout and layoutIfNeeded method after showing/hiding navigation bar.

Upvotes: 0

Rory McKinnel
Rory McKinnel

Reputation: 8014

An option would be to use the appearance and disappearance of cells to trigger the show/hide.

Use the delegate methods collectionView:willDisplayCell:forItemAtIndexPath: and collectionView:didEndDisplayingCell:forItemAtIndexPath: to detect movement. You can work out the direction from the index change of the cells being shown or removed. If you cannot scroll off screen then nothing happens.

Upvotes: 0

Sanjay Mohnani
Sanjay Mohnani

Reputation: 5967

Lets say you need to keep the minimum content size of scroll view to 100(of course this will be dynamic and vary according to device)

NSInteger minScrollViewContentHeight = 100;

After populating the scroll view with content, you need to check if the scroll view's content size is less than minimum required scroll views content size. If its lesser than the required content size than you need to set the minimum content size of the scroll view as follows -

if(scrollView.contentSize.height < minScrollViewContentHeight)
    [scrollView setContentSize:CGSizeMake(scrollView.frame.size.width, minScrollViewContentHeight)];

Upvotes: 1

joakim
joakim

Reputation: 4111

Off the top of my head (I'm on a phone), contentSize is not read-only I think.

How about changing it manually to the desired amount depending on the circumstances of scrolling direction etc?

Something like:

IF navbar is hidden THEN contentSize = whatever

Upvotes: 0

Related Questions