2017-08-15 28 views
0

所以我想知道怎样才能用UIStackView做以下UI代码:UIStackView内的UITableViewCell

enter image description here

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

以下是我想出了类:

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 
    } 
} 

目前,它看起来像这样:

enter image description here

,如果我从我的UIStackView卸下底部的约束,它会是这样的:

enter image description here

上得到了如何UIStackView作品更好地理解并具有自动调整一个在UITableViewCell在UITableViewCell中使用UIStackView高度赞赏

+0

据我所知你只想调整和约束堆栈视图本身。要修改视图内部的视图,您需要使用堆栈视图方法。否则,只需使自定义视图包含堆叠视图并正常约束即可。 –

+0

乘数:100/image.size.height)图像高度有可能是0吗?与原始问题无关。 – Kibitz503

回答

0

一般来说,任何帮助是不是一个好主意。这可能会导致性能问题。但是如果你喜欢,你可以尝试在你配置它时调用你的单元格的layoutIfNeeded()方法(尤其是在设置单元格的图像视图后)。也许它会有所帮助。

+0

是的,试过这一个,它没有工作。特别是对于自动调整大小的单元格,使用简单的布局更容易。只是好奇,如果这样的行为可以实现和如何 – manman