UIKit - UICollectionView

UICollectionView功能和UITableView很相似,都是页面布局控件,但是UITableView更多的处理行列布局,而UICollectionView更多的是以流布局的方式展现数据,功能相较UITableView强大很多。

1.基础介绍

    UICollectionViewLayout:自定义布局集合类。

   UICollectionViewFlowLayout:视图布局对象,继承自UICollectionViewLayout(流视图:一行排满,自动排到下行),通常自定义布局,继承该类就可以了。

 需要实现的协议:UICollectionViewDataSource(数据源)、UICollectionViewDelegate(代理)、UICollectionViewDelegateFlowLayout(视图布局)

2.创建

//设置布局Item
let flowLayout = UICollectionViewFlowLayout()

//以下对flowLayout的设置可以不用(或者也可以通过UICollectionViewDelegateFlowLayout的代理方法来动态实现)
//设置Item的Size
    flowLayout.itemSize = CGSize(width: 90, height: 60)
//设置Item的排列方式        
    flowLayout.scrollDirection = UICollectionViewScrollDirection.vertical
//设置 Item 的四周边距        
    flowLayout.sectionInset = UIEdgeInsetsMake(10, 10, 10, 10)
//设置同一列中上下相邻的两个 Item 之间的间距
    flowLayout.minimumLineSpacing = 10
//设置同一行中相邻的两个 Item 之间的间距        
    flowLayout.minimumInteritemSpacing = 10
//设置UICollectionView 的页头尺寸        
    flowLayout.headerReferenceSize = CGSize(width: 100, height: 50)
//设置 UICollectionView 的页尾尺寸        
    flowLayout.footerReferenceSize = CGSize(width: 100, height: 50)
        
        
//创建CollectionView
    collectView = UICollectionView(frame: CGRect(x:0, y:0, width:self.view.bounds.width, height: self.view.bounds.height), collectionViewLayout: flowLayout)
 
//注册cell
    collectView!.register(UICollectionViewCell.self, forCellWithReuseIdentifier:"cell")

//设置代理
     collectView?.delegate = self
     collectView?.dataSource = self

//添加视图   
     self.view.addSubview(collectView!)
//完成基本代理方法

//设置区块数
func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 1
}
    
//设置Cell样式
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    //初始化Cell
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) 
        
    //设置Cell内部自定义元素
    let titleLabel = UILabel(frame: CGRect(x: 20, y: 10, width: 100, height: 30))
        titleLabel.textColor = UIColor.red
        titleLabel.text = "ItemData"
        cell.contentView.addSubview(titleLabel)
        
    //设置cell整体样式
        cell.backgroundColor = UIColor.white
        cell.layer.masksToBounds = true
        cell.layer.cornerRadius = 2
        cell.layer.borderWidth = 1
        cell.layer.borderColor = UIColor.green.cgColor
    return cell
}

//设置每个Item个数
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return 10
}

3.基本设置

//对颜色设置
collectionView?.backgroundColor = UIColor.darkGray

// Collection 是否允许预加载 
collectionView?.isPrefetchingEnabled = true

// 设置item是否能够被选中
 collectionView?.allowsSelection = true

// 设置item 能够多选
collectionView?.allowsMultipleSelection = true

//滑动到指定Section的Item 的位置
collectionView?.scrollToItem(at: IndexPath.init(row: 2, section: 1), at: .top, animated: true)

//选择指定的Item。并将选中的Item滑动到指定的位置
collectionView?.selectItem(at: IndexPath.init(row: 2, section: 1), animated: true, scrollPosition: .top)

//取消选中的item
collectionView.deselectItem(at: IndexPath.init(row: 2, section: 1), animated: true)

// UICollectionView 的整体更新数据的方法 
collectionView?.reloadData()

4.布局相关操作

// 设置新的布局,从一个布局到另一个布局的转变 
collectionView?.setCollectionViewLayout(self.ctreateFlowLayout(), animated: true)
collectionView?.setCollectionViewLayout(self.ctreateFlowLayout(), animated: true) { (isFinsish) in
    NSLog("布局完成后操作") 
}

// 准备好动画,调用该方法开始动画对collectionView进行布局,成功后就会回调 setCollectionViewLayout:animated :{} 
collectionView?.finishInteractiveTransition()
    
 //取消对collectionView布局的动画,并回调 setCollectionViewLayout:animated :{}  
collectionView?.cancelInteractiveTransition()

5.获取属性信息

// 获取Section的数量
let sectionCount = collectionView?.numberOfSections

// 获取指定Section中Item数量
let itemCount = collectionView?.numberOfItems(inSection: 1)
        
// 获取指定Item属性
let ItemLayoutAttributes = collectionView?.layoutAttributesForItem(at: IndexPath.init(row: 1, section: 1))
// UICollectionViewLayoutAttributes 属性我们可以获取一些关于itme的属性,例如:大小、透明度、是否隐藏、IndexPath ...       ItemLayoutAttributes?.frame,ItemLayoutAttributes?.size,ItemLayoutAttributes?.indexPath,ItemLayoutAttributes?.alpha
        
// 获取ReusableView的一些属性
let ReusableViewLayoutAttributes = collectionView.layoutAttributesForSupplementaryElement(ofKind: UICollectionElementKindSectionHeader, at: IndexPath.init(item: 0, section: 2))
// UICollectionViewLayoutAttributes 属性我们可以获取一些关于ReusableView的属性,例如:大小、透明度、是否隐藏、IndexPath ... 等ReusableViewLayoutAttributes?.frame,ReusableViewLayoutAttributes?.size,ReusableViewLayoutAttributes?.indexPath,ReusableViewLayoutAttributes?.alpha
    
// 通过Item上某一点获取改Item的indexPath
let pointIndexPath = collectionView.indexPathForItem(at: CGPoint.init(x: 100, y: 200))
    pointIndexPath?.section     //区域
    pointIndexPath?.row         //行号
    
// 通过UICollectionViewCell来获取indexPath
let cellIndexPath = collectionView.indexPath(for: UICollectionViewCell.init())
    cellIndexPath?.section
    cellIndexPath?.row
    

// 通过indexPath 来获取 cell 
let cellData = collectionView.cellForItem(at: IndexPath.init(row: 1, section: 1))
    
// 获取 UICollectionView 视图可见的 Cell 
let vibCells = collectionView.visibleCells
    
// 获取视图上可见的Item的indexPath
let itemIndexPaths = collectionView.indexPathsForVisibleItems
    
// 通过指定的indexPath还获取 UICollectionView的 headerView & fotterView
let HTView = collectionView.supplementaryView(forElementKind: UICollectionElementKindSectionHeader, at: IndexPath.init(row: 0, section: 2))
    
// 通过给定的类型(UICollectionElementKindSectionHeader、UICollectionElementKindSectionFooter)来获取视图可见的 headerView & footerView 
let HTView = collectionView.visibleSupplementaryViews(ofKind: UICollectionElementKindSectionHeader)
    
// 通过给定的类型 (UICollectionElementKindSectionHeader、UICollectionElementKindSectionFooter)来获取视图可见的 indexPath 
let indexPaths = collectionView.indexPathsForVisibleSupplementaryElements(ofKind: UICollectionElementKindSectionHeader)
    

6.添加、删除、刷新、移动

//Section 的增加、删除、刷新、移动 
let setIndexs = NSIndexSet.init(indexesIn: NSRange.init(location: 0, length: 2))
   
//插入section
collectionView?.insertSections(setIndexs as IndexSet)
        
//删除Section
collectionView?.deleteSections(setIndexs as IndexSet)
    
//Section数据刷新
collectionView?.reloadSections(setIndexs as IndexSet)
    
//移动Section到另一个新的位置
collectionView?.moveSection(0, toSection: 2)
    
//Item 的增加、删除、刷新、移动 
//插入Item
collectionView?.insertItems(at: [IndexPath.init(row: 1, section: 1)])
    
//删除Item
collectionView?.deselectItem(at: IndexPath.init(row: 0, section: 1), animated: true)
    
//Item刷新
collectionView?.reloadItems(at: [IndexPath.init(row: 0, section: 1)])
    
//Item移动操作
collectionView?.moveItem(at: IndexPath.init(row: 0, section: 1), to: IndexPath.init(row: 0, section: 2))
    
//Section或者Item的增加、删除、刷新、移动调用的函数
collectionView?.performBatchUpdates({}) {
   (isFinsh) in
       NSLog("操作完成后调用")
}
        
// 是否在移动的时候,对Item进行排序,返回一个BOOl值,默认情况是 true
collectionView?.beginInteractiveMovementForItem(at: IndexPath.init(row: 0, section: 1))
    
// 更新Item移动时的位置
collectionView?.updateInteractiveMovementTargetPosition(CGPoint.init(x: 100, y: 30))
    
// 移动Item到新的位置
collectionView?.endInteractiveMovement()
    
// 将item恢复到原始的位置
collectionView?.cancelInteractiveMovement()

7.UICollectionViewDelegate代理方法

//设置Item点击后是否变为高亮状态。true:高亮状态;false:非高亮状态
func collectionView(_ collectionView: UICollectionView, shouldHighlightItemAt indexPath: IndexPath) -> Bool {
     return true
}
    
//Item被点击成为高亮状态后调用该函数
func collectionView(_ collectionView: UICollectionView, didHighlightItemAt indexPath: IndexPath) {
     NSLog("高亮" + "\(indexPath.section)" + "--" + "\(indexPath.row)")
}
    
//Item高亮状态变为非高亮状态时调用的函数
func collectionView(_ collectionView: UICollectionView, didUnhighlightItemAt indexPath: IndexPath) {
     NSLog("不高亮" + "\(indexPath.section)" + "--" + "\(indexPath.row)")
}
    
//是否允许取消选中
func collectionView(_ collectionView: UICollectionView, shouldDeselectItemAt indexPath: IndexPath) -> Bool {
    return true
}
    
//Item被点击选中触发该方法
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
     NSLog("选中Item:\(indexPath.section)--\(indexPath.row)")
     collectionView.cellForItem(at: indexPath)?.layer.backgroundColor = UIColor.red.cgColor
}
    
//取消Item选中时调用的函数
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
     NSLog("取消Item:\(indexPath.section)--\(indexPath.row)")
     collectionView.cellForItem(at: indexPath)?.layer.backgroundColor = UIColor.purple.cgColor
}
    
//Item将要显示在视图上的时候调用该函数
func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
     NSLog("将要显示的Item" + "\(indexPath.section)" + "\(indexPath.row)")
}
    
//Item显示结束,指的是Cell滑动移出视图时调用该函数
func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath){
     NSLog("Item显示结束" + "\(indexPath.section)" + "\(indexPath.row)")
}
    
//headerView 和 footerView 将要出视图的时调用
func collectionView(_ collectionView: UICollectionView, willDisplaySupplementaryView view: UICollectionReusableView, forElementKind elementKind: String, at indexPath: IndexPath) {
     NSLog("headerView 和 footerView 将要出现在当前视图")
}
    
//headerView 和 footerView 滑动移出视图的时调用
func collectionView(_ collectionView: UICollectionView, didEndDisplayingSupplementaryView view: UICollectionReusableView, forElementOfKind elementKind: String, at indexPath: IndexPath) {
     NSLog("headerView 和 footerView 被移出当前视图")
}
    
//是否允许Item是否显示菜单(Cut/Copy/Paste)
func collectionView(_ collectionView: UICollectionView, shouldShowMenuForItemAt indexPath: IndexPath) -> Bool {
    return true
}
    
//设置菜单内显示那些按钮
func collectionView(_ collectionView: UICollectionView, canPerformAction action: Selector, forItemAt indexPath: IndexPath, withSender sender: Any?) -> Bool {
    // 控制菜单内的按钮显示
    if action == #selector(UIResponderStandardEditActions.cut(_:)){
       return false
    }
    return true
}
    
//点击菜单内的按钮触发的函数 
func collectionView(_ collectionView: UICollectionView, performAction action: Selector, forItemAt indexPath: IndexPath, withSender sender: Any?){
    NSLog("菜单内的按钮被点击")
}
    
//Item 是否可以选择。true:可以选择;false:不可以选择 
func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
     return true
}
    
//重新布局调用该方法
func collectionView(_ collectionView: UICollectionView, transitionLayoutForOldLayout fromLayout: UICollectionViewLayout, newLayout toLayout: UICollectionViewLayout) -> UICollectionViewTransitionLayout {
    let TransitionLayout = UICollectionViewTransitionLayout.init(currentLayout: self.ctreateFlowLayout(), nextLayout: self.ctreateFlowLayout())
    return TransitionLayout
}

8.UICollectionViewDataSource代理方法

//设置Section数量
func numberOfSections(in collectionView: UICollectionView) -> Int {
    return 2
}
    
//设置每个Section中的Item数量
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
     return 20
}
    
//设置Cell的布局样式
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) 
        
        
    let titleLabel = UILabel(frame: CGRect(x: 20, y: 10, width: 100, height: 30))
        titleLabel.textColor = UIColor.white
        titleLabel.text = dataArr[indexPath.row]
        cell.contentView.addSubview(titleLabel)
        
        
    //设置cell样式
       cell.backgroundColor = UIColor.purple
       cell.layer.masksToBounds = true
       cell.layer.cornerRadius = 2
       cell.layer.borderWidth = 1
       cell.layer.borderColor = UIColor.green.cgColor
    return cell
}
    
//设置 UICollectionView的headerView和footerView布局样式
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        
        // 判断是headerView & footerView 
        let label = UILabel(frame: CGRect(x: 20, y: 0, width: 200, height: 50))
            label.textColor = UIColor.white
        if kind == UICollectionElementKindSectionHeader {
            let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionHeader, withReuseIdentifier: "headerID", for: indexPath)
                headerView.backgroundColor = UIColor.magenta
            
                label.text = "This is Header!"
                headerView.addSubview(label)
            return headerView
            
        }else{
            let footerView = collectionView.dequeueReusableSupplementaryView(ofKind: UICollectionElementKindSectionFooter, withReuseIdentifier: "footerID", for: indexPath)
                footerView.backgroundColor = UIColor.green
            
                label.text = "This is Footer!"
                footerView.addSubview(label)
            return footerView
        }
}
    
//编辑时设置是否可以移动Item
func collectionView(_ collectionView: UICollectionView, canMoveItemAt indexPath: IndexPath) -> Bool {
    return true
}
    
//Items 移动后,数据也要变更
func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
     NSLog("数据变更")
}
    
//设置索引参数
func indexTitles(for collectionView: UICollectionView) -> [String]? {
    return ["A","B","C","D","E"]
}
    
//返回索引位置信息
func collectionView(_ collectionView: UICollectionView, indexPathForIndexTitle title: String, at index: Int) -> IndexPath {
     return IndexPath.init()
}

9.UICollectionViewDelegateFlowLayout代理方法

//设置Item的宽、高
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
    return CGSize.init(width: collectionView.frame.width, height: 60)
}
    
//设置Section上、下、左、右 的偏移
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
    return UIEdgeInsets.init(top: 20, left: 0, bottom: 40, right: 0)
}
    
//设置Section HeaderView的宽、高
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
    return CGSize.init(width: self.view.frame.width, height: 30)
}
    
//设置Section footerView的宽、高
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForFooterInSection section: Int) -> CGSize {
    return CGSize.init(width: self.view.frame.width, height: 30)
}
    
//设置Items 之间的上下临时最小间距
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumInteritemSpacingForSectionAt section: Int) -> CGFloat {
    return 3
}
    
//设置Items之间的上下最小间距
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
    return 5
}

注:UICollectionViewDelegateFlowLayout代理中的方法可以在实例化let flowLayout = UICollectionViewFlowLayout()时,通过属性来设置

10.UICollectionViewDataSourcePrefetching代理方法

//UICollectionView 预先加载的数据 
func collectionView(_ collectionView: UICollectionView, prefetchItemsAt indexPaths: [IndexPath]) { 
    NSLog("获取Cell,赋值数据")
}

//UICollectionView 取消预先加载的数据 
func collectionView(_ collectionView: UICollectionView, cancelPrefetchingForItemsAt indexPaths: [IndexPath]) { 
    NSLog("取消预加载 ")
}

效果如图:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值