使用Kingfisher加载网络图片时使用indicatorType产生布局混乱
SheetInfoCell代码中,执行iconView.show(info.picurl) 时,若采用kf.indicatorType = .activity,则会产生ui页面混乱,如果不使用这个加载动画,则不会产生。
与此同时,对于发现页面,是否使用加载动画,则都不会产生ui混乱。
对于SheetInfoCell ,产生bug的具体表现为,BaseTableViewCell 中创建的container 的高度 在设置其高度自适应并且重写了自动计算高度的情况下,大于其父视图contentView。
父视图contentView的高度始终为 44 。
//
// SheetInfoCell.swift
// myMusic
// 歌单详情 歌单信息cell
// Created by Unlimited_z on 2025/3/4.
//
import UIKit
import TangramKit
class SheetInfoCell: BaseTableViewCell {
static let NAME = "SheetInfoCell"
var iconView:UIImageView!
override func initViews() {
super.initViews()
container.tg_padding = UIEdgeInsets(top: PADDING_OUTER, left: PADDING_OUTER, bottom: PADDING_LARGE2, right: PADDING_OUTER)
container.tg_space = PADDING_LARGE2
container.tg_height.equal(300)
container.backgroundColor = .clear
//水平容器
let orientationContainer = ViewFactoryUtil.orientationContainer()
orientationContainer.tg_space = PADDING_OUTER
orientationContainer.tg_gravity = TGGravity.vert.center
orientationContainer.tg_padding = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: PADDING_SMALL)
container.addSubview(orientationContainer)
//图标
iconView = UIImageView()
iconView.tg_width.equal(120)
iconView.tg_height.equal(120)
iconView.clipsToBounds = true
iconView.image = R.image.placeholder()
iconView.smallCorner()
iconView.contentMode = .scaleAspectFill
orientationContainer.addSubview(iconView)
//右侧容器
let rightContainer = TGLinearLayout(.vert)
rightContainer.tg_width.equal(.fill)
rightContainer.tg_height.equal(.wrap)
rightContainer.tg_space = PADDING_SMALL
orientationContainer.addSubview(rightContainer)
//标题
rightContainer.addSubview(self.titleView)
//用户容器
let userContainer = ViewFactoryUtil.orientationContainer()
userContainer.tg_space = PADDING_SMALL
userContainer.tg_gravity = TGGravity.vert.center
rightContainer.addSubview(userContainer)
userContainer.addSubview(self.avatarView)
userContainer.addSubview(self.nicknameView)
//详情容器
let detailContainer = ViewFactoryUtil.orientationContainer()
//类似paddingTop
detailContainer.tg_top.equal(PADDING_MEDDLE)
detailContainer.tg_space = PADDING_SMALL
userContainer.tg_gravity = TGGravity.vert.center
rightContainer.addSubview(detailContainer)
detailContainer.addSubview(self.detailView)
detailContainer.addSubview(ViewFactoryUtil.moreIconView())
//快捷按钮容器
let buttonContainer = ViewFactoryUtil.orientationContainer()
buttonContainer.corner(23)
buttonContainer.tg_horzMargin(PADDING_LARGE2)
buttonContainer.tg_height.equal(46)
container.addSubview(buttonContainer)
buttonContainer.addSubview(self.collectCountView)
buttonContainer.addSubview(ViewFactoryUtil.smallVerticalDivider())
buttonContainer.addSubview(self.commentCountView)
buttonContainer.addSubview(ViewFactoryUtil.smallVerticalDivider())
buttonContainer.addSubview(self.shareCountView)
}
func bind(_ data: PlaylistInfo) {
let info = data
iconView.show(info.picurl)
titleView.text = info.title
// 创建者信息
if let creator = info.creator {
// avatarView.show(creator.headurl)
nicknameView.text = creator.nick
}
detailView.text = info.desc
// 由于 MusicResponse 没有这些计数,可以显示歌曲数量
collectCountView.setTitle("\(info.songnum)", for: .normal)
commentCountView.setTitle("0", for: .normal) // 或者隐藏
}
override func getContainerOrientation() -> TGOrientation {
return .vert
}
lazy var titleView: UILabel = {
let r = UILabel()
r.tg_width.equal(.fill)
r.tg_height.equal(.wrap)
r.numberOfLines = 2
r.font = UIFont.systemFont(ofSize: TEXT_LARGE2)
r.textColor = .white
return r
}()
lazy var avatarView: UIImageView = {
let r = UIImageView()
r.tg_width.equal(30)
r.tg_height.equal(30)
r.contentMode = .scaleAspectFill
r.smallCorner()
return r
}()
lazy var nicknameView: UILabel = {
let r = UILabel()
r.tg_width.equal(.wrap)
r.tg_height.equal(.wrap)
r.numberOfLines = 1
r.font = UIFont.systemFont(ofSize: TEXT_MEDDLE)
r.textColor = .white
return r
}()
lazy var detailView: UILabel = {
let r = UILabel()
r.tg_width.equal(160)
r.tg_height.equal(.wrap)
r.numberOfLines = 1
r.font = UIFont.systemFont(ofSize: TEXT_MEDDLE)
r.textColor = .white
return r
}()
lazy var collectCountView: QMUIButton = {
let r = ViewFactoryUtil.secoundButton(icon: R.image.search()!, title: "0")
r.backgroundColor = .white
return r
}()
lazy var commentCountView: QMUIButton = {
let r = ViewFactoryUtil.secoundButton(icon: R.image.search()!, title: "0")
r.backgroundColor = .white
return r
}()
lazy var shareCountView: QMUIButton = {
let r = ViewFactoryUtil.secoundButton(icon: R.image.search()!, title: "0")
r.backgroundColor = .white
return r
}()
}
//
// File.swift
// myMusic
// Kingfisher显示图片扩展
// Created by Unlimited_z on 2025/3/5.
//
import UIKit
//图片加载
import Kingfisher
extension UIImageView{
/// 显示头像
/// - Parameter data: <#data description#>
func showAvatar(_ data:String?) {
show(data, "DefaultAvatar")
}
/// 显示网络图片
/// - Parameters:
/// - view: <#view description#>
/// - data: <#data description#>
/// - defaultRes: <#defaultRes description#>
func show(_ data:String?,_ defaultImage:String="Placeholder") {
if SuperStringUtil.isBlank(data) {
//空
//显示默认图片
image = UIImage(named: defaultImage)
} else {
var newData:String!
if data!.starts(with: "http") {
newData = data
} else {
newData = data?.absoluteUri()
}
showFull(newData)
}
}
/// 显示绝对路径
/// - Parameter data: <#data description#>
func showFull(_ data: String) {
// kf.indicatorType = .activity
kf.setImage(with: URL(string: data))
}
/// 显示本地图片
/// - Parameters:
/// - view: <#view description#>
/// - data: <#data description#>
/// - defaultRes: <#defaultRes description#>
func showLocal(_ data: String?, _ defaultImage: String = "Placeholder") {
if (SuperStringUtil.isBlank(data)) {
//空
//显示默认图片
self.image = UIImage(named: defaultImage)
} else {
kf.indicatorType = .activity
let url = URL(fileURLWithPath: data!)
let provider = LocalFileImageDataProvider(fileURL: url)
kf.setImage(with: provider)
}
}
}
//
// BaseTableViewCell.swift
// myMusic
// 简化自定义单元格的开发流程
// Created by Unlimited_z on 2025/2/17.
//
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 {
// let size = container.systemLayoutSizeFitting(targetSize)
// print("Calculated size: \(size)") // 方便调试
return self.container.systemLayoutSizeFitting(targetSize)
}
}