UITableViewCell 内的 UIStackView
Posted
技术标签:
【中文标题】UITableViewCell 内的 UIStackView【英文标题】:UIStackView inside UITableViewCell 【发布时间】:2017-08-15 20:03:55 【问题描述】:所以我想看看如何在代码中使用UIStackView
:
请注意,图像可以隐藏,甚至可以具有不同的大小。图片唯一不变的是宽度。
以下是我想出的课程:
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
中自动调整大小的帮助
【问题讨论】:
据我所知,您只想调整和约束堆栈视图本身。要修改内部视图,您需要使用堆栈视图方法。否则,只需制作自定义视图以包含您的堆叠视图并正常约束。 multiplier: 100 / image.size.height) 图像高度是否可能永远为 0?与原始问题无关。 【参考方案1】:你的逻辑是什么样子的:
- (CGSize) collectionView:(UICollectionView *)collectionView
layout:(UICollectionViewLayout*)collectionViewLayout
sizeForItemAtIndexPath:(NSIndexPath *)indexPath
应该是……
抓取该索引路径的单元格 根据宽度确定单元格高度返回合适的高度
这里有一些很好的例子what is NSLayoutConstraint "UIView-Encapsulated-Layout-Height" and how should I go about forcing it to recalculate cleanly
【讨论】:
【参考方案2】:一般来说,在 UITableViewCell 中使用 UIStackView 并不是一个好主意。它可能会导致性能问题。但是,如果您愿意,可以在配置单元格时尝试调用单元格的 layoutIfNeeded() 方法(尤其是在设置单元格的图像视图之后)。也许会有所帮助。
【讨论】:
是的,试过了,但没有用。使用简单的布局要容易得多,尤其是对于自动调整单元格大小。只是好奇是否可以实现这种行为以及如何实现以上是关于UITableViewCell 内的 UIStackView的主要内容,如果未能解决你的问题,请参考以下文章
UITableViewCell 内的 UIView 上的 UIGestureRecognizer
UITableViewCell 内的 UIStackView
如何增加 UItableviewcell 内的 UItableview 高度?
捏放大到 UITableViewCell 内的 UIImageView
iOS - UITableViewCell 内的 UIScrollView 内的 UIView 未触发 UITapGestureRecognizer