使用Swift開發一個貝樂虎啟蒙App - 識字頁面佈局

語言: CN / TW / HK

前言

現在都不知道寫些什麼了,今天我們來畫個這個頁面

1111111.gif

看效果圖發現,底部是個背景圖片,背景圖上面放了一個一個的小圖片,小圖片是有規律的排版。 所以我的思路是:

1、最底部是一個scrollViewscrollView上面放一個背景圖片,scrollViewcontentSize的高度是圖片的高度
2、scrollView上面再放個tableViewtableViewcell就是一個一個的小圖片,然後tableView的高度設定成背景圖片的高度
3、根據規則計算小圖片的位置

好了那我們就開始做吧

新建一個StudyViewController

  • 我們使用JXCategoryView來做分頁,先初始化JXCategoryView

``` class StudyViewController: BaseViewController {

var id: String = ""     private var controllers = StudyChildViewController     private var titles = StudySecItemModel     private var cateId: String = ""     private var imageBaseName = ""

private lazy var titleView: JXCategoryNumberView = {         let lineView = JXCategoryIndicatorLineView()         lineView.indicatorColor = .theme         lineView.indicatorHeight = 4         let titleView = JXCategoryNumberView()         titleView.defaultSelectedIndex = 0         titleView.delegate = self         titleView.indicators = [lineView]         titleView.titleColor = .c999999         titleView.titleSelectedColor = .theme         titleView.titleFont = 14.font         titleView.titleSelectedFont = 16.font         titleView.isTitleColorGradientEnabled = true         titleView.backgroundColor = .white         titleView.isAverageCellSpacingEnabled = true         titleView.cellSpacing = 0         return titleView     }()

private lazy var listContainerView: JXCategoryListContainerView = {         let listContainerView = JXCategoryListContainerView(type: .scrollView, delegate: self)         listContainerView?.setDefaultSelectedIndex(0)         return listContainerView!     }()

override func viewDidLoad() {         super.viewDidLoad()

addSubviews()         requestStudyDetailData()     }

private func addSubviews() {         automaticallyAdjustsScrollViewInsets = false

view.addSubview(titleView)         view.addSubview(listContainerView)

titleView.snp.makeConstraints { (make) in             make.top.equalTo(topLayoutGuideBottom)             make.left.right.equalToSuperview()             make.height.equalTo(40)         }

listContainerView.snp.makeConstraints { make in             make.left.right.equalToSuperview()             make.top.equalTo(titleView.snp.bottom)             make.bottom.equalTo(safeAreaLayoutGuideBottom)         }

titleView.contentScrollView = listContainerView.scrollView     } }

// MARK: JXCategoryViewDelegate extension StudyViewController: JXCategoryViewDelegate {     func categoryView(_ categoryView: JXCategoryBaseView!, didClickSelectedItemAt index: Int) {         listContainerView.didClickSelectedItem(at: index)     } }

// MARK: JXCategoryListContainerViewDelegate extension StudyViewController: JXCategoryListContainerViewDelegate {

func number(ofListsInlistContainerView listContainerView: JXCategoryListContainerView!) -> Int {         return controllers.count     }

func listContainerView(_ listContainerView: JXCategoryListContainerView!, initListFor index: Int) -> JXCategoryListContentViewDelegate! {         return controllers[index]     } } ```

  • 獲取資料

extension StudyViewController { /// 詳情資料     private func requestStudyDetailData() {         Network.School             .studyDetail(id: id)             .request()             .responseData(StudyDetailModel.self) { [weak self] model in                 guard let `self` = self else { return }                 self.navigation.item.title = model.result.title                 self.cateId = model.result.interactLesson.resourceId                 self.imageBaseName = model.result.interactLesson.imageBaseName                 self.requestStudySecData()         } failure: { error in             Toast.show(info: error.errorMessage)         }     } /// 標題資料     private func requestStudySecData() {         Network.School             .studySec(cateId: cateId)             .request()             .responseData(StudySecModel.self) { [weak self] model in                 guard let `self` = self else { return }                 self.titles = model.result.items                 self.reloadData()         } failure: { error in             Toast.show(info: error.errorMessage)         }     } }

  • 配置資料並重新整理

private func reloadData() { titleView.titles = titles.map({ return $0.name }) for item in titles { let vc = StudyChildViewController() vc.imageName = imageBaseName + String(format: "%02ld", item.nameIndex) vc.cateId = cateId vc.secId = item.secId controllers.append(vc) } titleView.reloadData() listContainerView.reloadData() }

新建一個StudyChildViewController

  • 初始化scrollView,並在scrollView裡面新增imageViewtableView

``` class StudyChildViewController: BaseViewController {

var cateId = ""     var secId = ""     var imageName: String = ""     private var imageViewHeight: CGFloat = 0     private var dataSource = StudySecItemModel

private lazy var scrollView: UIScrollView = {         let view = UIScrollView()         view.bounces = false         return view     }()

private lazy var imageView: UIImageView = {         let view = UIImageView()         view.contentMode = .scaleAspectFit         return view     }()

private lazy var tableView: UITableView = {         let view = UITableView(frame: .zero, style: .plain)         view.separatorStyle = .none         view.delegate = self         view.dataSource = self         view.backgroundColor = .clear         view.register(cellWithClass: StudyUnitCell.self)         return view     }()

override func viewDidLoad() {         super.viewDidLoad()

addSubviews()         requestStudyUnitData()     }

private func addSubviews() {         disablesAdjustScrollViewInsets(scrollView)         disablesAdjustScrollViewInsets(tableView)

/// 設定image,並計算image高度         if let image = UIImage(named: imageName) {             imageView.image = image             let imageW = image.size.width             let imageH = image.size.height             let sc = imageH/imageW             imageViewHeight = UIScreen.width * sc         }

view.addSubview(scrollView)         scrollView.addSubview(imageView)         scrollView.addSubview(tableView)

scrollView.snp.makeConstraints { make in             make.left.top.right.equalToSuperview()             make.bottom.equalToSuperview()         }

imageView.snp.makeConstraints { make in             make.left.top.equalToSuperview()             make.width.equalTo(UIScreen.width)             make.height.equalTo(imageViewHeight)         }

tableView.snp.makeConstraints { make in             make.top.equalToSuperview().offset(10)             make.left.equalToSuperview()             make.width.equalTo(UIScreen.width)             make.height.equalTo(imageViewHeight - 70)         }

scrollView.contentSize = CGSize(width: UIScreen.width, height: imageViewHeight)         scrollView.scrollToBottom()     }

}

extension StudyChildViewController: UITableViewDelegate, UITableViewDataSource {

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {         return dataSource.count     }

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {         let cell = tableView.dequeueReusableCell(withClass: StudyUnitCell.self)         cell.backgroundColor = .clear         cell.iconView.kf_set(dataSource[indexPath.row].coverVer)         cell.updateLayout(indexPath.row)         return cell     }

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {}

/// 根據總高度和item的數量計算cell高度     func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {         return (imageViewHeight - 70) / CGFloat(dataSource.count)     } }

extension StudyChildViewController: JXCategoryListContentViewDelegate {     func listView() -> UIView! {         return view     } } ``` - 獲取資料

``` extension StudyChildViewController {

private func requestStudyUnitData() {         Network.School             .studyUnitList(cateId: cateId, secId: secId)             .request()             .responseData(StudyUnitModel.self) { [weak self] model in                 guard let self = self else { return }                 self.dataSource = model.result.items.sorted(by: {                     $0.index > $1.index                 })                 self.tableView.reloadData()         } failure: { error in             Toast.show(info: error.errorMessage)         }     } } ```

  • 看效果圖發現,上面的小圖片是每5個會重置,所以在cell裡面這樣修改小圖片的佈局,具體的細節可以自己調 func updateLayout(_ index: Int) { let i = index % 4 switch i { case 0: iconView.snp.updateConstraints { make in make.centerX.equalToSuperview().offset(20) } case 1: iconView.snp.updateConstraints { make in make.centerX.equalToSuperview().offset(-60) } case 2: iconView.snp.updateConstraints { make in make.centerX.equalToSuperview().offset(-20) } case 3: iconView.snp.updateConstraints { make in make.centerX.equalToSuperview().offset(60) } default: break } }

效果:

222.gif

如果你們有更好的實現方法,歡迎與我分享