Swift自定义控件开发咨询:iPhone端单选汉堡选择控件实现
Custom Burger Selector Control Implementation Guide (Swift/iOS)
Hey Steve, let's walk through building this custom burger selector control step by step—here's a practical, Swift-focused approach that fits your requirements perfectly:
1. Define a Data Model
First, create a simple struct to hold each option's core details (display name and corresponding burger image reference):
struct BurgerOption { let name: String let imageName: String // Match this exactly to your asset catalog image filenames }
2. Build a Custom Table View Cell
Since each "cell" acts like a selectable button with a checkmark indicator, we'll create a custom UITableViewCell to handle selection state visuals:
class BurgerOptionCell: UITableViewCell { static let reuseIdentifier = "BurgerOptionCell" // UI Elements private let nameLabel = UILabel() private let checkmarkIcon = UIImageView(image: UIImage(systemName: "checkmark.circle.fill")) override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { super.init(style: style, reuseIdentifier: reuseIdentifier) setupCellLayout() } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } private func setupCellLayout() { // Configure label nameLabel.font = .systemFont(ofSize: 16, weight: .regular) nameLabel.translatesAutoresizingMaskIntoConstraints = false // Configure checkmark checkmarkIcon.tintColor = .systemBlue checkmarkIcon.isHidden = true checkmarkIcon.translatesAutoresizingMaskIntoConstraints = false // Add subviews to cell content view contentView.addSubview(nameLabel) contentView.addSubview(checkmarkIcon) // Auto Layout constraints NSLayoutConstraint.activate([ nameLabel.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), nameLabel.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 16), checkmarkIcon.centerYAnchor.constraint(equalTo: contentView.centerYAnchor), checkmarkIcon.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -16), checkmarkIcon.widthAnchor.constraint(equalToConstant: 24), checkmarkIcon.heightAnchor.constraint(equalToConstant: 24) ]) // Make cell tappable (behaves like a button) contentView.isUserInteractionEnabled = true } // Update cell based on option and selection state func configure(with option: BurgerOption, isSelected: Bool) { nameLabel.text = option.name checkmarkIcon.isHidden = !isSelected backgroundColor = isSelected ? .systemBlue.withAlphaComponent(0.1) : .white } }
3. Implement the Main View Controller Logic
This is where we handle the table view, single-selection behavior, and burger image switching:
class BurgerSelectorVC: UIViewController { // UI Components private let burgerImageView = UIImageView() private let optionsTableView = UITableView() // Data & State private let burgerOptions: [BurgerOption] = [ BurgerOption(name: "Burger 2", imageName: "burger2"), BurgerOption(name: "Burger 3", imageName: "burger3"), BurgerOption(name: "Burger 2/Mayo", imageName: "burger2_mayo"), BurgerOption(name: "Burger 3/Mayo", imageName: "burger3_mayo") ] private var selectedOptionIndex: Int? { didSet { updateBurgerImage() optionsTableView.reloadData() } } override func viewDidLoad() { super.viewDidLoad() setupUI() setupTableView() } private func setupUI() { view.backgroundColor = .white // Configure burger image view burgerImageView.contentMode = .scaleAspectFit burgerImageView.translatesAutoresizingMaskIntoConstraints = false view.addSubview(burgerImageView) // Layout constraints for image view NSLayoutConstraint.activate([ burgerImageView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20), burgerImageView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 20), burgerImageView.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -20), burgerImageView.heightAnchor.constraint(equalToConstant: 200) ]) } private func setupTableView() { optionsTableView.translatesAutoresizingMaskIntoConstraints = false optionsTableView.register(BurgerOptionCell.self, forCellReuseIdentifier: BurgerOptionCell.reuseIdentifier) optionsTableView.delegate = self optionsTableView.dataSource = self optionsTableView.rowHeight = UITableView.automaticDimension optionsTableView.estimatedRowHeight = 60 view.addSubview(optionsTableView) // Layout constraints for table view NSLayoutConstraint.activate([ optionsTableView.topAnchor.constraint(equalTo: burgerImageView.bottomAnchor, constant: 20), optionsTableView.leadingAnchor.constraint(equalTo: view.leadingAnchor), optionsTableView.trailingAnchor.constraint(equalTo: view.trailingAnchor), optionsTableView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor) ]) } // Update the displayed burger image when selection changes private func updateBurgerImage() { guard let index = selectedOptionIndex, index < burgerOptions.count else { burgerImageView.image = nil // Show empty or a default placeholder if no selection return } burgerImageView.image = UIImage(named: burgerOptions[index].imageName) } } // MARK: - UITableView Data Source & Delegate extension BurgerSelectorVC: UITableViewDataSource, UITableViewDelegate { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return burgerOptions.count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { guard let cell = tableView.dequeueReusableCell(withIdentifier: BurgerOptionCell.reuseIdentifier, for: indexPath) as? BurgerOptionCell else { return UITableViewCell() } let option = burgerOptions[indexPath.row] let isSelected = indexPath.row == selectedOptionIndex cell.configure(with: option, isSelected: isSelected) return cell } func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { // Single-selection logic: Toggle selection if tapping the same row, or set new selection selectedOptionIndex = selectedOptionIndex == indexPath.row ? nil : indexPath.row tableView.deselectRow(at: indexPath, animated: true) // Remove default table view highlight } }
Key Notes & Customizations
- Image Assets: Ensure your
Assets.xcassetscontains images matching theimageNamevalues in yourBurgerOptioninstances. - Forced Selection: If you want users to always have one option selected, remove the toggle logic in
didSelectRowAtand just setselectedOptionIndex = indexPath.row. - Visual Tweaks: Adjust the cell's font, colors, or checkmark icon to match your Excel prototype—you can replace the system icon with a custom image if needed.
- Grid Layout: If your prototype uses a grid (multiple cells per row), swap
UITableViewforUICollectionView—the selection and image-switching logic will remain nearly identical.
内容的提问来源于stack exchange,提问作者Steve
相关产品推荐
相关产品推荐

