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

Swift iOS:通过代码创建基于UIButton与约束的响应式顶部菜单

Hey there, let's build this responsive button layout that behaves just like Bootstrap's grid—adapting to orientation changes and button text length. Here's a complete, clean implementation using Swift and Auto Layout:

Step-by-Step Implementation

1. Define Constants & Setup Base Views

First, we'll set up reusable constants and core views (a top container and a stack view to handle the responsive button layout):

class ViewController: UIViewController {
    // Button titles array
    private let buttonTitles = ["one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten"]
    // Padding inside each button
    private let buttonContentInsets = UIEdgeInsets(top: 8, left: 16, bottom: 8, right: 16)
    // Spacing between buttons
    private let buttonSpacing: CGFloat = 8
    // Insets for the top container view
    private let containerInsets = UIEdgeInsets(top: 16, left: 16, bottom: 16, right: 16)
    
    // Top container view (stays anchored to the top of the screen)
    private lazy var topContainer: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints = false
        view.backgroundColor = .systemGray6 // Optional: for visibility during testing
        return view
    }()
    
    // Stack view to handle responsive button wrapping
    private lazy var buttonStack: UIStackView = {
        let stack = UIStackView()
        stack.translatesAutoresizingMaskIntoConstraints = false
        stack.axis = .horizontal
        stack.alignment = .center
        stack.distribution = .fillProportionally // Adjusts button width based on content
        stack.spacing = buttonSpacing
        stack.isLayoutMarginsRelativeArrangement = true
        stack.layoutMargins = containerInsets
        return stack
    }()
}

2. Assemble Views & Add Constraints

Next, we'll add these views to the main view and set up Auto Layout constraints to keep the container anchored to the top:

override func viewDidLoad() {
    super.viewDidLoad()
    setupLayout()
    createAndAddButtons()
}

private func setupLayout() {
    view.backgroundColor = .white
    
    // Add container and stack view to the hierarchy
    view.addSubview(topContainer)
    topContainer.addSubview(buttonStack)
    
    // Pin the top container to the safe area top, left, and right
    NSLayoutConstraint.activate([
        topContainer.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor),
        topContainer.leadingAnchor.constraint(equalTo: view.leadingAnchor),
        topContainer.trailingAnchor.constraint(equalTo: view.trailingAnchor),
        // Let the container's height be determined by the stack view content
        topContainer.bottomAnchor.constraint(equalTo: buttonStack.bottomAnchor)
    ])
    
    // Pin the stack view to fill the container
    NSLayoutConstraint.activate([
        buttonStack.topAnchor.constraint(equalTo: topContainer.topAnchor),
        buttonStack.leadingAnchor.constraint(equalTo: topContainer.leadingAnchor),
        buttonStack.trailingAnchor.constraint(equalTo: topContainer.trailingAnchor),
        buttonStack.bottomAnchor.constraint(equalTo: topContainer.bottomAnchor)
    ])
}

3. Create Buttons with Adaptive Behavior

Now we'll loop through our title array, create each button, and configure it to adapt to text length and screen size:

private func createAndAddButtons() {
    for title in buttonTitles {
        let button = UIButton(type: .system)
        button.setTitle(title, for: .normal)
        
        // Make button text shrink if it's too long for the button width
        button.titleLabel?.adjustsFontSizeToFitWidth = true
        button.titleLabel?.minimumScaleFactor = 0.7 // Don't shrink below 70% of original size
        
        // Add padding inside the button for better touch target and appearance
        button.contentEdgeInsets = buttonContentInsets
        
        // Style the button (customize this as needed)
        button.backgroundColor = .systemBlue
        button.setTitleColor(.white, for: .normal)
        button.layer.cornerRadius = 8
        
        // Ensure buttons prioritize their content width but can compress if needed
        button.setContentHuggingPriority(.defaultHigh, for: .horizontal)
        button.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
        
        // Add the button to the stack view
        buttonStack.addArrangedSubview(button)
    }
}
Key Features Explained
  • Responsive Wrapping: The UIStackView automatically wraps buttons to new lines when there's not enough horizontal space—perfect for handling landscape/portrait orientation changes.
  • Text Adaptation: Buttons will shrink their text size if the title is too long, preventing text truncation.
  • Flexible Layout: The stack view's fillProportionally distribution ensures buttons take up space based on their content, rather than forcing equal widths (though you can switch to .fillEqually if you prefer uniform button sizes).
  • Auto Height: The top container's height adjusts dynamically to fit all buttons, even when they wrap to multiple lines.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:07:52