美文网首页你可不能输!
图片浏览器(随便做做).

图片浏览器(随便做做).

作者: Little_Dragon | 来源:发表于2015-10-17 02:06 被阅读583次
    图片浏览器.gif

    动效还是欠缺了很多,希望各位能够指正. 个人并不是非常喜欢用框架. 所以想写一些比较实用的功能做一个展示.

    只是为了实现上面的功能, 所以建立了两个collectionView,
    一个用于展示图片(所有图片),
    一个用于点击后放大图片并进行展示.
    (并且可以实现左右展示,很像以前学过的水平布局展示的collectionView)

    遇到的几个问题
    1.需要处理的是弹出collectionView的数据展示问题, 以及当前展示的哪张图片问题.
    2.监测到手指点击的cell,到底处在屏幕的哪个位置上.
    3.图片放大缩小, 会影响外边蒙版的透明度.

    额外问题, 当我弹出控制器的时候,会牵扯到将原有模型数组中的模型中的图片取出.
    1.当时我想着可以遍历模型数组然后取出. 于是就在建立数组的时候(模型装数组的时候), 将需要传入的图片一起转换过来放入数组中 . 但是我发现会出现 加载程序变慢的情况. (废弃掉)
    2.后来我认为可以开辟一个子线程,然后用于专门加载要显示的图片,但到后面,如果我点击过快的话, 很出现数组越界的情况(数组还没有将数据完全加载).
    3.后来我不去把加载图片的环节放在当前控制器中处理(本来就该如此,谁的事件 就交给谁处理好了). 然后将字符串url传入就可以了.

    代码的相关实现

    1.对于控制器的处理,点击Item需要将1.所有数据 2.当前点击的indexPath传入
    modal的控制器进行接收. 展示数据, 并将显示转到传入的indexPath.
    modal出来的控制器,展示数据,并且把需要显示indexPath转到显示
    当点击item的时候,可以通过设置 modal出来的控制器的数据 和展示的 indexPath来控制 modal出来的控制器的显示

    实现代码

    // 为了确保数据加载完全, 就在viewWillAppear中书写跳转 
    - (void)viewWillAppear:(BOOL)animated
    {
        [super viewWillAppear:animated];
        [self.collectionView scrollToItemAtIndexPath:self.indexPath atScrollPosition:UICollectionViewScrollPositionRight animated:NO];
    }
    

    2.现在就是第二个难点的处理, 上一篇文章我们可以看出,只要给我们位置,我们可以以我们想要的数据方式进行弹出和关闭,
    此时我们需要记录的是, 点击item的尺寸 和 点击item的中心点的位置,这样我们才能更精确的控制modal控制器的弹出.

    在modal新的控制器的时候,我们需要做的事情有
    - (void)clickShopCell:(LXLShopCell *)cell
    {
    // 创建需要modal的控制器
        ModalViewController *modalVC = [[ModalViewController alloc]init];
    // 设置传入的数据
        modalVC.images = self.images;
    // 设置modal的控制器的代理
        modalVC.delegate = self;
    // 自定义转场, 设置modal控制器的转场代理, 利用代理去控制,转场动画
        modalVC.transitioningDelegate = self.custom;
    // 将转场的类型改为自定义, 自己才可以进行修改   
     modalVC.modalPresentationStyle = UIModalPresentationCustom;
    // 取得点击cell 的frame 在控制器view上的
        必须书写 superView 否则 就会转换不成功
    #warning  必须写superView
        CGRect frame = [cell.superview convertRect:cell.frame toView:self.view];
    // 获取点击cell的中心点 处在控制器view的什么位置上
        CGPoint center = [cell.superview convertPoint:cell.center toView:self.view];
    // 转场动画需要这两个值的出入
        self.custom.rect = frame;
        
        self.custom.center = center;
       // 后期需要. 当滑动collectionView的时候, 需要转换成不同的中心点.
        modalVC.custom = self.custom;
    // 获取点击cell的indexPath
        modalVC.indexPath =  [self.collectionView indexPathForCell:cell];
        
        [self presentViewController:modalVC animated:YES completion:^{
              }];
    }
    

    转场代理中的代码实现
    只进行转场动画的代码说明
    想法: 1.中心点的迁移
    点击中心点---->屏幕中心点
    2.尺寸的变化
    原cell的尺寸--->全屏幕

    需要倒着思考, 本来应该是屏幕中心 ,现在在cell的中线点上.
    本来是全屏幕, 现在 transform 到cell的尺寸上

    
    - (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext
    {
        UIView *presentView = [[UIView alloc]init];
        // 先进行计算,需要transformScale的大小
        CGFloat scaleX = self.rect.size.width / [UIScreen mainScreen].bounds.size.width;
        CGFloat scaleY = self.rect.size.height / [UIScreen mainScreen].bounds.size.height;
    // 对弹出控制器进行设置动画
    // 弹出前的位置,尺寸
        if (self.isPop) {
            
            presentView = [transitionContext viewForKey:UITransitionContextToViewKey];
    
            [[transitionContext containerView] addSubview:presentView];
            
            CGPoint point = presentView.center;
            
            presentView.center = self.center;
    
           
            presentView.transform = CGAffineTransformMakeScale(scaleX   , scaleY);
         
    // 动画modal过程,还原尺寸和位置
            [UIView animateWithDuration:1.0 animations:^{
                presentView.center = point;
                presentView.transform = CGAffineTransformIdentity;
    
            } completion:^(BOOL finished) {
    // 完成后记得关闭上下文, 否则后面的动画将无法执行
                [transitionContext completeTransition:YES];
            }];
        }else
            {
                presentView = [transitionContext viewForKey:UITransitionContextFromViewKey];
                [[transitionContext containerView] addSubview:presentView];
                [UIView animateWithDuration:1.0 animations:^{
                    presentView.center = self.center;
                    
                    presentView.transform = CGAffineTransformMakeScale(scaleX, scaleY);
                   
                } completion:^(BOOL finished) {
                    [transitionContext completeTransition:YES];
                }];
        
        
        }
        
    }
    

    3.写到这里我想基本功能应该是可以实现了, 但是当我们滑动modal控制器的图片时发现, dismiss的时候位置不是需要回退的cell 的位置, 因为此时点击的cell 和我需要回退的cell 已经不是一个了.
    这里我们遇到了问题,那么怎么解决呢. 很简单. 当我们滚动的时候,通知控制器,当前展示的是第几个item, 然后他将对应cell的中心点,再传给转场代理就可以了

    过程虽然复杂,但是也好做的
    modal控制器中的代码的实现

    // 苹果提供的方法, 方便我们找到离开实现的cell ,当时我还想找到需要的cell ,但是发现开始的移动根本就不可能找到. 但是此方法是针对与 拖动collectionView展示新的cell时调用, 我们确实需要
    - (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath
    {
       // 我利用 可显示的cell 的集合,  反正我设置的页面之内只能显示一个. 取出显示的cell
        UICollectionViewCell *selectCell = collectionView.visibleCells.lastObject;
    // 得到它的indexPath
        NSIndexPath *index = [collectionView indexPathForCell:selectCell];
       
    // 调用代理将 indexPath 传给控制器, 那么控制器就能方便的算出中心点了
        if ([self.delegate respondsToSelector:@selector(modalViewController:displayCellIndexPath:)]) {
            [self.delegate modalViewController:self displayCellIndexPath:index];
        }
    
    }
    

    控制器中的代码
    只写了modal控制器的代理部分代码

    - (void)modalViewController:(ModalViewController *)modalVC displayCellIndexPath:(NSIndexPath *)indexPath
    {
    // 取出cell
        UICollectionViewCell *cell = [self.collectionView cellForItemAtIndexPath:indexPath];
    // 算出中心点
        CGPoint center = [cell.superview convertPoint:cell.center toView:self.view];
    // 给转场代理 设置 值center
        self.custom.center = center;
    }
    

    现在图片展示功能基本实现了, 下一次,我想研究研究 图文混排的的实现...

    相关文章

      网友评论

      • 超_iOS:这个图片都是固定发现?能不能显示不同大小不失真啊?
      • e5aa69a9a319:不愧是五年开发经验的大神,我曾经听过你的事迹,你在百度干了2年,阿里干了2年,现在回小马哥教书了,厉害!
      • Amoly:其实我也没看懂什么,就是觉得觉得很牛逼的样子 :joy: :joy: :joy:
        Little_Dragon:@Enn_今玍 你是?简书不提示名字
        Amoly:@developer___iOS 注册这么长时间第一次留言,我是过来看看你的 :smiley: ,晓龙~
        Little_Dragon:@Enn_今玍 谢谢。简单的转场。你以后工作和学习也会用到的

      本文标题:图片浏览器(随便做做).

      本文链接:https://www.haomeiwen.com/subject/omfacttx.html