浏览大图的一种实现方式

利用转场动画实现(这里不说转场动画),主要就是几个坐标的转换:将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];
}
时间: 2024-08-07 08:36:26

浏览大图的一种实现方式的相关文章

WPF中使用文件浏览对话框的几种方式

原文:WPF中使用文件浏览对话框的几种方式 WPF本身并没有为我们提供文件浏览的控件, 也不能直接使用Forms中的控件,而文件浏览对话框又是我们最常用的控件之一. 下面是我实现的方式 方式1: 使用win32控件OpenFileDialog ? 1 2 3 4 5 6 7 Microsoft.Win32.OpenFileDialog ofd = new Microsoft.Win32.OpenFileDialog(); ofd.DefaultExt = ".xml"; ofd.Fil

Android一个应用多个图标的几种实现方式

本文标签: Android activity-alias 新需求我的应用将有多个ICON入口..最终选择了 activity-alias , 其实实现多图标有好几种方式 1. 多Activity + intent-filter方式 因为launcher会扫描app中含有以下intent-filter属性的标签, 有的话就会将其添加到桌面.所以只要在你想添加到桌面的activity下加上以下标签即可. <intent-filter> <action android:name="a

全面剖析Smarty缓存机制一[三种缓存方式]

今天主要全面总结下Smarty模板引擎中强大的缓存机制,缓存机制有效减少了系统对服务器的压力,而这也是很多开发者喜欢Smarty的原因之一,由于篇幅较大,便于博友阅读,这篇文章将剖析Smarty缓存的几种方式,下篇文章着重讲解下设置缓存及清除缓存的技巧方法(其中包含缓存集合方法). 一.Smarty缓存的几种方式缓存机制中,分为全局缓存.部分缓存.局部缓存三种方式,后面会一一讲述,下面是缓存设置前,Smarty类方法基本目录设置如下:$smarty->Smarty();$smarty->tem

php网站常见的几种攻击方式(转)

针对 PHP 的网站主要存在下面几种攻击方式::1.命令注入(Command Injection)2.eval 注入(Eval Injection)3.客户端脚本攻击(Script Insertion)4.跨网站脚本攻击(Cross Site Scripting, XSS)5.SQL 注入攻击(SQL injection)6.跨网站请求伪造攻击(Cross Site Request Forgeries, CSRF)7.Session 会话劫持(Session Hijacking)8.Sessio

介绍HTML5几种存储方式

总体情况 h5之前,存储主要是用cookies.cookies缺点有在请求头上带着数据,大小是4k之内.主Domain污染. 主要应用:购物车.客户登录 对于IE浏览器有UserData,大小是64k,只有IE浏览器支持. 下面就跟兄弟连(www.lampbrother.net )HTML5课程一起来学习HTML5几种存储方式: 目标 解决4k的大小问题 解决请求头常带存储信息的问题 解决关系型存储的问题 跨浏览器 1.本地存储localstorage 存储方式: 以键值对(Key-Value)

Struts2系列笔记(3)---Action类的3种书写方式

Action类的3种书写方式 本文主要写有关写Action类的3种书写方式: (1)第一种 Action可以是POJO (简单模型对象)  不需要继承任何父类 也不需要实现任何接口 (2)实现Action接口 (3)继承ActionSupport(推荐) 那我们先来书写第一种: (1)第一种 Action可以是POJO (简单模型对象)  不需要继承任何父类 也不需要实现任何接口 1 //这里其实就是一个普通的类,类里面的方法可以任意写,如果写execute()方法那就代表默认执行它 2 pub

[数据库事务与锁]详解八:底理解数据库事务乐观锁的一种实现方式——CAS

注明: 本文转载自http://www.hollischuang.com/archives/1537 在深入理解乐观锁与悲观锁一文中我们介绍过锁.本文在这篇文章的基础上,深入分析一下乐观锁的实现机制,介绍什么是CAS.CAS的应用以及CAS存在的问题等. 线程安全 众所周知,Java是多线程的.但是,Java对多线程的支持其实是一把双刃剑.一旦涉及到多个线程操作共享资源的情况时,处理不好就可能产生线程安全问题.线程安全性可能是非常复杂的,在没有充足的同步的情况下,多个线程中的操作执行顺序是不可预

利用图形窗口分割法将极坐标方程:r=cos(θ/3)+1/9用四种绘图方式画在不同的窗口中

利用图形窗口分割法将极坐标方程:r=cos(θ/3)+1/9用四种绘图方式画在不同的窗口中. 解:MATLAB指令: theta=0:0.1:6*pi;rho=cos(theta/3)+1/9; >> polar(theta,rho) >> >> plot(theta,rho) >> semilogx(theta,rho) >> grid >> hist(rho,15) 结果分别如下图: 图1 图2 图3 图4

linux ssh 的几种验证方式

介绍 本文说的SSH指的是OPENSSH这个开源软件,通过OPENSSH官网可发现,它在服务器上的使用率已经非常高了.运维人员.开发人员每天都在用它,但很多人对他的工作原理和认证方式不是很了解. 正文 SSH的认证方式可以概括有4种. 1 PAM认证 在配置文件/etc/ssh/sshd_config中对应参数: UsePAM 2 公钥私钥认证 在配置文件/etc/ssh/sshd_config中对应参数: RSAAuthentication.PubkeyAuthentication 我们在配置