[Swift通天遁地]九、拔剑吧-(17)创建一个三维折叠样式的页面展开效果

本文将演示实现单元格在扩展、收缩时折叠式的炫目动态效果。

GitHub项目:【Ramotion/folding-cell】,下载并解压文件。

【FoldingCell->【FoldingCell.swift】文件->将该文件拖动到项目中,点击【Finish】

创建一个继承自第三方类库的单元格。

在项目文件夹上点击鼠标右键,弹出右键菜单。

【New File->【Cocoa Touch->【Next】->

【Class】:DemoCell

【Subclass of:FoldingCell

【Language】:Swift

->Next->【Create】

点击打开【DemoCell.swift】

现在开始编写代码,创建自定义的单元格。

 1 import UIKit
 2 
 3 class DemoCell: FoldingCell
 4 {
 5     //添加一个标签属性,显示单元格处于折叠状态时的标题文字。
 6   @IBOutlet weak var closeNumberLabel: UILabel!
 7     //添加一个标签属性,显示单元格处于展开状态时的标题文字。
 8   @IBOutlet weak var openNumberLabel: UILabel!
 9   
10     //添加一个默认值为0的变量
11   var number: Int = 0
12   {
13     //当对该变量进行设置操作时,修改两个标签中的文字内容。
14     didSet
15     {
16       closeNumberLabel.text = "#\(String(number))"
17       openNumberLabel.text = "Item #\(String(number))"
18     }
19   }
20     
21     //当从故事板中加载完毕后,调用此方法
22   override func awakeFromNib()
23   {
24     //设置处于折叠状态时的单元格,
25     //将其前景视图的圆角半径设置为10
26     foregroundView.layer.cornerRadius = 10
27     foregroundView.layer.masksToBounds = true
28     
29     super.awakeFromNib()
30   }
31   
32     //添加一个方法,用来设置三段折叠动画各自的时长。
33   override func animationDuration(_ itemIndex:NSInteger, type:AnimationType)-> TimeInterval
34   {
35     //初始化一个包含三个元素的数组
36     let durations = [0.26, 0.2, 0.2]
37     //并根据索引返回相应的时长
38     return durations[itemIndex]
39   }
40 }
41 
42 //添加一个针对当前类的扩展
43 extension DemoCell
44 {
45     //添加一个方法,用来响应故事板中的按钮的点击事件
46   @IBAction func buttonHandler(_ sender: AnyObject)
47   {
48     print("tap")
49   }
50 }

在左侧的项目导航区,打开视图控制器的代码文件【ViewController.swift】

现在开始编写代码,创建一个表格控件。

 

  1 import UIKit
  2 
  3 //将父类修改为表格视图控制器
  4 class ViewController: UITableViewController {
  5     
  6     //添加一个常量属性,作为单元格在折叠状态时的高度。
  7     let kCloseCellHeight: CGFloat = 179
  8     //添加一个常量属性,作为单元格在展开状态时的高度。
  9     let kOpenCellHeight: CGFloat = 488
 10     //添加一个常量属性,作为单元格的数量。
 11     let kRowsCount = 10
 12     //添加一个数组属性,作为每个单元格各自的高度。
 13     var cellHeights = [CGFloat]()
 14     
 15     override func viewDidLoad()
 16     {
 17         super.viewDidLoad()
 18         //添加一个循环语句
 19         for _ in 0...kRowsCount
 20         {
 21             //作为单元格在折叠状态时的高度,存入数组中。
 22             cellHeights.append(kCloseCellHeight)
 23         }
 24         //设置表格视图的背景属性,这里使用一张图片,作为表格视图的背景。
 25         self.tableView.backgroundColor = UIColor(patternImage: UIImage(named: "background")!)
 26     }
 27     
 28     //添加一个代理方法,用来设置单元格的行数
 29     override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
 30     {
 31         return 10
 32     }
 33     
 34      //添加一个代理方法,用来响应单元格即将展示时的事件
 35     override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
 36     {
 37         //将单元格的类型进行转换
 38         guard case let cell as DemoCell = cell else {
 39             return
 40         }
 41         
 42         //当单元格处于折叠状态时
 43         if cellHeights[(indexPath as NSIndexPath).row] == kCloseCellHeight
 44         {
 45             //设置单元格对应的高度,在调整高度时不播放动画。
 46             cell.selectedAnimation(false, animated: false, completion:nil)
 47         }
 48         else
 49         {
 50             //当单元格处于展开状态时,
 51             //设置单元格对应的高度,在调整高度时同样不播放动画。
 52             cell.selectedAnimation(true, animated: false, completion: nil)
 53         }
 54         
 55         //清除单元格的背景颜色,并设置单元格属性的值。
 56         cell.backgroundColor = UIColor.clear
 57         //当设置该属性时,会自动调整标题文字的内容。
 58         cell.number = indexPath.row
 59     }
 60     
 61     //添加一个代理方法,用来初始化或复用单元格。
 62     override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
 63     {
 64         //从表格中获得指定复用标识符的单元格对象。
 65         let cell = tableView.dequeueReusableCell(withIdentifier: "FoldingCell", for: indexPath)
 66         
 67         return cell
 68     }
 69     
 70     //添加一个代理方法,用来设置单元格的高度。
 71     override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat
 72     {
 73         //根据单元格的行数,从数组中获得单元格对应的高度的值。
 74         return cellHeights[(indexPath as NSIndexPath).row]
 75     }
 76     
 77     //添加一个代理方法,用来响应单元格的点击事件。
 78     override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
 79     {
 80         //获得被点击的单元格,并转换单元格的类型。
 81         let cell = tableView.cellForRow(at: indexPath) as! FoldingCell
 82         
 83         //对于正在播放展开或折叠动画的单元格来说,
 84         //不需要执行后面的代码。
 85         if cell.isAnimating()
 86         {
 87             return
 88         }
 89         
 90         //初始化一个默认值为0的浮点变量,作为动画的时长。
 91         var duration = 0.0
 92         //处理单元格处于折叠状态时,被点击的情况。
 93         if cellHeights[(indexPath as NSIndexPath).row] == kCloseCellHeight
 94         {
 95             //当处于折叠状态的单元格被点击时,修改数组中对应元素的值。
 96             cellHeights[(indexPath as NSIndexPath).row] = kOpenCellHeight
 97             //单元格开始播放展示的动画。
 98             cell.selectedAnimation(true, animated: true, completion: nil)
 99             //设置动画的时长为0.秒
100             duration = 0.5
101         }
102         else
103         {
104             //当处于展开状态的单元格被点击时,修改数组中对应元素的值。
105             cellHeights[(indexPath as NSIndexPath).row] = kCloseCellHeight
106             //单元格开始播放折叠的动画。
107             cell.selectedAnimation(false, animated: true, completion: nil)
108             //设置动画的时长为0.8秒
109             duration = 0.8
110         }
111         
112         //创建一个指定时长、延时和缓冲属性的视图动画,
113         //用来动态调整单元格的高度。
114         UIView.animate(withDuration: duration, delay: 0, options: .curveEaseOut, animations: { () -> Void in
115                //对表格视图进行刷新操作
116                 tableView.beginUpdates()
117                 tableView.endUpdates()
118             }, completion: nil)
119     }
120 }

在左侧的项目导航区,打开故事板文件【Main.storyboard

选择故事板中 的默认视图控制器。

【Command】+【Delete】删除选择的控制器。

点击控件库图标,打开控件库的列表窗口。

往故事板中插入一个控制器。

进入身份检查器图标,进入身份设置面板。

【Class】:ViewController,输入视图控制器的类名。

【Storyboard ID:MainTableViewController设置视图控制器在故事板中的唯一标识符。

进入属性设置面板。

勾选【Is Initial View Controller】是否初始视图控制器。

将导航控制器修改为当前的故事板的初始控制器。

选择故事板中表格控件,进入尺寸设置面板

【Row Height】:83,设置行高。

选择单元格控件,

【Row Height】:667,设置行高。

进入身份设置面板,

【Class】:DemoCell输入单元格控件的类名

进入属性设置 面板,

【Item Count:设置单元格的折叠区域为4,默认值为2

【Back View Color】:设置后退视图的背景颜色,默认值为橙色。

【Identifier:FoldingCell输入单元格的复用标识符,保持和代码中的相同。

往故事板中插入一个视图,该视图作为你单元格在折叠时的显示容器。

点击身份检查器图标,进入身份设置面板。

【Class】:RotatedView

进入尺寸设置面板,依次设置视图对象的坐标和尺寸信息。

往故事板中插入一个图像视图,依次设置图像视图的坐标和尺寸信息。

点击属性检查器图标,进入属性设置面板,

设置图像视图的显示内容。【Image】:TopOne

打开控件库的列表窗口。往故事板中插入一个标签。

设置标签控件的文字内容【Text】

点击尺寸检查器图标,依次设置标签控件的坐标和尺寸信息。

选择单元格的内容视图,

往故事板中插入一个视图,该视图作为单元格在展开时的显示容器。

依次设置视图对象的坐标和尺寸信息。

打开控件库的列表窗口,往故事板中插入一个图像视图。

依次设置图像视图的坐标和尺寸信息。

点击属性检查器图标,进入属性设置面板。

设置图像视图的显示内容【Image】

打开控件库的列表窗口,往故事板中插入一标签控件。

设置标签控件的文字内容。

点击属性检查器图标,依次设置图像视图的坐标和尺寸信息。

往故事板中插入一个按钮,依次设置按钮控件的坐标和尺寸信息。

点击属性检查器图标,进入属性设置面板。

设置按钮上方的标题文字。设置前景色。

选择单元格在展开时的内容视图,

在内容视图按下右键,并拖动到单元格的内容视图,

以建立两者之间的约束关系。

在弹出的约束列表中,选择【Leading Space to Container Margin】

继续相同的拖动,设置其他约束【Trailing Space to Container Margin】

继续相同的拖动,设置其他约束【Top Space to Container Margin】

在内容视图上按下右键,并拖动到自身的其他位置,

以建立自身的约束关系。在弹出的约束列表中,

选择【Height】:从而约束其高度始终不变。

选择单元格在选择状态时的内容视图。

在内容视图上按下右键,并拖动到单元格的内容视图,以建立两者之间的约束关系。

在弹出的约束列表中,选择【Leading Space to Container Margin】

继续相同的拖动,设置其他约束【Trailing Space to Container Margin】

继续相同的拖动,设置其他约束【Top Space to Container Margin】

在内容视图上按下右键,并拖动个到自身的其他位置,以建立自身的约束关系。

在弹出的约束列表中,选择【Height】:从而约束其高度始终不变。

点击辅助编辑器图标,

最后将故事板中的控件,和类文件中的属性进行连接。

猜你喜欢

转载自www.cnblogs.com/strengthen/p/10361436.html