娛樂基本展示
效果展示
- 如圖
!
內容的展示
界面佈局
-
內容的展示依然是一個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
- 修改對應的代碼即可