Ios UIStackView内部UITableViewCell

Ios UIStackView内部UITableViewCell,ios,uitableview,uistackview,Ios,Uitableview,Uistackview,因此,我试图通过使用UIStackView,了解如何在代码中实现以下ui: 请注意,图像可以隐藏,甚至可以具有不同的大小。图像唯一不变的是宽度 以下是我想到的课程: public class MenuItemTableViewCell: UITableViewCell { //MARK: UI elements var titleLabel = UILabel() var detailsLabel = UILabel() var itemImageView =

因此,我试图通过使用
UIStackView
,了解如何在代码中实现以下ui:

请注意,图像可以隐藏,甚至可以具有不同的大小。图像唯一不变的是宽度

以下是我想到的课程:

public class MenuItemTableViewCell: UITableViewCell {

    //MARK: UI elements
    var titleLabel = UILabel()
    var detailsLabel = UILabel()
    var itemImageView = UIImageView()
    var mainStackView = UIStackView()

    //MARK: Variables
    var menuItem: MenuItem? {
        didSet {
            if let item = menuItem {
                titleLabel.text = item.name
                detailsLabel.text = item.itemDescription
                if let imageURL = item.imageURL {
                    itemImageView.af_setImage(withURL: imageURL) { [weak self] response in

                        guard let imageView = self?.itemImageView else {
                            return
                        }

                        switch response.result {
                        case .success(let image):

                            // Instance variable:
                            var imageAspectRatioConstraint: NSLayoutConstraint?

                            // When you set the image:
                            imageAspectRatioConstraint?.isActive = false
                            imageAspectRatioConstraint = imageView.heightAnchor.constraint(
                                equalTo: imageView.widthAnchor,
                                multiplier: 100 / image.size.height)
                            imageAspectRatioConstraint!.isActive = true
                        default:
                            return
                        }
                    }
                } else {
                    itemImageView.isHidden = true
                }
            } else {
                titleLabel.text = ""
                detailsLabel.text = ""
                itemImageView.image = nil
            }
        }
    }

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        initViews()
    }

    required public init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }


    private func initViews() {
        self.accessoryType = .disclosureIndicator
        self.selectionStyle = .none

        setupMainStackView()
        setupTitleLabel()
        setupDetailLabel()
        setupItemImageViewLabel()
    }

    //MARK: Components setup
    private func setupMainStackView() {
        mainStackView.alignment = .fill
        mainStackView.distribution = .fillProportionally
        mainStackView.spacing = 5
        mainStackView.axis = .vertical
        mainStackView.translatesAutoresizingMaskIntoConstraints = false
        mainStackView.layoutMargins = UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10)
        mainStackView.isLayoutMarginsRelativeArrangement = true
        mainStackView.setContentCompressionResistancePriority(UILayoutPriorityRequired, for: .vertical)
        mainStackView.distribution = .fillProportionally
        self.contentView.addSubview(mainStackView)

        addMainStackViewContraints()
    }

    //
    // Title Label
    //
    private func setupTitleLabel() {

        titleLabel.textColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
        titleLabel.numberOfLines = 1
        mainStackView.addArrangedSubview(titleLabel)

        addTitleLabelConstraints()
    }

    //
    // Detail Label
    //
    private func setupDetailLabel() {
        detailsLabel.textColor = #colorLiteral(red: 0.501960814, green: 0.501960814, blue: 0.501960814, alpha: 1)

        detailsLabel.setContentHuggingPriority(UILayoutPriorityRequired, for: .vertical)
        detailsLabel.numberOfLines = 2
        mainStackView.addArrangedSubview(detailsLabel)

        addDetailsLabelContraints()
    }

    //
    // Item Image
    //
    private func setupItemImageViewLabel() {
        itemImageView.contentMode = .scaleAspectFit
        itemImageView.clipsToBounds = true
        mainStackView.addArrangedSubview(itemImageView)

        addItemImageViewConstraitns()
    }

    //MARK: Constraints setup
    private func addTitleLabelConstraints() {
        titleLabel.translatesAutoresizingMaskIntoConstraints = false

        titleLabel.setContentCompressionResistancePriority(UILayoutPriorityRequired, for: .vertical)
        titleLabel.setContentHuggingPriority(UILayoutPriorityRequired, for: .vertical)
    }

    func addDetailsLabelContraints() {
        detailsLabel.translatesAutoresizingMaskIntoConstraints = false

        detailsLabel.setContentCompressionResistancePriority(UILayoutPriorityRequired, for: .vertical)
        detailsLabel.setContentHuggingPriority(UILayoutPriorityRequired, for: .vertical)
    }

    func addItemImageViewConstraitns() {
        itemImageView.translatesAutoresizingMaskIntoConstraints = false
        itemImageView.widthAnchor.constraint(equalTo: mainStackView.widthAnchor).isActive = true
        itemImageView.leftAnchor.constraint(equalTo: mainStackView.leftAnchor).isActive = true
    }

    private func addMainStackViewContraints() {
        mainStackView.topAnchor.constraint(equalTo: self.contentView.topAnchor).isActive = true
        mainStackView.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor).isActive = true
        mainStackView.leftAnchor.constraint(equalTo: self.contentView.leftAnchor).isActive = true
        mainStackView.rightAnchor.constraint(equalTo: self.contentView.rightAnchor).isActive = true
    }
}
现在看起来是这样的:

如果我从我的
UIStackView
中删除底部约束,它将如下所示:


如果您能更好地了解
UIStackView
的工作原理,并在
UITableViewCell
中自动调整大小,我们将不胜感激。

一般来说,在UITableViewCell中使用UIStackView不是一个好主意。这可能会导致性能问题。但是,如果您愿意,可以在配置单元时尝试调用单元的layoutIfNeeded()方法(特别是在设置单元的图像视图之后)。也许会有帮助。

你的逻辑是什么样的:

- (CGSize) collectionView:(UICollectionView *)collectionView
                   layout:(UICollectionViewLayout*)collectionViewLayout
   sizeForItemAtIndexPath:(NSIndexPath *)indexPath
应该是

  • 获取此索引路径的单元格
  • 根据宽度确定单元格高度
  • 返回适当的高度

    这里有一些很好的例子


据我所知,您只想调整堆栈视图本身的大小并对其进行约束。要修改内部视图,需要使用堆栈视图方法。否则,只需将自定义视图设置为包含堆叠视图并正常约束即可。乘数:100/image.size.height)图像高度是否可能为0?与原来的问题无关。是的,我试过了,但没用。使用简单布局更容易,尤其是对于自动调整单元格大小。我只是好奇这样的行为是否能够实现,以及如何实现