Reputation: 826
Looking for some clarification and just to double check if I am on the right path. I have a category list where multiple buttons will send a specific string through a segue. I have the IBOutlets for each button but want to make sure when that specific button is touched that specific string is sent. I am just unsure if the way I am setting up the segue is correct so that each button is specific to the set strings. So far, the current segue works for "attractionsButton" but when I tap other buttons it passes the same data. I know it's not set, but want to make sure that when another button is tapped its not sending the wrong string.
@IBOutlet weak var attractionsButton: UIButton!
@IBOutlet weak var eatingButton: UIButton!
@IBOutlet weak var financialButton: UIButton!
@IBOutlet weak var lodgingButton: UIButton!
@IBOutlet weak var medicalButton: UIButton!
@IBOutlet weak var publicButton: UIButton!
@IBOutlet weak var servicesButton: UIButton!
@IBOutlet weak var storesButton: UIButton!
@IBOutlet weak var transportationButton: UIButton!
let attractions = "Attractions & Entertainment"
let eating = "Eating & Drinking"
var financial = "Financial Institution"
var lodging = "Lodging Establishment"
var medical = "Medical & Health"
var publicService = "Public Services & Buildings"
var services = "Service"
var stores = "Stores & Shopping"
var transportation = "Transportation"
@IBAction func attractionsButton(_ sender: Any) {
performSegue(withIdentifier: "category", sender: self)
}
@IBAction func eatingButton(_ sender: Any) {
performSegue(withIdentifier: "category", sender: self)
}
@IBAction func financialButton(_ sender: Any) {
performSegue(withIdentifier: "category", sender: self)
}
@IBAction func lodgingButton(_ sender: Any) {
performSegue(withIdentifier: "category", sender: self)
}
@IBAction func medicalButton(_ sender: Any) {
performSegue(withIdentifier: "category", sender: self)
}
@IBAction func publicButton(_ sender: Any) {
performSegue(withIdentifier: "category", sender: self)
}
@IBAction func serviceButton(_ sender: Any) {
performSegue(withIdentifier: "category", sender: self)
}
@IBAction func storesButton(_ sender: Any) {
performSegue(withIdentifier: "category", sender: self)
}
@IBAction func transportationButton(_ sender: Any) {
performSegue(withIdentifier: "category", sender: self)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
if segue.identifier == "category" {
if let button1 = attractionsButton {
let user = attractions
let controller = segue.destination as? CategoryListedViewController
controller?.categoryList = user
}
}
}
Upvotes: 0
Views: 986
Reputation: 7250
If I were you I would use buttons tags and a good old enum to work this out:
First, in Interface Builder, you set the tag
property of each of your buttons (and you don't even need to have them anymore as @IBOutlet
)
1 for attractionsButton, 2 for eatingButton, etc.
Then, you create an enum, with raw value as Int
with matching values :
enum Category : Int, CustomStringConvertible {
case attractions = 1
case eating = 2
case financial = 3
case lodging = 4
case medical = 5
case publicService = 6
case services = 7
case stores = 8
case transportation = 9
var description : String {
switch self {
case .attractions: return "Attractions & Entertainment"
case .eating: return "Eating & Drinking"
case .financial: return "Financial Institution"
case .lodging: return "Lodging Establishment"
case .medical: return "Medical & Health"
case .publicService: return "Public Services & Buildings"
case .services: return "Service"
case .stores: return "Stores & Shopping"
case .transportation: return "Transportation"
}
}
}
After that, you link all your buttons to only one @IBAction
like this one:
@IBAction func onButtonTap(_ sender: UIButton) {
performSegue(withIdentifier: "category", sender: Category(rawValue: sender.tag))
}
This way, according to the tag of the button, you'll create the enum you need.
As an end, in your segue preparation, you can set things like that:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "category" {
guard
let controller = segue.destination as? CategoryListedViewController,
let category = sender as? Category
else { return }
controller.categoryList = category.description
}
}
This way, things are much more concise and you can attache more behaviors to your enum Category
, use it in switches, and so on, instead of relying on Strings
or multiplying copy&paste code.
Upvotes: 0
Reputation: 154513
All of your buttons can connect to just this one @IBAction
:
@IBAction func allButtons (_ sender: Any) {
performSegue(withIdentifier: "category", sender: sender)
}
Of course, if that is all the buttons are doing, you can skip using the @IBAction
entirely and just wire the segues from the buttons directly. If you do that when creating the first button in the Storyboard, you can copy that button and all copies will be wired to the same segue.
Then in prepare(for:sender:)
, compare the sender to your @IBOutlet
s to set your string:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let button = sender as? UIButton,
let controller = segue.destination as? CategoryListedViewController,
segue.identifier == "category" {
let str: String
switch button {
case attractionsButton: str = attractions
case eatingButton: str = eating
case financialButton: str = financial
default: str = ""
}
controller.categoryList = str
}
}
Upvotes: 1
Reputation: 877
change self in your action to sender, you can use this one action for all the buttons
@IBAction func transportationButton(_ sender: Any) {
performSegue(withIdentifier: "category", sender: sender)
}
use this code in your prepare for segue
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
super.prepare(for: segue, sender: sender)
if segue.identifier == "category" {
let senderButton = sender as! UIButton
switch senderButton{
case attractionsButton:
let user = attractions
let controller = segue.destination as? CategoryListedViewController
controller?.categoryList = user
case eatingButton:
//editing button scenario
print("editing button scenario")
default:
//default code
print("default scenario")
}
}
}
Upvotes: 2