Reputation: 143
I have a UICollectionViewController (embedded in a NavigationViewController), which scrolls a UICollectionView horizontally via paging through some sections:
if let flowLayout = collectionView?.collectionViewLayout as? UICollectionViewFlowLayout {
flowLayout.scrollDirection = .horizontal
flowLayout.minimumLineSpacing = 0
}
collectionView?.backgroundColor = .white
collectionView?.register(FeedCell.self, forCellWithReuseIdentifier: cellId)
//collectionView?.contentInset = UIEdgeInsetsMake(MenuBar.height, 0, 0, 0)
//collectionView?.scrollIndicatorInsets = UIEdgeInsetsMake(MenuBar.height, 0, 0, 0)
collectionView?.isPagingEnabled = true
Each section or page contains another UICollectionView (inside the FeedCell) which scrolls vertically through some UICollectionViewCells.
Inside the UICollectionViewController, I set
navigationController?.hidesBarsOnSwipe = true
which was working as long as there was only one UICollectionView. But since the (Top)CollectionView is scrolling horizontally and is containing additional (Sub)CollectionView, that are scrolling vertically, this feature seems not to work any longer.
I would like the NavigationBar to hide when the (Sub)CollectionView is scrolling vertically. Is there any hack to achieve this?
Upvotes: 2
Views: 645
Reputation: 589
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if let navigationBar = self.navigationController?.navigationBar {
let clampedYOffset = contentOffset.y <= 0 ? 0 : -contentOffset.y
navigationBar.transform = CGAffineTransform(translationX: 0, y: clampedYOffset)
self.additionalSafeAreaInsets.top = clampedYOffset
}
}
This is a solution that I came up with. Basically modify the transform of the NavigationBar to move it out the way when necessary. I also modify the additionalSafeAreaInset, as this will automatically shift all your content up to fill the space left by the navigation bar.
This function will be called as part of the UICollectionViewDelegate protocol.
This was suitable for my purposes - but if you want the navigation bar to appear when the user rapidly scrolls up (like in safari) you will have to add some additional logic.
Hope this helps!
Upvotes: 0
Reputation: 114
You can try the code like this (Swift 3.0):
extension ViewController: UICollectionViewDelegate {
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let isScrollingUp = scrollView.contentOffset.y - lastY > 0
lastY = scrollView.contentOffset.y
self.navigationController?.setNavigationBarHidden(isScrollingUp, animated: true)
}
func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
if !decelerate {
// show navigation bar ?
}
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
// show navigationBar ?
}
}
Upvotes: -2