zoukankan      html  css  js  c++  java
  • Swift

    1,效果图

    (1)图片从左至右横向排列(只有一行),通过手指拖动可以前后浏览图片。
    (2)视图滚动时,每张图片根据其与屏幕中心距离的不同,显示尺寸也会相应地变化。越靠近屏幕中心尺寸就越大,远离屏幕中心的就逐渐变小。
    (3)滑动结束后,会有位置自动修正的功能。即将当前最靠近屏幕中点的图片移动到正中央。
    (4)点击图片则将该图片删除,点击空白处会在最开始的位置插入一张图片。不管新增还是删除都有动画效果。
    (5)点击导航栏上的“切换”按钮,可以在普通的流式布局和我们自定义的画廊布局间相互切换。切换时也是有动画效果的。
       原文:Swift - 使用CollectionView实现图片Gallery画廊效果(左右滑动浏览图片)    原文:Swift - 使用CollectionView实现图片Gallery画廊效果(左右滑动浏览图片)    原文:Swift - 使用CollectionView实现图片Gallery画廊效果(左右滑动浏览图片)

    2,画廊布局类:LinearCollectionViewLayout

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    import UIKit
     
    class LinearCollectionViewLayout: UICollectionViewFlowLayout {
         
        //元素宽度
        var itemWidth:CGFloat = 100
        //元素高度
        var itemHeight:CGFloat = 100
         
        //对一些布局的准备操作放在这里
        override func prepare() {
            super.prepare()
            //设置元素大小
            self.itemSize = CGSize( itemWidth, height: itemHeight)
            //设置滚动方向
            self.scrollDirection = .horizontal
            //设置间距
            self.minimumLineSpacing = self.collectionView!.bounds.width / 2 -  itemWidth
             
            //设置内边距
            //左右边距为了让第一张图片与最后一张图片出现在最中央
            //上下边距为了让图片横行排列,且只有一行
            let left = (self.collectionView!.bounds.width - itemWidth) / 2
            let top = (self.collectionView!.bounds.height - itemHeight) / 2
            self.sectionInset = UIEdgeInsetsMake(top, left, top, left)
        }
         
        //边界发生变化时是否重新布局(视图滚动的时候也会触发)
        //会重新调用prepareLayout和调用
        //layoutAttributesForElementsInRect方法获得部分cell的布局属性
        override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
            return true
        }
         
        //rect范围下所有单元格位置属性
        override func layoutAttributesForElements(in rect: CGRect)
            -> [UICollectionViewLayoutAttributes]? {
            //从父类得到默认的所有元素属性
            let array = super.layoutAttributesForElements(in: rect)
             
            //可见区域(目前显示出来的位于collection view上的矩形区域)
            let visiableRect = CGRect(x: self.collectionView!.contentOffset.x,
                                      y: self.collectionView!.contentOffset.y,
                                       self.collectionView!.frame.width,
                                      height: self.collectionView!.frame.height)
             
            //当前屏幕中点,相对于collect view上的x坐标
            let centerX = self.collectionView!.contentOffset.x
                + self.collectionView!.bounds.width / 2
             
            //这个是为了计算缩放比例的
            let maxDeviation = self.collectionView!.bounds.width / 2 + itemWidth / 2
             
            for attributes in array! {
                //与可见区域做碰撞,如果该单元格没显示则直接跳过
                if !visiableRect.intersects(attributes.frame) {continue}
                //显示的单元根据偏移量决定放大倍数(最大放大1.8倍,而离屏幕中央越远的单元格缩放的越小)
                let scale = 1 + (0.8 - abs(centerX - attributes.center.x) / maxDeviation)
                attributes.transform = CGAffineTransform(scaleX: scale, y: scale)
            }
             
            return array
        }
         
        /**
         用来设置collectionView停止滚动那一刻的位置(实现目的是当停止滑动,时刻有一张图片是位于屏幕最中央的)
         proposedContentOffset: 原本collectionView停止滚动那一刻的位置
         velocity:滚动速度
         返回:最终停留的位置
         */
        override func targetContentOffset(forProposedContentOffset
            proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
            //停止滚动时的可见区域
            let lastRect = CGRect(x: proposedContentOffset.x, y: proposedContentOffset.y,
                                   self.collectionView!.bounds.width,
                                  height: self.collectionView!.bounds.height)
            //当前屏幕中点,相对于collect view上的x坐标
            let centerX = proposedContentOffset.x + self.collectionView!.bounds.width * 0.5;
            //这个可见区域内所有的单元格属性
            let array = self.layoutAttributesForElements(in: lastRect)
             
            //需要移动的距离
            var adjustOffsetX = CGFloat(MAXFLOAT);
            for attri in array! {
                //每个单元格里中点的偏移量
                let deviation = attri.center.x - centerX
                //保存偏移最小的那个
                if abs(deviation) < abs(adjustOffsetX) {
                    adjustOffsetX = deviation
                }
            }
            //通过偏移量返回最终停留的位置
            return CGPoint(x: proposedContentOffset.x + adjustOffsetX, y: proposedContentOffset.y)
        }
    }

    3,使用样例

    (1)自定义单元格类:MyCollectionViewCell.swift(创建的时候生成对应的 xib 文件)
    原文:Swift - 使用CollectionView实现图片Gallery画廊效果(左右滑动浏览图片)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    import UIKit
     
    //自定义的Collection View单元格
    class MyCollectionViewCell: UICollectionViewCell {
     
        //用于显示图片
        @IBOutlet weak var imageView: UIImageView!
         
        override func awakeFromNib() {
            super.awakeFromNib()
        }
    }

    (2)主视图代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    import UIKit
     
    class ViewController: UIViewController {
        //普通的flow流式布局
        var flowLayout:UICollectionViewFlowLayout!
        //自定义的线性布局
        var linearLayput:LinearCollectionViewLayout!
         
        var collectionView:UICollectionView!
         
        //重用的单元格的Identifier
        let CellIdentifier = "myCell"
         
        //所有书籍数据
        var images = ["c#.png", "html.png", "java.png", "js.png", "php.png",
                      "react.png", "ruby.png", "swift.png", "xcode.png"]
         
        override func viewDidLoad() {
            super.viewDidLoad()
             
            //初始化Collection View
            initCollectionView()
             
            //注册tap点击事件
            let tapRecognizer = UITapGestureRecognizer(target: self,
                                        action: #selector(ViewController.handleTap(_:)))
            collectionView.addGestureRecognizer(tapRecognizer)
        }
         
        private func initCollectionView() {
            //初始化flow布局
            flowLayout = UICollectionViewFlowLayout()
            flowLayout.itemSize = CGSize( 60, height: 60)
            flowLayout.sectionInset = UIEdgeInsets(top: 74, left: 0, bottom: 0, right: 0)
             
            //初始化自定义布局
            linearLayput = LinearCollectionViewLayout()
             
            //初始化Collection View
            collectionView = UICollectionView(frame: view.bounds,
                                              collectionViewLayout: linearLayput)
             
            //Collection View代理设置
            collectionView.delegate = self
            collectionView.dataSource = self
            collectionView.backgroundColor = .white
             
            //注册重用的单元格
            let cellXIB = UINib.init(nibName: "MyCollectionViewCell", bundle: Bundle.main)
            collectionView.register(cellXIB, forCellWithReuseIdentifier: CellIdentifier)
             
            //将Collection View添加到主视图中
            view.addSubview(collectionView)
        }
         
        //点击手势响应
        func handleTap(_ sender:UITapGestureRecognizer){
            if sender.state == UIGestureRecognizerState.ended{
                let tapPoint = sender.location(in: self.collectionView)
                //点击的是单元格元素
                if let  indexPath = self.collectionView.indexPathForItem(at: tapPoint) {
                    //通过performBatchUpdates对collectionView中的元素进行批量的插入,删除,移动等操作
                    //同时该方法触发collectionView所对应的layout的对应的动画。
                    self.collectionView.performBatchUpdates({ () -> Void in
                        self.collectionView.deleteItems(at: [indexPath])
                        self.images.remove(at: indexPath.row)
                    }, completion: nil)
                     
                }
                //点击的是空白位置
                else{
                    //新元素插入的位置(开头)
                    let index = 0
                    images.insert("xcode.png", at: index)
                    self.collectionView.insertItems(at: [IndexPath(item: index, section: 0)])
                }
            }
        }
         
        //切换布局样式
        @IBAction func changeLayout(_ sender: Any) {
            self.collectionView.collectionViewLayout.invalidateLayout()
            //交替切换新布局
            let newLayout = collectionView.collectionViewLayout
                .isKind(of: LinearCollectionViewLayout.self) ? flowLayout : linearLayput
            collectionView.setCollectionViewLayout(newLayout!, animated: true)
        }
         
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
        }
    }
     
    //Collection View数据源协议相关方法
    extension ViewController: UICollectionViewDataSource {
        //获取分区数
        func numberOfSections(in collectionView: UICollectionView) -> Int {
            return 1
        }
         
        //获取每个分区里单元格数量
        func collectionView(_ collectionView: UICollectionView,
                            numberOfItemsInSection section: Int) -> Int {
            return images.count
        }
         
        //返回每个单元格视图
        func collectionView(_ collectionView: UICollectionView,
                            cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
            //获取重用的单元格
            let cell = collectionView.dequeueReusableCell(withReuseIdentifier:
                CellIdentifier, for: indexPath) as! MyCollectionViewCell
            //设置内部显示的图片
            cell.imageView.image = UIImage(named: images[indexPath.item])
            return cell
        }
    }
     
    //Collection View样式布局协议相关方法
    extension ViewController: UICollectionViewDelegate {
         
    }
    源码下载:hangge_1602.zip
    原文出自:www.hangge.com  转载请保留原文链接:http://www.hangge.com/blog/cache/detail_1602.html
  • 相关阅读:
    HDU ACM 1392 Surround the Trees-&gt;凸包
    JMeter使用记录1 -- JDBC測试
    Html学习笔记4
    c++使用mysql的api连接相关问题
    [Angularjs]ng-select和ng-options
    mysql之字符串操作
    mysql之日期函数
    [sharepoint]Rest api相关知识(转)
    [工具类]泛型集合转换为DataTable
    C#修改文件或文件夹的权限,为指定用户、用户组添加完全控制权限
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/7233320.html
Copyright © 2011-2022 走看看