AnimatedCollectionViewLayout icon indicating copy to clipboard operation
AnimatedCollectionViewLayout copied to clipboard

Library Usage

Open heuism opened this issue 8 years ago • 9 comments

problem

after i followed the thing, i got this as result.

It doesnt seem like it working right. Just a normal CollectionView and even the snap is not on point. Can you help me with this? I am newbie.

the following code

super.viewDidLoad()

        animator = (ParallaxAttributesAnimator(), true)
        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false

        // Register cell classes
//        self.collectionView!.register(SimpleCollectionViewCell.self, forCellWithReuseIdentifier: "CollectionCell")
//        
//        self.collectionView?.register(<#T##cellClass: AnyClass?##AnyClass?#>, forCellWithReuseIdentifier: <#T##String#>)

        // Do any additional setup after loading the view, typically from a nib.
        
        // Must turn paging on.
        collectionView?.isPagingEnabled = true
        
        if let layout = collectionView?.collectionViewLayout as? AnimatedCollectionViewLayout {
            layout.animator = animator?.0
        }

heuism avatar Feb 22 '17 02:02 heuism

Hey @heuism, I think there're several possible reasons.

  • Check if your collectionView is full screen on the device.
  • Check if your delegate method collectionView(_:, layout:, sizeForItemAt:) -> CGSize returns the full screen size. (something like view.bounds.size or collectionView.frame.size)
  • Check if your delegate method collectionView(_:, layout:, section: Int) -> UIEdgeInsets returns UIEdgeInsets.zero.
  • Check if your delegate method collectionView(_: , layout:, minimumLineSpacingForSectionAt: ) -> CGFloat returns 0. (It looks like yours returns a positive value here)

KelvinJin avatar Feb 22 '17 03:02 KelvinJin

i copied everything in your iOS example code.

But when i actually do the extension as yours instead of put everything inside of the normal controller the code works fine. @@ i AM not too sure :)). Can you explain to me in your own idea?

Btw,

let layout = AnimatedCollectionViewLayout()
layout.animator = animator?.0
layout.scrollDirection = .horizontal
collectionView!.collectionViewLayout = layout
        if let layout = collectionView?.collectionViewLayout as? AnimatedCollectionViewLayout {
            print("Is there a layout?")
            layout.animator = animator?.0
        }

When i did the code below the code doesn't go insdie the if let closure. And when i do the normal way as you show on the manual i have to put another layout.scrolldirection = .horizontal in order to make it work in horizontal. Besides all of these problems, i make it works already.

Thanks a lot @KelvinJin

heuism avatar Feb 22 '17 03:02 heuism

I got a question about screen rotation, how can i do to keep the animation the same for both rotation? cause at the moment it seems screwed up when i try to rotate it.

Thanks @KelvinJin

heuism avatar Feb 22 '17 03:02 heuism

 if let layout = collectionView?.collectionViewLayout as? AnimatedCollectionViewLayout {
            print("Is there a layout?")
            layout.animator = animator?.0
        }

This won't work in your case. It works in my case because I set it up in Storyboard (sorry for that, I didn't mention how you can do that in the README). You need to do the normal way. Yeah, vertical is not supported yet, only horizontal. I'm currently working on it. So stay tuned!

I haven't tested on screen rotation yet. I can see there might be issues. I'll investigating a bit more later on once i finish vertical support.

KelvinJin avatar Feb 22 '17 03:02 KelvinJin

Thanks @KelvinJin, yeah i have been trying to test around, play around with that to see the screen rotation effect.

But yeah, i will keep updating to see if this thing can be successful

heuism avatar Feb 22 '17 04:02 heuism

@heuism, I figured out how to fix this issue. I encountered it too when using this library with the RotateInOutAttributesAnimator. I hope this will be helpful for your issue. It totally fixed the issue in my project.

@KelvinJin, i would be happy to add this into the library. Can you point me to where i should include this logic and i'll make a pull request?

So my fix for this situation where the cards don't fill the frame properly after the animation but remain offset from the collectionView frame: Have your UICollectionViewController impliment the UIScrollViewDelegate protocol, then add the delegate method func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>).

This method calculates the current cell based on size of the cell and the content offset of the collection view and then works out how to adjusts the center point so the cell will fit properly into the desired frame, and passes this adjustment to the CollectionView using the targetContentOffset's property, with is basically an inout pointer. Source: http://stackoverflow.com/a/35436300/.

   // snaps cell back into desired position after scrolling
   func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) {
               //Ensure the scrollview is in the collectionView we care about
       if (scrollView == self.myCollectionView) {
           
           // Find cell closest to the frame centre with reference from the targetContentOffset.
           let frameCenter: CGPoint = self.collectionView.center
           var targetOffsetToCenter: CGPoint = CGPoint(x: targetContentOffset.pointee.x + frameCenter.x, y: targetContentOffset.pointee.y + frameCenter.y)
           var indexPath: IndexPath? = self.myCollectionView.indexPathForItem(at: targetOffsetToCenter)
           
           // Check for "edgecase" that the target will land between cells and then find a close neighbor to prevent scrolling to index {0,0}.
           while indexPath == nil {
               targetOffsetToCenter.x += 10
               indexPath = self.myCollectionView.indexPathForItem(at: targetOffsetToCenter)
           }
           if let index = indexPath {
               // Find the centre of the target cell
               if let centerCellPoint: CGPoint = myCollectionView.layoutAttributesForItem(at: index)?.center {
                   
                   // Calculate the desired scrollview offset with reference to desired target cell centre.
                   let desiredOffset: CGPoint = CGPoint(x: centerCellPoint.x - frameCenter.x, y: centerCellPoint.y - frameCenter.y)
                   targetContentOffset.pointee = desiredOffset
               }
           }
       }
   }

For reference, i'm using this library with the RotateInOutAnimator in a horizontally paging UICollectionView. My setup of the animator in viewDidLoad:

        let layout = AnimatedCollectionViewLayout()
        layout.animator = RotateInOutAttributesAnimator(minAlpha: 0.6, maxRotate: 0.1)
        layout.scrollDirection = .horizontal
        
        layout.itemSize = CGSize(width: myCollectionView.bounds.size.width, height: myCollectionView.bounds.size.height)
        layout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
        layout.minimumInteritemSpacing = 0
        layout.minimumLineSpacing = 0
        myCollectionView?.collectionViewLayout = layout

And I also added these CustomFlowLayout methods in my CollectionViewController, but these alone did not address the issue:

    // MARK: Collection View CustomFlowLayout setup / size / layout specifics
    func collectionView(_ collectionView: UICollectionView,
                        layout collectionViewLayout: UICollectionViewLayout,
                        sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize {
        return CGSize(width: myCollectionView.bounds.size.width, height: myCollectionView.bounds.size.height )
    }
    
    // for custom flow animation
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
        return .zero
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
        return 0
    }
    
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
        return 0
    }

nataliachodelski avatar Mar 24 '17 21:03 nataliachodelski

@nchodelski Hey, thanks for sharing those. Ideally, the pagingEnabled property of UICollectionView will take care of the "Snap" behaviour, which can be seen in the sample app. I wonder if you have a minimum sample project that can show the issue you're having?

KelvinJin avatar Mar 26 '17 09:03 KelvinJin

@nchodelski, thanks for this suggestion, i haven't got a chance to test that but thanks for your help. I will reply again when i got a chance to test that 👍.

heuism avatar Apr 04 '17 00:04 heuism

Hi, does the collectionView size have to be full screen ? what if i want to pin my collectionView only at the 1/3 top of the view ? thanks

athemer avatar Aug 22 '17 14:08 athemer