Reputation: 1161
I am presenting a viewcontroller with a custom presentationStyle. The parent Controller is a UICollectionViewController. In my didSelectAtIndexPath method of the UICollectionViewController I am taking the UIImageView of the selected cell and animating it to the location of a UIView's frame within the viewcontroller that is modally presented.
How can I get the UIView's frame of the modally presented viewcontroller?
self.imageView!.frame = trophyOverlayVC.trophyImageLocationView!.frame
does not work.
It appears off the screen in most cases.
import UIKit
class CollectionHolderViewController: MainPageContentViewController, UICollectionViewDelegate, UICollectionViewDataSource {
[..insert other methods here..]
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("collectionCell", forIndexPath: indexPath) as TrophyCollectionViewCell
self.collectionViewController.collectionView!.scrollEnabled = false // disable scrolling so view won't move
self.collectionViewController.collectionView!.userInteractionEnabled = false
let innerOffset = collectionView.contentOffset as CGPoint // offset of content view due to scrolling
let attributes = self.collectionViewController.collectionView!.layoutAttributesForItemAtIndexPath(indexPath) as UICollectionViewLayoutAttributes!
let cellRect = attributes.frame // frame of cell in contentView
imageView = UIImageView(frame: CGRectMake(cellRect.origin.x, cellRect.origin.y, cellRect.size.width, cellRect.size.height)) //places image in location of collectionViewCell.
imageView!.image = UIImage(named: placeHolderArray[indexPath.row]) //change.
imageView!.contentMode = UIViewContentMode.ScaleAspectFit
self.collectionViewController.collectionView!.addSubview(imageView!)
self.placeHolderArray[indexPath.row] = ""
UIView.setAnimationsEnabled(false)
self.collectionViewController.collectionView!.reloadItemsAtIndexPaths([indexPath])
UIView.setAnimationsEnabled(true)
var trophyOverlayVC = self.collectionViewController.storyboard!.instantiateViewControllerWithIdentifier("TrophyOverlayVC") as TrophyOverlayViewController
trophyOverlayVC.modalPresentationStyle = UIModalPresentationStyle.Custom
self.presentViewController(trophyOverlayVC, animated: false, completion: self.presentViewController(trophyOverlayVC, animated: false, completion: { (value: Void) in UIView.animateWithDuration(0.5, animations: {
self.imageView!.frame = trophyOverlayVC.trophyImageLocationView!.frame
}, completion: {
(value: Bool) in
}) })
}
Upvotes: 0
Views: 176
Reputation: 66234
Instead of trying to animate it immediately, do this inside the presentViewController
completion block (where you're currently passing nil
). At this point, all of the frame
s will be set properly.
Also, this approach will only work if their superviews are placed identically in the coordinate system. Remember that a frame's origin
(and a view's center
) are coordinates in relation to their superview. If they're not the same, you'll need to use UIView
's convertRect(_:toView:)
or convertRect(_:fromView:)
to convert the rect to the appropriate view's coordinate system.
Upvotes: 1