You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过代码调整主图片位置并在其下方添加3张小图片?

实现主图位置调整+下方3张小图的Auto Layout约束(代码实现)

我需要调整主图片的位置,并像第二张截图那样在其下方添加3张小图片,请问需要设置哪些Auto Layout约束?(通过代码实现)

当前界面
目标界面

原代码

import UIKit

class DetailsHomeViewController: UIViewController {
    
    
    let someImageView: UIImageView = {
           let theImageView = UIImageView()
           theImageView.image = UIImage(named: "t-shirt.png")
           theImageView.translatesAutoresizingMaskIntoConstraints = false
           return theImageView
        }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.addSubview(someImageView)
        
        someImageViewConstraints()
        

        view.backgroundColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
        setupViews()
    }
    
    private func setupViews() {
        createCustomNavigationBar()
        
        let RightButton = createCustomButton(
            imageName: "square.and.arrow.up",
            selector: #selector(RightButtonTapped)
        )
        
        let customTitleView = createCustomTitleView(
            detailsName: "Label"
        )
        
        navigationItem.rightBarButtonItems = [RightButton]
        navigationItem.titleView = customTitleView
    }
    
    
    func someImageViewConstraints() {
        someImageView.translatesAutoresizingMaskIntoConstraints = false
        someImageView.widthAnchor.constraint(equalToConstant: 340).isActive = true
        someImageView.heightAnchor.constraint(equalToConstant: 340).isActive = true
        someImageView.translatesAutoresizingMaskIntoConstraints = false
        someImageView.heightAnchor.constraint(equalToConstant: 80).isActive = true
        someImageView.widthAnchor.constraint(equalTo: someImageView.heightAnchor, multiplier: 16/9 ).isActive = true
           
        }
   
    
    @objc private func RightButtonTapped() {
        print("RightButtonTapped")
    }
    
}

解决方案

首先清理原代码的问题:someImageViewConstraints中重复设置translatesAutoresizingMaskIntoConstraints,且重复添加宽高约束会导致布局冲突,需要先删除这些无效代码。

接下来按以下步骤实现目标布局:

1. 定义所有图片控件与容器

用UIStackView管理三个小图,自动处理间距和排列逻辑:

// 主图
let mainImageView: UIImageView = {
    let iv = UIImageView()
    iv.image = UIImage(named: "t-shirt.png")
    iv.contentMode = .scaleAspectFit // 保持图片比例
    iv.translatesAutoresizingMaskIntoConstraints = false
    return iv
}()

// 三个小图
let smallImageView1: UIImageView = {
    let iv = UIImageView()
    iv.image = UIImage(named: "small1.png") // 替换为你的图片名
    iv.contentMode = .scaleAspectFit
    iv.translatesAutoresizingMaskIntoConstraints = false
    return iv
}()

let smallImageView2: UIImageView = {
    let iv = UIImageView()
    iv.image = UIImage(named: "small2.png")
    iv.contentMode = .scaleAspectFit
    iv.translatesAutoresizingMaskIntoConstraints = false
    return iv
}()

let smallImageView3: UIImageView = {
    let iv = UIImageView()
    iv.image = UIImage(named: "small3.png")
    iv.contentMode = .scaleAspectFit
    iv.translatesAutoresizingMaskIntoConstraints = false
    return iv
}()

// 小图容器StackView
let smallImagesStackView: UIStackView = {
    let stack = UIStackView()
    stack.axis = .horizontal // 水平排列
    stack.spacing = 16 // 小图间距
    stack.distribution = .fillEqually // 小图平分容器宽度
    stack.translatesAutoresizingMaskIntoConstraints = false
    return stack
}()

2. 在viewDidLoad中添加控件到视图

override func viewDidLoad() {
    super.viewDidLoad()
    view.backgroundColor = .white
    setupViews()
    
    // 添加主图到视图
    view.addSubview(mainImageView)
    // 将小图添加到StackView,再把StackView添加到视图
    smallImagesStackView.addArrangedSubview(smallImageView1)
    smallImagesStackView.addArrangedSubview(smallImageView2)
    smallImagesStackView.addArrangedSubview(smallImageView3)
    view.addSubview(smallImagesStackView)
    
    setupLayoutConstraints()
}

3. 设置Auto Layout约束

private func setupLayoutConstraints() {
    NSLayoutConstraint.activate([
        // 主图约束:顶部与导航栏下方安全区对齐,水平居中,宽度不超过视图90%,宽高比1:1
        mainImageView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
        mainImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
        mainImageView.widthAnchor.constraint(lessThanOrEqualTo: view.widthAnchor, multiplier: 0.9),
        mainImageView.heightAnchor.constraint(equalTo: mainImageView.widthAnchor, multiplier: 1.0),
        
        // 小图容器约束:顶部与主图底部间距20,水平居中,宽度与主图一致
        smallImagesStackView.topAnchor.constraint(equalTo: mainImageView.bottomAnchor, constant: 20),
        smallImagesStackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
        smallImagesStackView.widthAnchor.constraint(equalTo: mainImageView.widthAnchor),
        
        // 单个小图宽高比约束(可根据需求调整比例)
        smallImageView1.heightAnchor.constraint(equalTo: smallImageView1.widthAnchor, multiplier: 0.8),
        smallImageView2.heightAnchor.constraint(equalTo: smallImageView2.widthAnchor, multiplier: 0.8),
        smallImageView3.heightAnchor.constraint(equalTo: smallImageView3.widthAnchor, multiplier: 0.8)
    ])
}

约束说明

  • 主图:
    • 顶部绑定安全区,避免被导航栏遮挡
    • 水平居中保证视觉平衡
    • 宽度限制为视图90%,适配不同屏幕尺寸
    • 宽高比1:1确保图片不变形
  • 小图容器:
    • 与主图保持固定间距,形成上下层级布局
    • 和主图宽度一致,保持布局统一性
  • 小图:
    • 通过StackView的fillEqually自动平分宽度,再用宽高比约束控制高度,保证小图比例统一

完整可运行代码

import UIKit

class DetailsHomeViewController: UIViewController {
    
    // 主图
    let mainImageView: UIImageView = {
        let iv = UIImageView()
        iv.image = UIImage(named: "t-shirt.png")
        iv.contentMode = .scaleAspectFit
        iv.translatesAutoresizingMaskIntoConstraints = false
        return iv
    }()
    
    // 三个小图
    let smallImageView1: UIImageView = {
        let iv = UIImageView()
        iv.image = UIImage(named: "small1.png")
        iv.contentMode = .scaleAspectFit
        iv.translatesAutoresizingMaskIntoConstraints = false
        return iv
    }()
    
    let smallImageView2: UIImageView = {
        let iv = UIImageView()
        iv.image = UIImage(named: "small2.png")
        iv.contentMode = .scaleAspectFit
        iv.translatesAutoresizingMaskIntoConstraints = false
        return iv
    }()
    
    let smallImageView3: UIImageView = {
        let iv = UIImageView()
        iv.image = UIImage(named: "small3.png")
        iv.contentMode = .scaleAspectFit
        iv.translatesAutoresizingMaskIntoConstraints = false
        return iv
    }()
    
    // 小图容器StackView
    let smallImagesStackView: UIStackView = {
        let stack = UIStackView()
        stack.axis = .horizontal
        stack.spacing = 16
        stack.distribution = .fillEqually
        stack.translatesAutoresizingMaskIntoConstraints = false
        return stack
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = .white
        setupViews()
        
        // 添加控件到视图
        view.addSubview(mainImageView)
        smallImagesStackView.addArrangedSubview(smallImageView1)
        smallImagesStackView.addArrangedSubview(smallImageView2)
        smallImagesStackView.addArrangedSubview(smallImageView3)
        view.addSubview(smallImagesStackView)
        
        setupLayoutConstraints()
    }
    
    private func setupViews() {
        createCustomNavigationBar()
        
        let rightButton = createCustomButton(
            imageName: "square.and.arrow.up",
            selector: #selector(rightButtonTapped)
        )
        
        let customTitleView = createCustomTitleView(
            detailsName: "Label"
        )
        
        navigationItem.rightBarButtonItems = [rightButton]
        navigationItem.titleView = customTitleView
    }
    
    private func setupLayoutConstraints() {
        NSLayoutConstraint.activate([
            // 主图约束
            mainImageView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20),
            mainImageView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            mainImageView.widthAnchor.constraint(lessThanOrEqualTo: view.widthAnchor, multiplier: 0.9),
            mainImageView.heightAnchor.constraint(equalTo: mainImageView.widthAnchor, multiplier: 1.0),
            
            // 小图容器约束
            smallImagesStackView.topAnchor.constraint(equalTo: mainImageView.bottomAnchor, constant: 20),
            smallImagesStackView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            smallImagesStackView.widthAnchor.constraint(equalTo: mainImageView.widthAnchor),
            
            // 小图宽高比约束
            smallImageView1.heightAnchor.constraint(equalTo: smallImageView1.widthAnchor, multiplier: 0.8),
            smallImageView2.heightAnchor.constraint(equalTo: smallImageView2.widthAnchor, multiplier: 0.8),
            smallImageView3.heightAnchor.constraint(equalTo: smallImageView3.widthAnchor, multiplier: 0.8)
        ])
    }
    
    @objc private func rightButtonTapped() {
        print("RightButtonTapped")
    }
    
    // 补充原有的自定义方法实现
    private func createCustomNavigationBar() {
        // 你的自定义导航栏逻辑
    }
    
    private func createCustomButton(imageName: String, selector: Selector) -> UIBarButtonItem {
        let button = UIButton(type: .system)
        button.setImage(UIImage(systemName: imageName), for: .normal)
        button.addTarget(self, action: selector, for: .touchUpInside)
        return UIBarButtonItem(customView: button)
    }
    
    private func createCustomTitleView(detailsName: String) -> UIView {
        let titleLabel = UILabel()
        titleLabel.text = detailsName
        titleLabel.font = UIFont.systemFont(ofSize: 17, weight: .semibold)
        return titleLabel
    }
}

内容的提问来源于stack exchange,提问作者Captain Grimm

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 19:09:32