2017-08-15 31 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