This is the 18th day of my participation in the August Genwen Challenge.More challenges in August

preface

Now we don’t know what to write, today we draw this page

Looking at the effect drawing, I found that there was a background picture at the bottom, and a small picture was placed on the background picture, and the small picture was regularly typeset. So here’s my idea:

A scrollView is a tableView with a background image on top of it. The contentSize of the scrollView is the height of the image. TableView cell is a small picture, and then set the height of the tableView to the height of the background picture 3, according to the rules to calculate the position of the small picture

All right, so let’s get started

Create a newStudyViewController

  • We use theJXCategoryViewI’m going to do pagination. I’m going to initialize itJXCategoryView
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] } }Copy the code
  • To get the data
Private func requestStudyDetailData() {net.school.studydetail (id: studyDetail) 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() {net.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) } } }Copy the code
  • Configure and refresh data
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()
}
Copy the code

Create a newStudyChildViewController

  • Initialize thescrollViewAnd, inscrollViewaddimageViewandtableView
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) / / / set up the image, and calculate the height of the image if the 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) {} func tableView(_ tableView: UITableView, heightForRowAt IndexPath: func tableView(_ tableView: UITableView, heightForRowAt IndexPath: IndexPath) -> CGFloat { return (imageViewHeight - 70) / CGFloat(dataSource.count) } } extension StudyChildViewController: JXCategoryListContentViewDelegate { func listView() -> UIView! { return view } }Copy the code
  • To get the data
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)
        }
    }
}
Copy the code
  • Looking at the renderings, it is found that the small pictures above are reset every 5, so incellInside so modify the layout of small pictures, specific details can be adjusted
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
    }
}
Copy the code

Effect:

If you have a better implementation method, please share with me