在添加 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 中不起作用

两个或多个线程如何在它们分配的堆上共享内存?

修复:在 0.1.6 之前,libyaml 容易受到来自恶意 YAML 有效负载的堆溢出攻击

Windows OS下如何给Jenkins更多的堆空间