如何在垂直Root Stack View右侧正确显示UIImageView
解决Root Stack View右侧UIImageView不显示的问题
你当前的代码存在两个核心问题导致图标无法正常显示:
- 重复添加视图:把
imageView同时加到了rootStack和dateInfoStackView两个不同的栈视图中,UIKit不允许同一个视图属于多个父视图,这会导致布局逻辑混乱。 - 布局结构错误:
rootStack设为垂直方向且对齐方式为leading,就算图标能显示也会挤在左侧,无法达到右侧显示的需求。
修正方案
重新构建布局结构:让rootStack采用水平方向,左侧放置一个垂直的contentStack来承载所有文本相关的子栈(保持原有文本垂直排列的结构),右侧单独放置imageView。这样既保留了文本区域的布局逻辑,又能让图标固定在单元格右侧。
修改后的完整代码
class UserCell: UIView { var rootStack = UIStackView() var contentStack = UIStackView() // 新增垂直栈,专门承载文本内容 var userInfoStackView = UIStackView() var subtitleStackView = UIStackView() var dateInfoStackView = UIStackView() var nameLabel = UILabel() var compCode = UILabel() var captionLabel = UILabel() var dateLabel2 = UILabel() var imageView = UIImageView() override init(frame: CGRect) { super.init(frame: frame) backgroundColor = .white setUpViews() addComponents() layoutComponents() } required init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func setUpViews(){ // 根栈改为水平方向,内容与图标居中对齐,设置间距 rootStack.translatesAutoresizingMaskIntoConstraints = false rootStack.axis = .horizontal rootStack.alignment = .center rootStack.spacing = 16 // 内容栈保持垂直方向,文本左对齐 contentStack.translatesAutoresizingMaskIntoConstraints = false contentStack.axis = .vertical contentStack.alignment = .leading contentStack.spacing = 3 subtitleStackView.translatesAutoresizingMaskIntoConstraints = false subtitleStackView.spacing = 2 dateInfoStackView.translatesAutoresizingMaskIntoConstraints = false dateInfoStackView.spacing = 2 nameLabel.font = UIFont.systemFont(ofSize: 20, weight: .bold) nameLabel.text = "Rolls Royce" compCode.font = UIFont.systemFont(ofSize: 20, weight: .semibold) compCode.text = "(RTYD8NTV001)" captionLabel.font = UIFont.systemFont(ofSize: 9, weight: .semibold) captionLabel.textColor = .darkGray captionLabel.text = "Best Customer Since 07/01/2019" dateLabel2.font = UIFont.systemFont(ofSize: 13, weight: .bold) dateLabel2.text = "July 2022" imageView.translatesAutoresizingMaskIntoConstraints = false imageView.image = UIImage(systemName: "print") imageView.tintColor = .black // 给SF Symbol设置颜色,避免透明无法显示 imageView.layer.cornerRadius = 20 imageView.clipsToBounds = true imageView.contentMode = .center // 确保图标居中显示 } private func addComponents() { // 组装文本子栈 userInfoStackView.addArrangedSubview(nameLabel) userInfoStackView.addArrangedSubview(compCode) subtitleStackView.addArrangedSubview(captionLabel) dateInfoStackView.addArrangedSubview(dateLabel2) // 将所有文本子栈加入内容栈 contentStack.addArrangedSubview(userInfoStackView) contentStack.addArrangedSubview(subtitleStackView) contentStack.addArrangedSubview(dateInfoStackView) // 根栈加入内容栈和图标 rootStack.addArrangedSubview(contentStack) rootStack.addArrangedSubview(imageView) addSubview(rootStack) } private func layoutComponents() { rootStack.snp.makeConstraints { (make) in // 给根栈添加内边距,优化布局美观度 make.edges.equalToSuperview().inset(UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16)) } imageView.snp.makeConstraints { (make) in make.width.height.equalTo(40) } } } let userCell = UserCell(frame: CGRect(x: 0, y: 0, width: 500, height: 60)) PlaygroundPage.current.liveView = userCell
关键修改点
- 新增
contentStack垂直栈,统一承载所有文本子视图,保留原有文本垂直排列的逻辑。 - 将
rootStack改为水平方向,左侧放置文本内容栈,右侧放置图标,通过spacing控制两者间距。 - 移除重复添加
imageView的代码,确保每个视图只有一个父视图。 - 给
imageView添加tintColor和contentMode,避免SF Symbol因默认透明或拉伸导致无法显示。 - 给
rootStack添加内边距,提升整体布局的美观度。
内容的提问来源于stack exchange,提问作者Alexander Paul
相关产品推荐
相关产品推荐

