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

devtools/2024/9/23 4:42:14/

歌单详情完整效果

歌单详情歌单列表效果

歌单详情列表页整体效果稍微有点复杂,我们进行分部实现,先实现歌单详情里面的歌单列表,使用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 TangramKitclass SongItemCell: BaseTableViewCell {override func initViews() {super.initViews()container.tg_space = 0container.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_SMALLcontainer.addSubview(rightContainer)//标题rightContainer.addSubview(self.titleView)//信息容器let infoContainer = TGLinearLayout(.horz)infoContainer.tg_width.equal(.fill)infoContainer.tg_height.equal(.wrap)infoContainer.tg_space = PADDING_SMALLrightContainer.addSubview(infoContainer)infoContainer.addSubview(self.downloadedView)infoContainer.addSubview(self.infoView)//更多按钮let moreButton = ViewFactoryUtil.button(image:R.image.moreVerticalDot()!.withTintColor())moreButton.tintColor = .black80moreButton.tg_width.equal(50)moreButton.tg_height.equal(50)container.addSubview(moreButton)}func bind(_ data:Song) {titleView.text = data.titleinfoView.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 = 1result.font = UIFont.systemFont(ofSize: TEXT_LARGE)result.textColor = .black80return result}()lazy var titleView: UILabel = {let r = UILabel()r.tg_width.equal(.fill)r.tg_height.equal(.wrap)r.numberOfLines = 1r.font = UIFont.systemFont(ofSize: TEXT_LARGE)r.textColor = .colorOnSurfacereturn r}()lazy var downloadedView: UIImageView = {let r = UIImageView()r.tg_width.equal(.wrap)r.tg_height.equal(.wrap)r.tg_visibility = .goner.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 = 1r.font = UIFont.systemFont(ofSize: TEXT_MEDDLE)r.textColor = .black80return r}()
}
//
//  BaseTableViewCell.swift
//  通用TableViewCell
//
//  Created by jin on 2024/8/27.
//import UIKit//提供类似Android中更高层级布局框架
import TangramKitclass 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 = .clearcontentView.backgroundColor = .clear//去掉默认的选中颜色selectionStyle = .none//根容器container = TGLinearLayout(getContainerOrientation())container.tg_width.equal(.fill)container.tg_height.equal(.wrap)container.tg_space = PADDING_MEDDLEcontentView.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 HandyJSONclass 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? = niloverride 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 inself?.show(data.data!)}.disposed(by: rx.disposeBag)}func show(_ data: Sheet) {self.data = datadatum = 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! Songlet cell = tableView.dequeueReusableCell(withIdentifier: Constant.CELL, for: indexPath) as! SongItemCellcell.bind(data)cell.indexView.text = "\(indexPath.row + 1)"return cell}
}

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


http://www.ppmy.cn/devtools/115814.html

相关文章

零工市场小程序:推动零工市场建设

人力资源和社会保障部在2024年4月发布了标题为《地方推进零工市场建设经验做法》的文章。 零工市场小程序的功能 信息登记与发布 精准匹配、推送 在线沟通 权益保障 零工市场小程序作为一个找零工的渠道&#xff0c;在往后随着技术的发展和政策的支持下&#xff0c;功能必然…

linux下的日志编写

1、日志初始化创建 2、日志写入 3、日志关闭 log.c #include "log.h"static log_t LOG;//初始化日志文件&#xff0c;在当前目录创建日志文件 int log_init(char *pdirname) {time_t t;struct tm *ptm NULL;char filepath[64] {0};int ret 0;time(&t);ptm …

网络编程问题解答

TCP/IP是哪种模型的协议 TCP/IP 是一组通信协议的集合&#xff0c;它基于 TCP/IP 模型。TCP/IP 模型通常被认为是一种实用的网络通信模型&#xff0c;与 OSI 模型相比&#xff0c;TCP/IP 模型更加简洁和侧重于实际应用&#xff0c;被广泛应用于互联网和大多数计算机网络中。 T…

CertiK因发现Apple Vision Pro眼动追踪技术漏洞,第6次获苹果认可

​2024年9月20日&#xff0c;头部Web3.0安全机构CertiK自豪地宣布&#xff0c;CertiK的工程师因发现Apple Vision Pro MR&#xff08;混合现实&#xff09;头显设备中的关键漏洞而获得Apple公司认可&#xff0c;这已经是Apple公司第六次公开发布对CertiK的致谢&#xff0c;Cert…

24年 九月 刷题记录

1. leetcode997找到小镇的法官 小镇里有 n 个人&#xff0c;按从 1 到 n 的顺序编号。传言称&#xff0c;这些人中有一个暗地里是小镇法官。 如果小镇法官真的存在&#xff0c;那么&#xff1a; 小镇法官不会信任任何人。 每个人&#xff08;除了小镇法官&#xff09;都信任这…

Qt安卓开发连接手机调试(红米K60为例)

1.前置条件 本人默认您已经完成Qt安卓环境的配置&#xff0c;若还没配置请参考链接文章&#xff1a;【Qt】最详细教程&#xff0c;如何从零配置Qt Android安卓环境_qt_七夕先生-开放原子开发者工作坊。准备一台目前主流在用的手机&#xff0c;其实自己用的就行(只要你不是某些…

光控资本:沪指涨0.59%,酿酒板块大幅拉升,数字货币概念等活跃

19日早盘&#xff0c;两市首要指数全线拉升&#xff0c;深证成指、创业板指涨约1%&#xff1b;场内超4800股飘红。 截至午间收盘&#xff0c;沪指涨0.59%报2733.38点&#xff0c;深证成指涨1.25%&#xff0c;创业板指涨0.99%&#xff0c;两市估计成交4263亿元。 盘面上看&…

Selenium点击元素的方法

前言 点击方法在web自动化测试中经常用到&#xff0c;下面就来介绍一下selenium常用和不常用的点击方法&#xff1b; 1、常用方法 1.1、使用 click() 方法&#xff1a; 这是最简单和最常用的方法。通过选中要点击的元素&#xff0c;然后使用 click() 方法来触发点击事件。 …