当前位置: 首页 > article >正文

IOS 24 实现歌单详情(UITableView)列表

歌单详情完整效果

歌单详情歌单列表效果

歌单详情列表页整体效果稍微有点复杂,我们进行分部实现,先实现歌单详情里面的歌单列表,使用UITableView来实现。UITableView的使用在之前的文章中多次使用,想来也比较熟悉了。不熟悉的可以看之前文章:IOS 21 发现界面(UITableView)单曲列表(UITableView)实现

歌单列表UITableView实现

1、创建SheetDetailController,继承自BaseTitleController

class SheetDetailController: BaseTitleController {
}

2、重新initViews(),初始化 UITableView

class SheetDetailController: BaseTitleController {

    override func initViews() {
        super.initViews()
        
        // 初始化TableView结构
        initTableViewSafeArea()

    }
 }

歌单列表Cell实现

实现流程:
1.创建Cell,及在使用UITableView的Controller控制器上注册Cell;

2.获取data列表数据,并调用UITableView的reloadData(),将数据更新到列表;

3.将data的Item数据绑定UITableView的每一个Cell。

1)创建和注册Cell

从效果图上面可以看出,歌单列表Cell由一个水平方向布局包含左中右三部分来实现。

自定义SongItemCell,继承自BaseTableViewCell,默认就是一个水平方向的TGLinearLayout。

//
//  SongItemCell.swift
//  音乐cell
//
//  Created by jin on 2024/9/12.
//

import UIKit
import TangramKit

class SongItemCell: BaseTableViewCell {
    override func initViews() {
        super.initViews()
        container.tg_space = 0
        container.backgroundColor = .colorLightWhite
        
        //右侧有边距
        container.tg_padding = UIEdgeInsets(top: PADDING_SMALL, left: 0, bottom: 0, right: PADDING_SMALL)
        container.tg_gravity = TGGravity.vert.center
        
        //左侧容器
        let leftContainer = TGRelativeLayout()
        leftContainer.tg_width.equal(50)
        leftContainer.tg_height.equal(50)
        container.addSubview(leftContainer)
        
        //索引
        leftContainer.addSubview(self.indexView)
        
        //右侧容器
        let rightContainer = TGLinearLayout(.vert)
        rightContainer.tg_width.equal(.fill)
        rightContainer.tg_height.equal(.wrap)
        rightContainer.tg_space = PADDING_SMALL
        container.addSubview(rightContainer)
        
        //标题
        rightContainer.addSubview(self.titleView)
        
        //信息容器
        let infoContainer = TGLinearLayout(.horz)
        infoContainer.tg_width.equal(.fill)
        infoContainer.tg_height.equal(.wrap)
        infoContainer.tg_space = PADDING_SMALL
        rightContainer.addSubview(infoContainer)
        
        infoContainer.addSubview(self.downloadedView)
        infoContainer.addSubview(self.infoView)
        
        //更多按钮
        let moreButton = ViewFactoryUtil.button(image:R.image.moreVerticalDot()!.withTintColor())
        moreButton.tintColor = .black80
        moreButton.tg_width.equal(50)
        moreButton.tg_height.equal(50)
        container.addSubview(moreButton)
    }
    
    func bind(_ data:Song) {
        titleView.text = data.title
        infoView.text = "\(data.singer.nickname!) - 这是专辑"
    }
    
    lazy var indexView: UILabel = {
        let result = UILabel()
        result.tg_width.equal(.wrap)
        result.tg_height.equal(.wrap)
        result.tg_centerX.equal(0)
        result.tg_centerY.equal(0)
        result.numberOfLines = 1
        result.font = UIFont.systemFont(ofSize: TEXT_LARGE)
        result.textColor = .black80
        
        return result
    }()
    
    lazy var titleView: UILabel = {
        let r = UILabel()
        r.tg_width.equal(.fill)
        r.tg_height.equal(.wrap)
        r.numberOfLines = 1
        r.font = UIFont.systemFont(ofSize: TEXT_LARGE)
        r.textColor = .colorOnSurface
        
        return r
    }()
    
    lazy var downloadedView: UIImageView = {
        let r = UIImageView()
        r.tg_width.equal(.wrap)
        r.tg_height.equal(.wrap)
        r.tg_visibility = .gone
        r.image = R.image.downloaded()
        
        return r
    }()
    
    lazy var infoView: UILabel = {
        let r = UILabel()
        r.tg_width.equal(.fill)
        r.tg_height.equal(.wrap)
        r.numberOfLines = 1
        r.font = UIFont.systemFont(ofSize: TEXT_MEDDLE)
        r.textColor = .black80
        
        return r
    }()
}
//
//  BaseTableViewCell.swift
//  通用TableViewCell
//
//  Created by jin on 2024/8/27.
//

import UIKit

//提供类似Android中更高层级布局框架
import TangramKit

class BaseTableViewCell:UITableViewCell{
    
    //对于需要动态评估高度的UITableViewCell来说可以把布局视图暴露出来。用于高度评估和边界线处理。以及事件处理的设置。
    var container:TGBaseLayout!
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        innerInit()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        innerInit()
    }
    
    func innerInit() {
        initViews()
        initDatum()
        initListeners()
    }
    
    /// 找控件
    func initViews() {
        //背景透明
        backgroundColor = .clear
        contentView.backgroundColor = .clear
        
        //去掉默认的选中颜色
        selectionStyle = .none
        
        //根容器
        container = TGLinearLayout(getContainerOrientation())
        container.tg_width.equal(.fill)
        container.tg_height.equal(.wrap)
        container.tg_space = PADDING_MEDDLE
        contentView.addSubview(container)
    }
    
    func initDatum() {
        
    }
    
    func initListeners() {
        
    }
    
    /// 获取根容器布局方向
    func getContainerOrientation() -> TGOrientation {
        return .horz
    }
    
    /// 使用TangramKit后,让item自动计算高度,要重写该方法
    /// - Parameters:
    ///   - targetSize: <#targetSize description#>
    ///   - horizontalFittingPriority: <#horizontalFittingPriority description#>
    ///   - verticalFittingPriority: <#verticalFittingPriority description#>
    /// - Returns: <#description#>
    override func systemLayoutSizeFitting(_ targetSize: CGSize, withHorizontalFittingPriority horizontalFittingPriority: UILayoutPriority, verticalFittingPriority: UILayoutPriority) -> CGSize {
        return self.container.systemLayoutSizeFitting(targetSize)
    }
}

在SheetDetailController控制器,注册SongItemCell

class SheetDetailController: BaseTitleController {

    override func initViews() {
        super.initViews()
        
        // 初始化TableView结构
        initTableViewSafeArea()
        
        // 注册单曲
        tableView.register(SongItemCell.self, forCellReuseIdentifier: Constant.CELL)
    }
    
}
2)获取data列表数据

定义列表数据模型Song

//
//  Song.swift
//  单曲模型
//
//  Created by jin on 2024/9/2.
//

import Foundation

//导入JSON解析框架
import HandyJSON

class Song : BaseCommon{
    /// 标题
    var title:String!
    
    /// 封面
    var icon:String?
    
    /// 音乐地址
    var uri:String!
    
    /// 点击数
    var clicksCount:Int = 0
    
    /// 评论数
    var commentsCount:Int = 0
    
    /// 创建该音乐的人
    var user:User!
    
    /// 歌手
    var singer:User!
    
    /// 歌词类型
    var style:Int = 0
    
    /**
     * 歌词内容
     */
    var lyric:String? = nil
    
    override func mapping(mapper: HelpingMapper) {
        super.mapping(mapper: mapper)
        mapper <<< self.clicksCount <-- "clicks_count"
        mapper <<< self.commentsCount <-- "comments_count"
    }
}

请求歌单详情接口获取歌单详情里的歌曲列表数据,更新tableView.reloadData()

class SheetDetailController: BaseTitleController {
    var id: String!
    var data: Sheet!
    
    override func initViews() {
        super.initViews()
        
        // 初始化TableView结构
        initTableViewSafeArea()
        
        title = R.string.localizable.sheet()
        
        // 注册单曲
        tableView.register(SongItemCell.self, forCellReuseIdentifier: Constant.CELL)
    }
    
    override func initDatum() {
        super.initDatum()
        loadData()
    }
    
    func loadData() {
        DefaultRepository.shared
            .sheetDetail(id)
            .subscribeSuccess { [weak self] data in
                self?.show(data.data!)
            }.disposed(by: rx.disposeBag)
    }
    
    func show(_ data: Sheet) {
        self.data = data
        datum = data.songs ?? []
        tableView.reloadData()
    }
}
3)Item数据绑定Cell

SheetDetailController控制器重写父类的扩展 cellForRowAt方法,创建对应的Cell,并将Item数据绑定到Cell。

extension SheetDetailController {
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let data = datum[indexPath.row] as! Song
        let cell = tableView.dequeueReusableCell(withIdentifier: Constant.CELL, for: indexPath) as! SongItemCell
        cell.bind(data)
        cell.indexView.text = "\(indexPath.row + 1)"
        return cell
    }
}

至此,实现了歌单详情里面的歌单列表。


http://www.kler.cn/a/310450.html

相关文章:

  • 2024版本IDEA创建Sprintboot项目下载依赖缓慢
  • 深度学习之 LSTM
  • RAFT: Recurrent All-Pairs Field Transforms for Optical Flow用于光流估计的循环全对场变换
  • PaaS云原生:分布式集群中如何构建自动化压测工具
  • 河南省的一级科技查新机构有哪些?
  • Spring Boot 核心配置文件
  • 下载Kafka 3.0.0教程
  • 基于Matlab的模拟答题卡识别阅卷可以识别指定答题卡的各个部分-界面
  • Day04_JVM实战
  • 开发定制:学校考试成绩自动处理,可定制规则
  • 2024桥梁科技两江论坛——第二届桥梁工程安全与韧性学术会议
  • laravel public 目录获取
  • 如何在 Fork 的 GitHub 项目中保留自己的修改并同步上游更新?github_fork_update
  • 如何使用麦肯锡方法解决软件的BUG和运维管理?
  • 基于微信小程序的游泳馆管理系统--论文源码调试讲解
  • SSL证书选择指南:免费 vs 付费
  • 【vue2】v-scale-screen大屏自适应组件
  • QCustomPlot笔记(一)
  • 2024年9月python二级易错题和难题大全(附详细解析)(二)
  • android 14.0 Launcher3长按拖拽时,获取当前是哪一屏,获取当前多少个应用图标
  • Hugging Face NLP课程学习记录 - 2. 使用 Hugging Face Transformers
  • Canvas简历编辑器-Monorepo+Rspack工程实践
  • 使用PaddleNLP调用大模型ChatGLM3-6b进行信息抽取
  • Oracle事物
  • 线性代数之QR分解和SVD分解
  • ShouldSniffAttr在自动化测试中具体是如何应用?