iOS代码创建自定义View:水平排列按钮与UITableView高度适配
Hey there! Let's fix your popup's layout problems step by step—you're dealing with two key issues: buttons not aligning horizontally, and the UITableView not adjusting its height to fit content without scrolling. Let's break this down:
1. Fixing Horizontal Button Alignment
Your current button setup has two critical issues:
- You're setting a manual
framebut also enabling auto layout (translatesAutoresizingMaskIntoConstraints = false), which means auto layout ignores your frame calculations entirely. - The
nextButtonhas a typo in its width parameter (you passedpreviousButtoninstead of a valid width value).
The cleanest way to get horizontal button alignment is to wrap both buttons in a UIStackView. Here's how to adjust your code:
Updated Button Initialization
lazy var previousButton: UIButton = { let button = UIButton(type: .system) button.translatesAutoresizingMaskIntoConstraints = false button.setTitle("Previous", for: .normal) button.widthAnchor.constraint(equalToConstant: 150).isActive = true button.heightAnchor.constraint(equalToConstant: 36).isActive = true return button }() lazy var nextButton: UIButton = { let button = UIButton(type: .system) button.translatesAutoresizingMaskIntoConstraints = false button.setTitle("Next", for: .normal) button.widthAnchor.constraint(equalTo: previousButton.widthAnchor).isActive = true button.heightAnchor.constraint(equalTo: previousButton.heightAnchor).isActive = true return button }() // Add a stack view for horizontal button layout lazy var buttonStackView: UIStackView = { let stackView = UIStackView(arrangedSubviews: [previousButton, nextButton]) stackView.translatesAutoresizingMaskIntoConstraints = false stackView.axis = .horizontal stackView.spacing = 10 // Adjust spacing between buttons as needed stackView.distribution = .fillEqually // Use .fill if you prefer flexible widths return stackView }()
2. Making UITableView Adjust Height to Content
To get the table view to fit its content without scrolling, follow these steps:
- Disable scrolling on the table view
- Enable automatic row height calculation
- Add a height constraint we can update based on content size
Updated TableView Initialization
lazy var tableView: UITableView = { let tv = UITableView(frame: .zero) tv.translatesAutoresizingMaskIntoConstraints = false tv.isScrollEnabled = false // Disable scrolling entirely tv.rowHeight = UITableView.automaticDimension tv.estimatedRowHeight = 44 // Give a reasonable estimated height (adjust for your cells) // Register your cell class here if needed, e.g.: // tv.register(YourCustomCell.self, forCellReuseIdentifier: "Cell") return tv }() // Store a reference to the table view's height constraint for later updates private var tableViewHeightConstraint: NSLayoutConstraint!
3. Putting It All Together in Auto Layout
Update your didMoveToSuperview method to use the stack view and proper constraints:
override func didMoveToSuperview() { super.didMoveToSuperview() // Add all views to the popup container addSubview(titleLabel) addSubview(tableView) addSubview(buttonStackView) // Initialize and activate the table view height constraint tableViewHeightConstraint = tableView.heightAnchor.constraint(equalToConstant: 0) tableViewHeightConstraint.isActive = true // Activate all layout constraints NSLayoutConstraint.activate([ // Title label: full width, fixed 50pt height, top-aligned titleLabel.topAnchor.constraint(equalTo: topAnchor), titleLabel.leadingAnchor.constraint(equalTo: leadingAnchor), titleLabel.trailingAnchor.constraint(equalTo: trailingAnchor), titleLabel.heightAnchor.constraint(equalToConstant: 50), // Table view: below title, full width, height to be updated later tableView.topAnchor.constraint(equalTo: titleLabel.bottomAnchor), tableView.leadingAnchor.constraint(equalTo: leadingAnchor), tableView.trailingAnchor.constraint(equalTo: trailingAnchor), // Button stack: below table view, horizontal padding, bottom-aligned buttonStackView.topAnchor.constraint(equalTo: tableView.bottomAnchor, constant: 10), buttonStackView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 10), buttonStackView.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -10), buttonStackView.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -10) ]) }
4. Updating TableView Height When Content Changes
After you reload your table view data, call this method to adjust its height to fit content:
func updateTableViewHeight() { tableView.layoutIfNeeded() // Force layout to calculate accurate content size tableViewHeightConstraint.constant = tableView.contentSize.height layoutIfNeeded() // Update the popup's layout to fit the new table view height }
For example, when setting your data source:
func setDataSource(_ data: [YourDataType]) { // Update your data source array here tableView.reloadData() updateTableViewHeight() }
Key Notes to Remember
- Never mix manual
framesettings with auto layout—they conflict, and auto layout will always override your frame values. UITableView.automaticDimensionrequires your table view cells to have complete top-to-bottom auto layout constraints so the system can calculate their height.UIStackViewsimplifies grouped view layouts (like buttons) and makes it easy to adjust spacing or alignment later.
内容的提问来源于stack exchange,提问作者Ipek Ercel

