在添加 LinkPresentation 视图的堆栈上重用单元格时不显示元素
Posted
技术标签:
【中文标题】在添加 LinkPresentation 视图的堆栈上重用单元格时不显示元素【英文标题】:Cell not displaying elements when being reused on a stack that adds a LinkPresentation view 【发布时间】:2020-09-09 12:06:19 【问题描述】:在我为元数据引入 LinkView
在我引入 LinkView 后,由于它位于 stackView 内,因此在准备可重用时我必须从 superview 中删除 linkView(不知道为什么要尝试重绘布局,但似乎这不适用于 LinkView)向下滚动时会出现问题元素,似乎数据在某些时候丢失了,奇怪的是它只发生在包含 linkView 项目的可重用元素上,这有什么原因吗?我该如何解决?
这是我用于单元格的代码
final class TimeLineTableViewCell: UITableViewCell
var cornerRadius: CGFloat = 6
var shadowOffsetWidth = 0
var shadowOffsetHeight = 3
var shadowColor: UIColor = .gray
var shadowOpacity: Float = 0.3
lazy var containerView: UIView =
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = .white
view.addSubview(stackViewContainer)
let shadowPath = UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius)
view.layer.cornerRadius = cornerRadius
view.clipsToBounds = true
view.layer.masksToBounds = false
view.layer.shadowColor = shadowColor.cgColor
view.layer.shadowOffset = CGSize(width: shadowOffsetWidth, height: shadowOffsetHeight);
view.layer.shadowOpacity = shadowOpacity
view.layer.shadowPath = shadowPath.cgPath
return view
()
lazy var stackViewContainer: UIStackView =
let stack = UIStackView()
stack.axis = .horizontal
stack.alignment = .center
stack.translatesAutoresizingMaskIntoConstraints = false
stack.distribution = .fill
stack.spacing = 10.0
stack.addArrangedSubview(profileImage)
stack.addArrangedSubview(stackViewDataHolder)
return stack
()
lazy var profileImage: UIImageView =
let image = UIImage()
let imageView = UIImageView(image: image)
imageView.translatesAutoresizingMaskIntoConstraints = false
imageView.contentMode = .scaleAspectFit
return imageView
()
lazy var userName: UILabel =
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
return label
()
lazy var tweetInfo: UILabel =
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
return label
()
lazy var tweetText: UILabel =
let label = UILabel()
label.translatesAutoresizingMaskIntoConstraints = false
label.numberOfLines = 0
return label
()
lazy var linkView: LPLinkView =
let viewer = LPLinkView(frame: CGRect(origin: .zero, size: .init(width: 200, height: 20)))
viewer.translatesAutoresizingMaskIntoConstraints = false
return viewer
()
lazy var stackViewDataHolder: UIStackView =
let stack = UIStackView()
stack.axis = .vertical
stack.translatesAutoresizingMaskIntoConstraints = false
stack.distribution = .fillProportionally
stack.addArrangedSubview(userName)
stack.addArrangedSubview(tweetInfo)
stack.addArrangedSubview(tweetText)
return stack
()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?)
super.init(style: style, reuseIdentifier: reuseIdentifier)
commonInit()
required init?(coder: NSCoder)
super.init(coder: coder)
commonInit()
override func prepareForReuse()
linkView.removeFromSuperview()
func configure(viewModel: ProfileTweetViewModel)
tweetInfo.configure(model: viewModel.tweetInfo)
userName.configure(model: viewModel.name)
tweetText.configure(model: viewModel.tweet)
if let metadata = viewModel.linkData
linkView = LPLinkView(metadata: metadata)
stackViewDataHolder.addArrangedSubview(linkView)
//Tried almost all layoyt options but seems a previous view can't be updated since frame is wrong
if let url = viewModel.profilePic
profileImage.downloadImage(from: url)
private extension TimeLineTableViewCell
struct Metrics
static let lateralPadding: CGFloat = 8
func constraints()
NSLayoutConstraint.activate([
stackViewContainer.topAnchor.constraint(equalTo: containerView.topAnchor, constant: Metrics.lateralPadding),
stackViewContainer.bottomAnchor.constraint(equalTo: containerView.bottomAnchor, constant: -Metrics.lateralPadding),
stackViewContainer.leadingAnchor.constraint(equalTo: containerView.leadingAnchor, constant: Metrics.lateralPadding),
stackViewContainer.trailingAnchor.constraint(equalTo: containerView.trailingAnchor, constant: -Metrics.lateralPadding),
profileImage.heightAnchor.constraint(equalTo: profileImage.widthAnchor, multiplier: 1.0),
profileImage.widthAnchor.constraint(equalToConstant: 50.0),
])
func commonInit()
addSubview(containerView)
backgroundColor = .clear
NSLayoutConstraint.activate([
containerView.topAnchor.constraint(equalTo: topAnchor),
containerView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 4),
containerView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -4),
containerView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -4),
])
constraints()
感谢您的宝贵时间。
【问题讨论】:
【参考方案1】:该问题与 stackView 中的 .fillProportionally
有关
由于 linkView 有时会以 0 高度呈现,因此我只需要在 stackView 中使用 .fill
属性即可完全显示它
【讨论】:
以上是关于在添加 LinkPresentation 视图的堆栈上重用单元格时不显示元素的主要内容,如果未能解决你的问题,请参考以下文章
Xcode 13 dyld:库未加载:/System/Library/Frameworks/LinkPresentation.framework/LinkPresentation
如何使用 LinkPresentation 在 SwiftUI 中获取链接元数据?
LPLinkView backgroundColor 在 iOS 中不起作用