浏览大图的一种实现方式

利用转场动画实现(这里不说转场动画),主要就是几个坐标的转换:将cell上的imageView快照生成一个snapView(直接创建一个ImageVIew也一样), 在将cell上image的frame 坐标转换到containerView上,在将snapView放大到目标尺寸 (首先你要知道转场动画时怎么一回事)。

 

下面是主要代码,一个自定义类继承自NSObject。实现了UINavigationControllerDelegate、UIViewControllerAnimatedTransitioning协议

- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
    
    // 获取当前的控制器
    UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
    
    // 获取将要转向的控制器
    UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
    
    // 获取容器视图
    UIView *containerView = [transitionContext containerView];
    
    UICollectionView *collectionView ;
    UIImageView *contentImageView;
    if (self.opration == PushAnimationOprationPush) {
        
        ViewController *from =  (ViewController *)fromVC;
        collectionView = from.collectionView;
        
        contentImageView = [toVC valueForKey:@"_contentImageView"];
    }else {
        
        ViewController *to =  (ViewController *)toVC;
        collectionView = to.collectionView;
        contentImageView = [fromVC valueForKey:@"_contentImageView"];
    }
    
    // 获取选中的cell 的indexpath
    NSArray *selectedItems = [collectionView indexPathsForSelectedItems];
    
    // 根据indexpath 获取 cell
    CusCollectionViewCell *cell = (CusCollectionViewCell *)[collectionView cellForItemAtIndexPath:[selectedItems firstObject]];
    
    UIView *snapView;
    CGRect snapViewFrame;
    CGRect snapViewTargetFrame;
    
    if (self.opration == PushAnimationOprationPush) {
        
        // 截取cell 上contentImage 的快照
        snapView = [cell.contentImage snapshotViewAfterScreenUpdates:NO];
        
        // 根据contentImage在cell上的坐标 转换到 containerView上
        snapViewFrame = [containerView convertRect:cell.contentImage.frame fromView:cell.contentImage.superview];
        
        // 获取目标控制器上要显示的 imageView,并根据该imageView的尺寸位置,转换到 容器视图上,成为snapView 最终尺寸。
        snapViewTargetFrame = [containerView convertRect:contentImageView.frame fromView:contentImageView.superview];

    }else {
        
        snapView = [contentImageView snapshotViewAfterScreenUpdates:NO];
        
        snapViewFrame = [containerView convertRect:contentImageView.frame fromView:contentImageView.superview];
        
        snapViewTargetFrame = [containerView convertRect:cell.contentImage.frame fromView:cell.contentImage];
        
    }
    
    snapView.frame = snapViewFrame;
    toVC.view.alpha = 0;
    
    [containerView addSubview:toVC.view];
    [containerView addSubview:snapView];
    
    contentImageView.hidden = YES;
    cell.contentImage.hidden = YES;
    
    
    [UIView animateWithDuration:[self transitionDuration:transitionContext] delay:0 usingSpringWithDamping:0.6f initialSpringVelocity:1.0f options:UIViewAnimationOptionCurveEaseInOut animations:^{
        snapView.frame = snapViewTargetFrame;
        toVC.view.alpha = 1.0;
    } completion:^(BOOL finished) {
        
        contentImageView.hidden = NO;
        cell.contentImage.hidden = NO;
        [snapView removeFromSuperview];
        [transitionContext completeTransition:![transitionContext transitionWasCancelled]];
    }];
    
}
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC {
    
    if (operation == UINavigationControllerOperationPush) {
        
        self.opration = PushAnimationOprationPush;
        
    }else if (operation == UINavigationControllerOperationPop) {
        
        self.opration = PushAnimationOprationPop;
    }
    return self;
}

- (void)start {
    self.nav.delegate = self;
}

/** 为目标控制器添加一个tap手势,返回上一个控制器 */
- (void)tapGestureToPopWithController:(UIViewController *)targetVC {
    
    self.targetViewController = targetVC;
    UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapGesture:)];
    [targetVC.view addGestureRecognizer:tapGesture];
}

- (void)tapGesture:(UITapGestureRecognizer *)gesture {
    
    [self.targetViewController.navigationController popViewControllerAnimated:YES];
}
原文地址:https://www.cnblogs.com/CyanStone/p/5153564.html