I'm developing an application with a map. Now I build a modal sheet from bottom and I want to implement the map type selection (like google maps).
The problem is that I'm not sure how to build the selectable list of button like this one:
What I'm not understanding is which type of object I need to use? Because I'm trying to build it with buttons but I'm not sure that this is a great solution.
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
}
}
}
EDIT: This solution seems working but I'm not sure that this is a real solution. Because if I need to add more style I should write a lot of code.
CodePudding user response:
I was thinking to something like :
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)
}
}
}