正确转换UICollectionViewCell中的子视图

时间:2014-11-18 01:58:02

标签: swift uicollectionview uicollectionviewcell

我正在使用layoutToLayout导航过渡(useLayoutToLayoutNavigationTransitions),但动画不流畅;在转换期间,细胞的子视图奇怪地跳跃:

enter image description here

可能出现什么问题?

我的collectionviewcell类看起来像这样:

private class PageCell : UICollectionViewCell {
    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    var viewController : UIViewController? {
        willSet {
            for view in self.contentView.subviews as [UIView] {
                view.removeFromSuperview()
            }
        }

        didSet {
            if let view = viewController?.view {
                view.frame = self.contentView.bounds
                self.contentView.addSubview(view)
                self.contentView.autoresizingMask = .FlexibleHeight | .FlexibleWidth;
                view.autoresizingMask = .FlexibleHeight | .FlexibleWidth;
            }
        }
    }
}

1 个答案:

答案 0 :(得分:1)

我通过使用TLTransitionLayout转换到其他布局来解决了这个问题。它使动画看起来更适合更复杂的单元格,因为它没有使用Core Animation。

该方法也与useLayoutToLayoutNavigationTransitions兼容,因此您可以获得所有好东西,例如推送到导航栏等的新导航项目。(我仅在iOS8上测试过)。

所以这些是我的步骤:

1。有一个layoutToLayout从一个UICollectionViewController转换到另一个:


DetailViewController *detail = [[DetailViewController alloc] init];
detail.useLayoutToLayoutNavigationTransitions = YES;
[self.navigationController pushViewController:detail animated:YES];

... UICollectionViewController子类中的其他地方......

- (UICollectionViewTransitionLayout *)collectionView:(UICollectionView *)collectionView transitionLayoutForOldLayout:(UICollectionViewLayout *)fromLayout newLayout:(UICollectionViewLayout *)toLayout
{
    NSArray *supplementaryKinds = @[]; // optional supplementary view kinds
    TLTransitionLayout *layout = [[TLTransitionLayout alloc] initWithCurrentLayout:fromLayout nextLayout:toLayout supplementaryKinds:supplementaryKinds];
    return layout;
}

2。在某处实现此方法的UINavigationControllerDelegate


- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
                                  animationControllerForOperation:(UINavigationControllerOperation)operation
                                               fromViewController:(UIViewController*)fromVC
                                                 toViewController:(UIViewController*)toVC
{
    if (operation == UINavigationControllerOperationPush) {
        return [[PushLayoutToLayoutAnimator alloc] init];
    }

    if (operation == UINavigationControllerOperationPop) {
        return [[PopLayoutToLayoutAnimator alloc] init];
    }

    return nil;
}

3。实现动画师:


#import "TTProfileDetailPushAnimator.h"
#import <TLTransitionLayout.h>

@implementation TTProfileDetailPushAnimator

- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
    return 0.5;
}

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    UICollectionViewController *toViewController;
    toViewController = (UICollectionViewController *)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    NSAssert([toViewController isKindOfClass:[UICollectionViewController class]], @"must be collection view controller");
    NSAssert(toViewController.useLayoutToLayoutNavigationTransitions, @"expecting layoutToLayout transition!");

    [[transitionContext containerView] addSubview:toViewController.view];

    UICollectionViewLayout *toLayout = toViewController.collectionViewLayout;
    UICollectionView *toCollectionView = toViewController.collectionView;
    NSTimeInterval duration = [self transitionDuration:transitionContext];

    UICollectionViewLayoutInteractiveTransitionCompletion completionBlock = ^(BOOL completed, BOOL finished) {
        [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
    };

    TLTransitionLayout *layout;
    layout = (TLTransitionLayout *)[toCollectionView transitionToCollectionViewLayout:toLayout
                                                                             duration:duration
                                                                               easing:CubicEaseInOut
                                                                           completion:completionBlock];

    CGPoint toOffset = [toCollectionView toContentOffsetForLayout:layout
                                                       indexPaths:[toCollectionView indexPathsForSelectedItems]
                                                        placement:TLTransitionLayoutIndexPathPlacementCenter];

    layout.toContentOffset = toOffset;
}


@end

#import "TTProfileDetailPopAnimator.h"
#import <TLTransitionLayout.h>

@implementation TTProfileDetailPopAnimator

- (NSTimeInterval)transitionDuration:(id <UIViewControllerContextTransitioning>)transitionContext
{
    return 0.5;
}

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
{
    UICollectionViewController* toViewController;
    toViewController = (UICollectionViewController *)[transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    UICollectionViewController* fromViewController;
    fromViewController = (UICollectionViewController *)[transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];

    NSAssert([toViewController isKindOfClass:[UICollectionViewController class]], @"toVC must be collection view controller");
    NSAssert([fromViewController isKindOfClass:[UICollectionViewController class]], @"fromVC must be collection view controller");
    NSAssert(fromViewController.useLayoutToLayoutNavigationTransitions, @"expecting layoutToLayout transition!");

    [[transitionContext containerView] insertSubview:toViewController.view aboveSubview:fromViewController.view];

    UICollectionViewLayout *toLayout = toViewController.collectionViewLayout;
    UICollectionView *toCollectionView = toViewController.collectionView;
    NSTimeInterval duration = [self transitionDuration:transitionContext];

    UICollectionViewLayoutInteractiveTransitionCompletion completionBlock = ^(BOOL completed, BOOL finished) {
        [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
    };

    TLTransitionLayout *layout;
    layout = (TLTransitionLayout *)[toCollectionView transitionToCollectionViewLayout:toLayout
                                                                             duration:duration
                                                                               easing:CubicEaseInOut
                                                                           completion:completionBlock];

    CGPoint toOffset = [toCollectionView toContentOffsetForLayout:layout
                                                       indexPaths:[toCollectionView indexPathsForVisibleItems]
                                                        placement:TLTransitionLayoutIndexPathPlacementCenter];
    layout.toContentOffset = toOffset;
}

@end