1
votes

I have a UICollectionViewController and I added two UIViews as subviews. One is the purple UIView and above it is another white UIView, with the blue collection view getting scrolled up behind both.

Below those UIViews, I made the collectionView.contentInset from the top 300 (that's the total size of two UIViews' height). What I'm trying to accomplish is to scroll the collection view along with the two UIViews above. It's almost similar to the solution on this thread (Move a view when scrolling in UITableView), except when I override scrollViewDidScroll, the whole frame gets scrolled up and cells go behind the two Views. All I want is to scroll up the UIViews, and then scroll through the collection views. I feel like this might involve nested scroll views.

enter image description here

This was how I overrode scrollViewDidScroll:

    var rect = self.view.frame
    rect.origin.y =  -scrollView.contentOffset.y - 300
    self.view.frame = rect

EDIT: I posted a video that demonstrates what I want to do per iOS Tumblr app: https://youtu.be/elfxtzoiHQo

4
don't use a UICollectionViewController and instead use a UiViewController and add a UiCollectoinView to the UIViewController with a subclass of UIView as the view for the UIVIewController then add the UIViews to the view hierarchy first and then the UICollectionViewLarry Pickles

4 Answers

5
votes

I have achieved the same requirement through some basic steps as below.

//Declare the view which is going to be added as header view
    let requiredView = UIView()

//Add your required view as subview of uicollectionview backgroundView view like as
collectionView.backgroundView = UIView() 
collectionView.backgroundView?.addSubview(requiredView)

//After that control the frame of requiredHeaderView in scrollViewDidScroll delegate method like
        func scrollViewDidScroll(scrollView: UIScrollView) {
         let per:CGFloat = 60 //percentage of required view to move on while moving collection view
                let deductValue = CGFloat(per / 100 * requiredView.frame.size.height)
                let offset = (-(per/100)) * (scrollView.contentOffset.y)
                let value = offset - deductValue
                let rect = requiredView.frame
                self.requiredView.frame = CGRectMake(rect.origin.x, value, rect.size.width, rect.size.height)
        }
1
votes

It sounds like what you want is a header.

you can specify a class or nib for the header with either of these:

self.collectionView.registerClass(_:, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier:)

registerNib(_:, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: )

you should also specify a reference height if you are using a flow layout: self.flowLayout.headerReferenceHeight = ...

then you can provide the header via your UICollectionViewController in: collectionView(_:, viewForSupplementaryElementOfKind:, at:) by checking for the section header kind.

Here is a decent tutorial on this for reference: https://www.raywenderlich.com/78551/beginning-ios-collection-views-swift-part-2

0
votes

You have a library CSStickyHeaderFlowLayout

From the ReadMe:

UICollectionView replacement of UITableView. Do even more like Parallax Header, Sticky Section Header. Made for iOS 7.

0
votes

Try this.

headerViewYConstraint is header view's top y constraint.

Stores the last contact offset.

var lastContentOffset: CGFloat = 0


override func scrollViewDidScroll(scrollView: UIScrollView) {
    if scrollView != contentScrollView {

        if scrollView.dragging || scrollView.decelerating {
            let newOffset = scrollView.contentOffset.y
            let headerViewHeight = headerView.frame.width
            if headerViewHeight > 0 && scrollView.contentSize.height > view.frame.height + headerViewHeight{
                var topOffset = newOffset == 0 ? 0.0 : (headerViewYConstraint.constant + lastContentOffset - newOffset)
                topOffset = min(0, max(topOffset, -headerViewHeight))
                if headerViewYConstraint.constant > topOffset || newOffset < headerViewHeight || lastDirectionalContentOffset - newOffset > cellHeight(){
                    headerViewYConstraint.constant = topOffset
                }
            } else {
                headerViewYConstraint.constant = 0
            }
            lastContentOffset = newOffset
        }
    }
}