本文将演示如何创建强大的Pinterest风格的瀑布流界面。
Github项目:【demonnico/PinterestSwift】,下载并解压文件。
【PinterestSwift】文件夹->【CHTCollectionVIEwWatrfallLayout.swift】文件
->按下【Command】,继续选择【Extension.swift】->继续选择【Macro.swift】
->继续选择【NTHorizontalPagVIEwCell.swift】
->继续选择【NTTransition.swift】
->继续选择【NTTransitionProtocol.swift】
->继续选择【NTWaterfallVIEwCell.swift】
将上面选择的文件,拖入到自己的项目中。
在d出的文件导入确认窗口中,点击【Finish】完成按钮,确认文件的导入。
在项目文件夹上点击鼠标右键,d出右键菜单。
【New file】->【Cocoa touch】->【Next】->
【Class】:HorizontalPageVIEwController
【Subclass of】:UICollectionVIEwController
【Language】:Swift
->【Next】->【Create】
点击打开【HorizontalPageVIEwController.swift】,
现在开始编写代码,创建一个自定义的集合视图。
1 import Foundation 2 import UIKit 3 4 //初始化一个字符串常量,作为集合单元格的复用标识。 5 let horizontalPageVIEwCellIDentify = "horizontalPageVIEwCellIDentify" 6 7 //给当前的类添加两个协议,使用第一个协议中的方法,返回页面切换所需的集合视图, 8 //使用第二个协议的方法,设置集合视图的单元格的偏移距离。 9 class HorizontalPageVIEwController : UICollectionVIEwController,NTTransitionProtocol,NTHorizontalPageVIEwControllerProtocol10 {11 //添加一个字符串数组属性,作为集合视图每个单元格显示的图片内容。12 var imagenameList : Array <Nsstring> = []13 //添加一个属性,作为集合视图单元格的偏移距离。14 var pullOffset = CGPoint.zero15 16 //添加一个初始化方法,用来设置集合视图的布局。17 init(collectionVIEwLayout layout: UICollectionVIEwLayout!,currentIndexPath indexPath: IndexPath)18 {19 super.init(collectionVIEwLayout:layout)20 //获得集合视图控制器的集合视图。21 let collectionVIEw :UICollectionVIEw = self.collectionVIEw!;22 //设置集合视图在页面跳转时自动停止滚动23 collectionVIEw.isPagingEnabled = true24 //使用第三方类库提供的集合单元格类,注册集合视图的单元格,并设置单元格的复用标识。25 collectionVIEw.register(NTHorizontalPageVIEwCell.self,forCellWithReuseIDentifIEr: horizontalPageVIEwCellIDentify)26 //通过扩展方法,把一个对象与另外一个对象进行关联。27 //这需要使用到运行时函数,包含四个参数:28 //源对象、关键字、关联的对象、一个关联策略。29 collectionVIEw.setToIndexPath(indexPath)30 31 //调用集合视图对象的序列刷新方法,该方法可以执行多个插入、删除、重新加载、移动等 *** 作。32 collectionVIEw.performBatchUpdates({collectionVIEw.reloadData()},completion: { finished in33 if finished34 {35 //调用集合视图对象的滑动到指定项目方法,在垂直方向上,滑动到指定索引的单元格。36 collectionVIEw.scrollToItem(at: indexPath,at:.centeredHorizontally,animated: false)37 }});38 }39 40 overrIDe func vIEwDIDLoad()41 {42 super.vIEwDIDLoad()43 }44 45 //添加一个代理方法,用来初始化或复用集合视图中的单元格。46 overrIDe func collectionVIEw(_ collectionVIEw: UICollectionVIEw,cellForItemAt indexPath: IndexPath) -> UICollectionVIEwCell47 {48 //根据复用标识,从集合视图中获取可以复用的单元格。49 let collectionCell: NTHorizontalPageVIEwCell = collectionVIEw.dequeueReusableCell(withReuseIDentifIEr: horizontalPageVIEwCellIDentify,for: indexPath) as! NTHorizontalPageVIEwCell50 51 //设置集合视图的扩展设置,从而往集合视图中添加一个图像视图。52 collectionCell.imagename = self.imagenameList[(indexPath as NSIndexPath).row] as String53 //初始化集合视图的扩展属性。54 collectionCell.tappedAction = {}55 //给集合视图添加一个下拉动作。56 collectionCell.pullAction = { offset in57 //当接收到下拉事件时,58 self.pullOffset = offset59 //在导航控制器的堆栈中,返回上一个页面。60 self.navigationController!.popVIEwController(animated: true)61 }62 //在绘制周期开始前,首先对集合视图进行布局,63 collectionCell.setNeedsLayout()64 65 //最后返回设置好的集合视图单元格。66 return collectionCell67 }68 69 //添加一个代理方法,用来设置集合视图的单元格的数据。70 overrIDe func collectionVIEw(_ collectionVIEw: UICollectionVIEw,numberOfItemsInSection section: Int) -> Int71 {72 return imagenameList.count73 }74 75 //添加一个代理方法,用来返回页面切换所需的集合视图76 func TransitionCollectionVIEw() -> UICollectionVIEw!77 {78 return collectionVIEw79 }80 81 //添加一个代理方法,设置集合视图的单元格的偏移距离。82 func pageVIEwCellScrollVIEwContentOffset() -> CGPoint83 {84 return self.pullOffset85 }86 87 //添加一个必须实现的初始化方法88 required init?(coder aDecoder: NSCoder)89 {90 fatalError("init(coder:) has not been implemented")91 }92 }
在左侧的项目导航区,打开视图控制器的代码文件【VIEwController.swift】
现在开始编写代码,将系统默认的视图控制器,修改为另一个集合视图控制器,
作为瀑布流的载体。
1 import UIKit 2 3 let waterfallVIEwCellIDentify = "waterfallVIEwCellIDentify" 4 5 //创建一个遵循导航控制器代理协议的类 6 class NavigationControllerDelegate: NSObject,UINavigationControllerDelegate 7 { 8 //添加一个方法,用来处理导航控制器页面之间的跳转事件, 9 //并返回页面跳转的动画样式。 10 func navigationController(_ navigationController: UINavigationController,animationControllerFor operation: UINavigationController.Operation,from fromVC: UIVIEwController,to toVC: UIVIEwController) -> UIVIEwControllerAnimatedTransitioning?{ 11 12 //初始化三个对象,作为导航控制器跳转前的页面。 13 let fromVCConfromA = (fromVC as? NTTransitionProtocol) 14 let fromVCConfromB = (fromVC as? NTWaterFallVIEwControllerProtocol) 15 let fromVCConfromC = (fromVC as? NTHorizontalPageVIEwControllerProtocol) 16 17 //初始化三个对象,作为导航控制器跳转后的页面。 18 let toVCConfromA = (toVC as? NTTransitionProtocol) 19 let toVCConfromB = (toVC as? NTWaterFallVIEwControllerProtocol) 20 let toVCConfromC = (toVC as? NTHorizontalPageVIEwControllerProtocol) 21 22 //判断当从瀑布流页面,跳转到详情页面,或者从详情页面,返回瀑布流页面时的跳转样式。 23 if((fromVCConfromA != nil)&&(toVCConfromA != nil)&&( 24 (fromVCConfromB != nil && toVCConfromC != nil)||(fromVCConfromC != nil && toVCConfromB != nil))){ 25 //初始化一个动画跳转对象 26 let Transition = NTTransition() 27 //根据导航控制器的页面跳转的类型是否为出栈 *** 作, 28 //来设置跳转对象的布尔属性。 29 Transition.presenting = operation == .pop 30 //最后返回设置好的切换对象。 31 return Transition 32 } 33 else 34 { 35 return nil 36 } 37 } 38 } 39 40 //修改当前视图控制器的父类,将父类修改为集合视图控制器, 41 //并遵循瀑布流布局协议、动画切换协议、以及瀑布流视图控制器协议。 42 class VIEwController:UICollectionVIEwController,CHTCollectionVIEwDelegateWaterfallLayout,NTWaterFallVIEwControllerProtocol{ 43 44 //初始化一个字符串数组,作为集合视图所有图像的名称。 45 var imagenameList : Array <Nsstring> = [] 46 //初始化一个导航控制器代理对象。 47 let delegateHolder = NavigationControllerDelegate() 48 overrIDe func vIEwDIDLoad() 49 { 50 super.vIEwDIDLoad() 51 // Do any additional setup after loading the vIEw,typically from a nib. 52 //设置当前导航控制器的代理对象。 53 self.navigationController!.delegate = delegateHolder 54 55 var index = 1 56 //添加一个循环语句,用来往数组中添加图片的名称。 57 while(index<14) 58 { 59 //根据循环的索引,初始化一个由图片名称组成的字符串数组。 60 let imagename = Nsstring(format: "Pic%d.png",index) 61 //将图片名称添加到数组中。 62 imagenameList.append(imagename) 63 index += 1 64 } 65 66 //获得当前集合视图控制器中的集合视图。 67 let collection :UICollectionVIEw = collectionVIEw! 68 //设置集合视图的显示区域与屏幕相同,在此使用了宏定义常量。 69 collection.frame = screenBounds 70 //设置集合视图的布局样式 71 collection.setCollectionVIEwLayout(CHTCollectionVIEwWaterfallLayout(),animated: false) 72 //设置集合视图的背景颜色为黑色 73 collection.backgroundcolor = UIcolor.black 74 //给集合视图注册复用标识符 75 collection.register(NTWaterfallVIEwCell.self,forCellWithReuseIDentifIEr: waterfallVIEwCellIDentify) 76 //重新加载集合视图中的数据 77 collection.reloadData() 78 } 79 80 //添加一个方法,用来设置单元格的尺寸 81 func collectionVIEw(_ collectionVIEw: UICollectionVIEw,layout collectionVIEwLayout: UICollectionVIEwLayout,sizeforItemAtIndexPath indexPath: IndexPath) -> CGSize 82 { 83 //加载数组中的指定名称的图片 84 let image:UIImage! = UIImage(named: self.imagenameList[(indexPath as NSIndexPath).row] as String) 85 //单元格的宽度时固定的,在此根据单元格的高度和图片的宽度,获得等比例的图片高度。 86 let imageHeight = image.size.height*grIDWIDth/image.size.wIDth 87 88 //返回计算好的图片尺寸 89 return CGSize(wIDth: grIDWIDth,height: imageHeight) 90 } 91 92 //添加一个代理方法,用来初始化或复用集合视图中的单元格。 93 overrIDe func collectionVIEw(_ collectionVIEw: UICollectionVIEw,cellForItemAt indexPath: IndexPath) -> UICollectionVIEwCell 94 { 95 //根据复用标识,从集合视图中获取可以复用的单元格。 96 let collectionCell: NTWaterfallVIEwCell = collectionVIEw.dequeueReusableCell(withReuseIDentifIEr: waterfallVIEwCellIDentify,for: indexPath) as! NTWaterfallVIEwCell 97 //设置集合视图的扩展方法,从而往集合视图中添加一个图像视图。 98 collectionCell.imagename = self.imagenameList[(indexPath as NSIndexPath).row] as String 99 //对单元格在绘制之前进行重新布局。并返回设置好的单元格。100 collectionCell.setNeedsLayout()101 return collectionCell102 }103 104 //添加一个代理方法,用来设置单元格的数量105 overrIDe func collectionVIEw(_ collectionVIEw: UICollectionVIEw,numberOfItemsInSection section: Int) -> Int106 {107 return imagenameList.count108 }109 110 //添加一个代理方法,用来处理单元格的触摸事件。111 overrIDe func collectionVIEw(_ collectionVIEw: UICollectionVIEw,dIDSelectItemAt indexPath: IndexPath)112 {113 //初始化一个视图控制器,作为即将显示的细节页面。114 let pageVIEwController =115 HorizontalPageVIEwController(collectionVIEwLayout: pageVIEwControllerLayout(),currentIndexPath:indexPath)116 //设置控制器的图片名称列表属性117 pageVIEwController.imagenameList = imagenameList118 //在集合视图中,跳转到指定位置的单元格119 collectionVIEw.setToIndexPath(indexPath)120 //在导航控制器的堆栈中,压入新的集合控制器。121 navigationController!.pushVIEwController(pageVIEwController,animated: true)122 }123 124 //添加一个方法,用来设置集合视图的布局方式125 func pageVIEwControllerLayout () -> UICollectionVIEwFlowLayout126 {127 //初始化一个集合视图流布局对象。128 let flowLayout = UICollectionVIEwFlowLayout()129 //根据导航栏的显示状态,创建集合视图的尺寸。130 let itemSize = self.navigationController!.isNavigationbarHIDden ?131 CGSize(wIDth: screenWIDth,height: screenHeight+20) : CGSize(wIDth: screenWIDth,height: screenHeight-navigationheaderAndStatusbarHeight)132 //设置集合视图的单元格的尺寸。133 flowLayout.itemSize = itemSize134 //设置单元格之间的最小行距135 flowLayout.minimumlinespacing = 0136 //设置同一行的单元格之间的最小间距。137 flowLayout.minimumInteritemSpacing = 0138 //设置布局对象的滚动方向为水平方向。139 flowLayout.scrollDirection = .horizontal140 141 //返回设置好的布局对象142 return flowLayout143 }144 145 //添加一个方法,用来返回进行动态切换的集合视图146 func TransitionCollectionVIEw() -> UICollectionVIEw!147 {148 return collectionVIEw149 }150 151 func vIEwWillAppearWithPageIndex(_ pageIndex : NSInteger)152 {153 154 }155 156 overrIDe func dIDReceiveMemoryWarning() {157 super.dIDReceiveMemoryWarning()158 // dispose of any resources that can be recreated.159 }160 }
在项目导航区,打开故事板文件。
在故事板中添加一个集合视图控制器,首先选择并删除默认的视图控制器。
选择默认的视图控制器,【Command】+【Delete】删除选择的视图控制器。
点击控件库图标,打开控件库的列表窗口。双击集合视图控制器,往故事板中插入一个控制器。
依次点击:【Editor】编辑器->【Embed In】植入->【Navigation Controller】导航控制器
将集合视图控制器植入导航控制器。植入导航控制器。
打开检查器设置面板,点击属性检查器图标,进入属性设置面板。
勾选【Is Initial VIEw Controller】是否初始视图控制器。
将导航控制器修改为项目的初始控制器。
选择集合视图控制器,点击身份检查器图标,打开身份设置面板。
在类名输入框内,输入所绑定的自定义集合视图类。
【Class】:VIEwController
模拟器启动后,由下往上拖动,可以浏览瀑布流底部的内容。
在详情页面的顶部往下方拖动,
通过下拉动作,返回瀑布流页面。
总结以上是内存溢出为你收集整理的[Swift通天遁地]九、拔剑吧-(11)创建强大的Pinterest风格的瀑布流界面全部内容,希望文章能够帮你解决[Swift通天遁地]九、拔剑吧-(11)创建强大的Pinterest风格的瀑布流界面所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)