炫酷的UIcollectionlayout圆形布局

原文// github: https://github.com/jasnig
// 简书: http://www.jianshu.com/p/b84f4dd96d0c

75B039F67A985615F062BAF1BAE9A4A9.jpg
代码

class CircleLayout: UICollectionViewLayout {
    private var layoutAttributes: [UICollectionViewLayoutAttributes] = []
    // 圆心
    var center = CGPoint(x: 0.0, y: 0.0)
    // 圆半径
    var radius: CGFloat = 0.0
    var totalNum = 0
    override func prepare() {
        super.prepare()
        // 初始化需要的数据
        totalNum = collectionView!.numberOfItems(inSection: 0)
        // 每次计算前需要清零
        layoutAttributes = []
        center = CGPoint(x: Double(collectionView!.bounds.width * 0.5), y: Double(collectionView!.bounds.height * 0.5))
        radius = min(collectionView!.bounds.width, collectionView!.bounds.height) / 3.0
        
        var indexPath: IndexPath
        for index in 0..<totalNum {
            indexPath = IndexPath(row: index, section: 0)
            let attributes = layoutAttributesForItem(at: indexPath)!

            layoutAttributes.append(attributes)
        }
        
        
    }
    
    // 因为返回的collectionViewContentSize使得collectionView不能滚动, 所以当旋转的时候才会触发, 故返回为true便于重新计算布局
    override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
        return true
    }
    // Apple建议要重写这个方法, 因为某些情况下(delete insert...)系统可能需要调用这个方法来布局

    override func layoutAttributesForItem(at indexPath: IndexPath) -> UICollectionViewLayoutAttributes? {
        
        let attributes = UICollectionViewLayoutAttributes(forCellWith: indexPath)
        attributes.size = CGSize(width: 60.0, height: 60.0)
        // 当前cell的角度
        // 注意类型转换
        let angle = 2 * CGFloat(M_PI) * CGFloat(indexPath.row) / CGFloat(totalNum)
        // 一点点数学转换
        attributes.center = CGPoint(x: center.x + radius*cos(angle), y: center.y + radius*sin(angle))
        return attributes
    }
    
    
    override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
        return layoutAttributes
    }
    
    override var collectionViewContentSize: CGSize { // change func to var
        return collectionView!.bounds.size
    }
}

简单使用

func setCircleLayout() {
        let layout = CircleLayout()
        collectionView?.collectionViewLayout = layout
    }

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 173,926评论 25 709
  • afinalAfinal是一个android的ioc,orm框架 https://github.com/yangf...
    passiontim阅读 15,601评论 2 45
  • 球球的游戏规则就是大球吃小球,最终的目的就是生存下来。刚开始我很不解,就一直吃那些小点点有什么好玩的,可当我真的试...
    方默默阅读 576评论 6 5
  • 原来看过的文字,再看一遍竟然忍不住眼泪,人从头到脚都麻了,得控制着呼吸才能不抽噎,是这故事动人还是带入感强烈,...
    老翅膀儿阅读 762评论 0 0