【问题标题】:UILabel disappears in StackView when there is too much content内容过多时UILabel在StackView中消失
【发布时间】:2021-08-14 06:27:23
【问题描述】:

我有一个 UIStackView,其中包含三个子视图:标题 (UILabel)、正文 (UILabel) 和帖子图像 (UIImageView)。仅当帖子具有 imageURL 时才添加最后一张图片(这是可选的。)

看下面,你可以看到当我显示图像时,UILabel 不知何故从 stackView 中消失了。我该如何解决这个问题?

附:展望未来,当用户从缺少 imageViewURLs 的帖子滚动时,我将要删除 imageViews。关于如何在此处进行的任何提示?再次提前感谢您。

下面是相关代码:

class FeedTableViewCell: UITableViewCell {
//MARK: Public properties
var post: Post?{
    didSet{
        guard let post = post else {return}

        // Adding user's name
        let attributedText = NSMutableAttributedString(string: post.author.name + " → " + post.group.name, attributes: [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 14)])

        // Adding date and user's first name
        let dateFormatter = PostDateFormatter()
        dateFormatter.dateStyle = .long
        dateFormatter.timeStyle = .short
        attributedText.append(NSAttributedString(string: "\n" + dateFormatter.string(from: post.createdAt), attributes: [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 12), NSAttributedString.Key.foregroundColor: UIColor(r: 155/255, g: 161/255, b: 171/255)]))

        // Increasing Spacing
        let paragraphStyle = NSMutableParagraphStyle()
        paragraphStyle.lineSpacing = 4
        attributedText.addAttribute(NSAttributedString.Key.paragraphStyle, value: paragraphStyle, range: NSMakeRange(0, attributedText.length))

        titleLabel.attributedText = attributedText

        // Setting profile image
        iconImageView.setImage(for: post.author, setContentMode: .scaleAspectFit)

        messageTextView.text = post.content

        setupImageSubviews()
    }
}

//MARK: Private implementation
private let iconImageView = CircleImageView(size: 44)

private let titleLabel: UILabel = {
    let label = UILabel()
    label.numberOfLines = 0
    label.font = UIFont.systemFont(ofSize: 14)
    label.textColor = .black
    label.translatesAutoresizingMaskIntoConstraints = false
    return label
}()

private let messageTextView: UILabel = {
    let labelView = UILabel()
    labelView.numberOfLines = 0
    labelView.font = UIFont.systemFont(ofSize: 14)
    labelView.translatesAutoresizingMaskIntoConstraints = false
    return labelView
}()

override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
    super.init(style: style, reuseIdentifier: reuseIdentifier)
    setupDefaultViews()

}

required init?(coder: NSCoder) {
    fatalError("init(coder:) has not been implemented")

}

var stackView = UIStackView()

func setupDefaultViews(){
    backgroundColor = UIColor.white

    stackView.addArrangedSubview(titleLabel)
    stackView.addArrangedSubview(messageTextView)

    contentView.addSubview(iconImageView)
    contentView.addSubview(stackView)

    iconImageView.anchor(top: contentView.topAnchor, leading: contentView.leadingAnchor, bottom: nil, trailing: nil, padding: .init(top: 0, left: 8, bottom: 0, right: 0), size: CGSize(width: 44, height: 44))

    stackView.anchor(top: contentView.topAnchor, leading: iconImageView.trailingAnchor, bottom: contentView.bottomAnchor, trailing: contentView.trailingAnchor, padding: .init(top: 0, left: 8, bottom: 8, right: 8))
    stackView.axis = .vertical
}

private func setupImageSubviews() {

    guard let imageURL = post?.imageURL else {return} // if no image exists, return, preventing image view from taking extra memory and performance to initialize and calculate constraints

    // initialize here instead of globally, so it doesnt take extra memory holding this when no image exists.
    let messageImageView: UIImageView = {
        let imageView = UIImageView()
        let contentImage = UIImage(systemName: "person.crop.circle.fill")!.withTintColor(.gray).withRenderingMode(.alwaysOriginal)
        imageView.kf.setImage(with: imageURL, placeholder: contentImage)
        imageView.contentMode = .scaleAspectFill
        imageView.layer.masksToBounds = true
        imageView.layer.borderWidth = 1
        imageView.translatesAutoresizingMaskIntoConstraints = false
        return imageView
    }()

    stackView.addArrangedSubview(messageImageView)
}}

【问题讨论】:

  • 使用视图调试器查看视图发生了什么。
  • 如果您要更改单元格的大小 已显示,您必须告诉表格视图更新布局。要么重新加载行,要么调用performBatchUpdates()
  • 所以我设法通过改变我的方法解决了这个问题(使用这个优秀的帖子:stackoverflow.com/questions/18746929/…)。但是,我仍然遇到如上所示压缩图像的问题,直到我开始滚动,此时行调整大小以适应内容。在单元格中设置图像后我会执行BatchUpdates 吗?

标签: swift autolayout stackview


【解决方案1】:

为了让人们知道我是如何解决这个问题的,我试图使用一个单元格模板来处理两种不同类型的单元格。这是一个错误,而是使用此linkUsing Auto Layout in UITableView for dynamic cell layouts & variable row heights 中的信息来正确创建两个单元格模板。我还发现这段代码可以保证单元格正确显示标题:

    // Keeps the title text always showing
override func didMoveToSuperview() {
    super.didMoveToSuperview()
    layoutIfNeeded()
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-09
    • 1970-01-01
    • 2012-07-03
    • 1970-01-01
    • 2017-02-21
    • 2020-01-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多