Swift 可选标签

Swift selectable label

我正在开发一个带有地图的应用程序。现在我从底部构建一个模态 sheet,我想实现地图类型选择(比如 google 地图)。

问题是我不确定如何像这样构建可选择的按钮列表:

我不明白我需要使用哪种类型的对象?因为我正在尝试使用按钮构建它,但我不确定这是一个很好的解决方案。

import UIKit

@objc(LayerViewController)
public class LayerViewController: UIViewController {
    
    var selectedIndex: Int = 0
    
    var normal: UIButton = UIButton()
    var satellite: UIButton = UIButton()
    
    var style: [UIButton] = []
        
    override public func viewDidLoad() {
        super.viewDidLoad()
        
        style.append(normal)
        style.append(satellite)
        
        setStyle()
    }
    
    func setStyle() {
        
        normal.frame = CGRect(
            x: 100,
            y: self.view.frame.height * 0.2,
            width: 100,
            height: 100
        )
        normal.setBackgroundImage(UIImage(named: "background"), for: .normal)
        normal.layer.borderColor = .init(red: 0, green: 0, blue: 255, alpha: 1)
        normal.layer.borderWidth = 5
        normal.isSelected = true
        normal.addTarget(self, action: #selector(selectNormal), for: .touchUpInside)
        
        satellite.frame = CGRect(
            x: 300,
            y: self.view.frame.height * 0.2,
            width: 100,
            height: 100
        )
        satellite.setBackgroundImage(UIImage(named: "background"), for: .normal)
        satellite.isSelected = false
        satellite.addTarget(self, action: #selector(selectedSatellite), for: .touchUpInside)
        
        
        self.view.addSubview(normal)
        self.view.addSubview(satellite)
    }
    
    @objc func selectNormal() {
        if (selectedIndex != 0) {
            normal.layer.borderColor = .init(red: 0, green: 0, blue: 255, alpha: 1)
            normal.layer.borderWidth = 5
            normal.isSelected = true
            
            style[selectedIndex].layer.borderColor = .init(red: 0, green: 0, blue: 0, alpha: 0)
            style[selectedIndex].layer.borderWidth = 0
            style[selectedIndex].isSelected = false
            selectedIndex = 0
        }
    }
    
    @objc func selectedSatellite() {
        if (selectedIndex != 1) {
            satellite.layer.borderColor = .init(red: 0, green: 0, blue: 255, alpha: 1)
            satellite.layer.borderWidth = 5
            satellite.isSelected = true
            
            style[selectedIndex].layer.borderColor = .init(red: 0, green: 0, blue: 0, alpha: 0)
            style[selectedIndex].layer.borderWidth = 0
            style[selectedIndex].isSelected = false
            selectedIndex = 1
        }
    }
}

编辑: 该解决方案似乎有效,但我不确定这是一个真正的解决方案。因为如果我需要添加更多样式我应该写很多代码。

我在想类似的东西:

public class LayerViewController: UIViewController {
    // Type of style to apply
    enum StyleType: Int, CaseIterable {
        case normal = 1
        case satellite = 2
        case terrain = 3
        case explore = 4
        // Add more styles here and increment value
    }
    // Button images
    static let buttonImages: [StyleType:String] =
    [.normal: "normal",
     .satellite: "satellite",
     .terrain: "terrain",
     .explore: "explore"]
        // Add more button images for new styles
    
    // The selected style
    var selectedSyle = StyleType.normal
    
    var buttons: [StyleType:UIButton] = [:]

    override public func viewDidLoad() {
        super.viewDidLoad()
        
        addButton(.normal)
        addButton(.satellite)
        addButton(.terrain)
        addButton(.explore)
        setStyle(selectedSyle)
    }
    
    // Button creation and adding to button dictionary
    func addButton(_ style: StyleType) {
        let x: CGFloat = 100 + 200 * CGFloat(buttons.count)
        
        let frame = CGRect(
            x: x,
            y: self.view.frame.height * 0.2,
            width: 100,
            height: 100
        )
        if let imageName = Self.buttonImages[style] {
            let button = UIButton(frame: frame)
            
            // Use tag to know which button is touched
            button.tag = style.rawValue
            button.setBackgroundImage(UIImage(named: imageName), for: .normal)
            button.layer.borderColor = .init(red: 0, green: 0, blue: 255, alpha: 1)
            button.layer.borderWidth = 5
            button.isSelected = true
            button.addTarget(self, action: #selector(selectStyle(_:)), for: .touchUpInside)
            buttons[style] = button
            self.view.addSubview(button)
        }
    }

    // Update the style of button when selecting one style
    func setStyle(_ selectedStyle: StyleType) {
        for (style, button) in buttons {
            if style == selectedStyle {
                button.layer.borderColor = .init(red: 0, green: 0, blue: 255, alpha: 1)
                button.layer.borderWidth = 5
                button.isSelected = true
                selectedSyle = style
            } else {
                button.layer.borderColor = .init(red: 0, green: 0, blue: 0, alpha: 0)
                button.layer.borderWidth = 0
                button.isSelected = false
            }
            
        }
    }

    // Called when button touched
    @objc func selectStyle(_ sender: UIButton) {
        // Get style via button tag
        if let selectedStyle = StyleType(rawValue: sender.tag) {
            self.setStyle(selectedStyle)
        }
    }
}