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

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.xcassets contains images matching the imageName values in your BurgerOption instances.
  • Forced Selection: If you want users to always have one option selected, remove the toggle logic in didSelectRowAt and just set selectedOptionIndex = 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 UITableView for UICollectionView—the selection and image-switching logic will remain nearly identical.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:01:55