娱乐基本展示
效果展示
- 如图
!
内容的展示
界面布局
-
内容的展示依然是一个UICollectionView
- 懒加载UICollectionView
- 将UICollectionView添加到控制器的View中
- 实现数据源&代理
-
懒加载UICollectionView
private let kItemMargin : CGFloat = 10
private let kItemW = (kScreenW - 3 * kItemMargin) / 2
private let kNormalItemH = kItemW * 3 / 4
private let kPrettyItemH = kItemW * 4 / 3
private let kHeaderViewH : CGFloat = 50
private let kNormalCellID = "kNormalCellID"
private let kPrettyCellID = "kPrettyCellID"
private let kHeaderViewID = "kHeaderViewID"
class AmuseViewController: UIViewController {
// MARK: 懒加载属性
fileprivate lazy var collectionView : UICollectionView = {[unowned self] in
// 1.创建布局
let layout = UICollectionViewFlowLayout()
layout.itemSize = CGSize(width: kItemW, height: kNormalItemH)
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = kItemMargin
layout.headerReferenceSize = CGSize(width: kScreenW, height: kHeaderViewH)
layout.sectionInset = UIEdgeInsets(top: 0, left: kItemMargin, bottom: 0, right: kItemMargin)
// 2.创建UICollectionView
let collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: layout)
collectionView.backgroundColor = UIColor.white
collectionView.dataSource = self
collectionView.delegate = self
collectionView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
collectionView.register(UINib(nibName: "CollectionNormalCell", bundle: nil), forCellWithReuseIdentifier: kNormalCellID)
collectionView.register(UINib(nibName: "CollectionPrettyCell", bundle: nil), forCellWithReuseIdentifier: kPrettyCellID)
collectionView.register(UINib(nibName: "CollectionHeaderView", bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: kHeaderViewID)
return collectionView
}()
// MARK: 系统回调
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
}
}
- 实现数据源&代理方法
// MARK:- 遵守UICollectionView的数据源&代理协议
extension AmuseViewController : UICollectionViewDataSource, UICollectionViewDelegate {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return 8
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 4
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// 1.获取Cell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: kNormalCellID, for: indexPath)
cell.backgroundColor = UIColor.randomColor()
return cell
}
}
请求数据&展示数据
- 接口描述
- 请求地址:http://capi.douyucdn.cn/api/v1/getHotRoom/2
- 请求参数:无参数
- ViewModel封装
class AmuseViewModel {
fileprivate lazy var anchorGroups : [AnchorGroup] = [AnchorGroup]()
}
extension AmuseViewModel {
func loadAmuseData(finishedCallback : @escaping () -> ()) {
NetworkTools.requestData(.get, URLString: "http://capi.douyucdn.cn/api/v1/getHotRoom/2") { (result) in
// 1.获取数据
guard let resultDict = result as? [String : Any] else { return }
guard let dataArray = resultDict["data"] as? [[String : Any]] else { return }
// 2.字典转模型
for dict in dataArray {
self.anchorGroups.append(AnchorGroup(dict: dict))
}
// 3.回调数据
finishedCallback()
}
}
}
- 控制器中展示数据
- 修改之前的数据源&代理
fileprivate func loadData() {
amuseVM.loadAmuseData {
self.collectionView.reloadData()
}
}
父类抽取
- 展示内容,我们会发现,该界面和推荐界面相似度非常非常高
- 相似:添加UICollectionView,并且每组有对应的HeaderView
- 不同:推荐界面第1组使用的是PrettyCell
- 思考:
- 既然相似度很高,那么我们可以抽取父类
- 将相同代码抽取到父类中,不同代码子类自己来实现
- 请求数据的ViewModel的抽取
class BaseViewModel {
lazy var anchorGroups : [AnchorGroup] = [AnchorGroup]()
}
extension BaseViewModel {
func loadAnchorData(URLString : String, parameters : [String : Any]? = nil, finishedCallback : @escaping () -> ()) {
NetworkTools.requestData(.get, URLString: URLString, parameters: parameters) { (result) in
// 1.获取数据
guard let resultDict = result as? [String : Any] else { return }
guard let dataArray = resultDict["data"] as? [[String : Any]] else { return }
// 2.字典转模型
for dict in dataArray {
self.anchorGroups.append(AnchorGroup(dict: dict))
}
// 3.回调数据
finishedCallback()
}
}
}
- 抽取懒加载UICollectionView
- 两个控制器都需要懒加载一个UICollectionView
- 并且UICollectionView需要设置的内容和尺寸也是一致的
- 实现数据源&代理
- 无论是推荐还是娱乐都需要成为UICollectionView的数据源&代理
- 如果子类有不同的实现,可以让子类自己实现
private let kItemMargin : CGFloat = 10
private let kHeaderViewH : CGFloat = 50
let kItemW = (kScreenW - 3 * kItemMargin) / 2
let kNormalItemH = kItemW * 3 / 4
let kPrettyItemH = kItemW * 4 / 3
private let kNormalCellID = "kNormalCellID"
private let kHeaderViewID = "kHeaderViewID"
let kPrettyCellID = "kPrettyCellID"
class BaseAnchorViewController: UIViewController {
// MARK: 懒加载属性
var baseVM : BaseViewModel!
lazy var collectionView : UICollectionView = {[unowned self] in
// 1.创建布局
let layout = UICollectionViewFlowLayout()
layout.itemSize = CGSize(width: kItemW, height: kNormalItemH)
layout.minimumLineSpacing = 0
layout.minimumInteritemSpacing = kItemMargin
layout.headerReferenceSize = CGSize(width: kScreenW, height: kHeaderViewH)
layout.sectionInset = UIEdgeInsets(top: 0, left: kItemMargin, bottom: 0, right: kItemMargin)
// 2.创建UICollectionView
let collectionView = UICollectionView(frame: self.view.bounds, collectionViewLayout: layout)
collectionView.backgroundColor = UIColor.white
collectionView.dataSource = self
collectionView.delegate = self
collectionView.autoresizingMask = [.flexibleHeight, .flexibleWidth]
collectionView.register(UINib(nibName: "CollectionNormalCell", bundle: nil), forCellWithReuseIdentifier: kNormalCellID)
collectionView.register(UINib(nibName: "CollectionPrettyCell", bundle: nil), forCellWithReuseIdentifier: kPrettyCellID)
collectionView.register(UINib(nibName: "CollectionHeaderView", bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: kHeaderViewID)
return collectionView
}()
// MARK: 系统回调
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
loadData()
}
}
// MARK:- 设置UI界面内容
extension BaseAnchorViewController {
func setupUI() {
view.addSubview(collectionView)
}
func loadData() {
}
}
// MARK:- 遵守UICollectionView的数据源&代理协议
extension BaseAnchorViewController : UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
func numberOfSections(in collectionView: UICollectionView) -> Int {
return baseVM.anchorGroups.count
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return baseVM.anchorGroups[section].anchors.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
// 1.获取Cell
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: kNormalCellID, for: indexPath) as! CollectionNormalCell
cell.anchor = baseVM.anchorGroups[indexPath.section].anchors[indexPath.item]
return cell
}
func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
// 1.取出headerView
let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: kHeaderViewID, for: indexPath) as! CollectionHeaderView
headerView.group = baseVM.anchorGroups[indexPath.section]
return headerView
}
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: kItemW, height: kNormalItemH)
}
}
- 让RecommendViewController&AmuseViewController集成子BaseAnchorViewController
- 修改对应的代码即可