# CTCollectionViewDemo **Repository Path**: wangxingzhao/CTCollectionViewDemo ## Basic Information - **Project Name**: CTCollectionViewDemo - **Description**: UICollectionView的一些使用 - **Primary Language**: Swift - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 2 - **Created**: 2020-12-25 - **Last Updated**: 2020-12-25 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README 如果觉得有帮助,客观点个赞再走 ------ #1、头部拉伸效果 ![headerGrag.gif](https://upload-images.jianshu.io/upload_images/5725066-cc5c3a47adacacfc.gif?imageMogr2/auto-orient/strip) >1.继承UICollectionViewFlowLayout >2.方法override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool需要返回true,否则重写无效 >3.拿出所有布局内容数组,找到elementKindSectionHeader >4.判断是否是下拉,既contentOffset.y是否小于0 >5.重写frame ``` import UIKit class HeaderDragLayout: UICollectionViewFlowLayout { override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { let layoutAttributes = super.layoutAttributesForElements(in: rect) for layout in layoutAttributes! { /** 1.判断是否是头部视图 */ if layout.representedElementKind == UICollectionView.elementKindSectionHeader { let contentOffSetY: CGFloat = self.collectionView?.contentOffset.y ?? 0 /** 2.判断是否下拉 */ if contentOffSetY < CGFloat(0) { /** 3.重新设置头部视图的起始位置和高度 */ layout.frame = CGRect(x: layout.frame.minX, y: contentOffSetY, width: layout.frame.width, height: layout.frame.height - contentOffSetY) } } } return layoutAttributes } override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool { return true } } ``` #2、距离中心点越远,缩放越大 ![滚动图片.gif](https://upload-images.jianshu.io/upload_images/5725066-870d7aeb0bc592be.gif?imageMogr2/auto-orient/strip) >1.继承UICollectionViewFlowLayout >2.方法override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool需要返回true,否则重写无效 >3.找出滚动到的item的中心点位置centerX >4.使用abs()获取绝对距离 >5.计算缩放的范围(这里只是简单的做了一些算术题,主要是实现思路....) >6.最后设置每一个item的transform >7.重新设置中心点位置,这里用到了四舍五入方法round() ``` import UIKit class ScrollLayout: UICollectionViewFlowLayout { override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? { let customLayouts = super.layoutAttributesForElements(in: rect) if self.scrollDirection == .horizontal { let centerX = CGFloat((self.collectionView?.contentOffset.x)!) + CGFloat((self.collectionView?.bounds.size.width)!*0.5) for layout in customLayouts! { /// item中心点与界面中心的距离 let center = abs(layout.center.x - centerX) let scale = 1/(1+center/((self.collectionView?.bounds.size.width)! - self.minimumLineSpacing)) layout.transform = CGAffineTransform(scaleX: scale, y: scale) } } else { let centerY = CGFloat((self.collectionView?.contentOffset.y)!) + CGFloat((self.collectionView?.bounds.size.height)!*0.5) for layout in customLayouts! { /// item中心点与界面中心的距离 let center = abs(layout.center.y - centerY) let scale = 1/(1+center/((self.collectionView?.bounds.size.height)! - self.minimumLineSpacing)) layout.transform = CGAffineTransform(scaleX: scale, y: scale) } } return customLayouts } /// 重新设置中心点位置 override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint { var point = super.targetContentOffset(forProposedContentOffset: proposedContentOffset, withScrollingVelocity: velocity) if self.scrollDirection == .horizontal { let page = round(proposedContentOffset.x/(self.itemSize.width + self.minimumLineSpacing)) let pageX = self.itemSize.width * (page + 0.5) - (self.collectionView?.bounds.size.width)! * 0.5 + self.minimumLineSpacing*page point.x = pageX } else { let page = round(proposedContentOffset.y/(self.itemSize.height + self.minimumLineSpacing)) let pageY = self.itemSize.height * (page + 0.5) - (self.collectionView?.bounds.size.height)! * 0.5 + self.minimumLineSpacing*page point.y = pageY } return point } override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool { return true } } ``` #3、item的选中和移动 ![itemDrag.gif](https://upload-images.jianshu.io/upload_images/5725066-d1f7542ff26b0be0.gif?imageMogr2/auto-orient/strip) 本例中没有重新操作数据源 >1.声明UICollectionViewDragDelegate, UICollectionViewDropDelegate >2.声明代理时记得collectionView.dragInteractionEnabled = true >3.代理方法 optional func collectionView(_ collectionView: UICollectionView, dragPreviewParametersForItemAt indexPath: IndexPath) -> UIDragPreviewParameters? 实现选中item后的一些基础设置,包括如:、贝塞尔曲线. 、item的背景色 >4.代理方法 func collectionView(_ collectionView: UICollectionView, performDropWith coordinator: UICollectionViewDropCoordinator)实现拖动停止后的后续操作 ``` extension LevelViewController: UICollectionViewDragDelegate, UICollectionViewDropDelegate { func collectionView(_ collectionView: UICollectionView, itemsForBeginning session: UIDragSession, at indexPath: IndexPath) -> [UIDragItem] { let itemProvider = NSItemProvider.init() let drag = UIDragItem.init(itemProvider: itemProvider) return [drag] } /** 被选中以后可执行的操作:1、设置贝塞尔曲线 2、设置背景颜色 */ func collectionView(_ collectionView: UICollectionView, dragPreviewParametersForItemAt indexPath: IndexPath) -> UIDragPreviewParameters? { let path = UIBezierPath.init(roundedRect: CGRect(origin: CGPoint(x: 0, y: 0), size: cellSize), cornerRadius: 18) let parameters = UIDragPreviewParameters.init() parameters.backgroundColor = UIColor.gray parameters.visiblePath = path return parameters } func collectionView(_ collectionView: UICollectionView, itemsForAddingTo session: UIDragSession, at indexPath: IndexPath, point: CGPoint) -> [UIDragItem] { let itemProvider = NSItemProvider.init() let drag = UIDragItem.init(itemProvider: itemProvider) return [drag] } func collectionView(_ collectionView: UICollectionView, dragSessionDidEnd session: UIDragSession) { } func collectionView(_ collectionView: UICollectionView, dragSessionWillBegin session: UIDragSession) { } func collectionView(_ collectionView: UICollectionView, dragSessionAllowsMoveOperation session: UIDragSession) -> Bool { return true } func collectionView(_ collectionView: UICollectionView, dragSessionIsRestrictedToDraggingApplication session: UIDragSession) -> Bool { return true } // MARK:--------------- UICollectionViewDropDelegate --------------- func collectionView(_ collectionView: UICollectionView, dropSessionDidUpdate session: UIDropSession, withDestinationIndexPath destinationIndexPath: IndexPath?) -> UICollectionViewDropProposal { let dropProposal = UICollectionViewDropProposal.init(operation: .move, intent: .insertAtDestinationIndexPath) return dropProposal } func collectionView(_ collectionView: UICollectionView, performAction action: Selector, forItemAt indexPath: IndexPath, withSender sender: Any?) { } func collectionView(_ collectionView: UICollectionView, performDropWith coordinator: UICollectionViewDropCoordinator) { guard let endIndexPath: IndexPath = coordinator.destinationIndexPath else {return} guard let beginIndexPath: IndexPath = coordinator.items.first?.sourceIndexPath else {return} collectionView.moveItem(at: beginIndexPath, to: endIndexPath) } func collectionView(_ collectionView: UICollectionView, canHandle session: UIDropSession) -> Bool { return true } func collectionView(_ collectionView: UICollectionView, dropSessionDidEnter session: UIDropSession) { } } ``` [代码在这里:]https://gitee.com/wuchuantao_admin/CTCollectionViewDemo