Reputation: 1021
Is there any easy way I can do this? Let's say I have 10 different buttons and a textbox.
@IBOutlet var button1: UIButton!
@IBOutlet var button2: UIButton!
@IBOutlet var button3: UIButton!
@IBOutlet var button4: UIButton!
@IBOutlet var button5: UIButton!
@IBOutlet var button6: UIButton!
@IBOutlet var button7: UIButton!
@IBOutlet var button8: UIButton!
@IBOutlet var button9: UIButton!
@IBOutlet var button10: UIButton!
If textBox.text is "bt1", i want only enable button1, and disable the rest, and if textbox.text is "bt2", i want to only enable button2, and disable the rest, and so on...
Upvotes: 0
Views: 1116
Reputation: 73186
Note that you mustn't necessarily create an array of your buttons. As an alternative---given that these are all the buttons in your View Controller---you can make use of Mirror(reflecting: ...
:
/* ViewController.swift */
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var button1: UIButton!
@IBOutlet weak var button2: UIButton!
@IBOutlet weak var button3: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
button1.enabled = true
button2.enabled = true
button3.enabled = true
setEnableValueForAllButtons(false, exceptForButton: "button2")
print(button1.enabled)
print(button2.enabled)
print(button3.enabled)
/* button1.enabled = false
button2.enabled = true
button3.enabled = false */
}
func setEnableValueForAllButtons(toValue: Bool, exceptForButton: String) {
let buttons = Mirror(reflecting: self).children.filter { $0.value is UIButton && ($0.label ?? "") != exceptForButton}
for button in buttons {
(button.value as? UIButton)?.enabled = toValue
}
}
}
If you want to only show the button whose property name is entered into a text field, you can simply extend the example above to include the text field, and call the setEnableValueForAllButtons(...)
function from the UITextFieldDelegate
method textFieldShouldReturn
(hence after you press return after entering a string in the text field) as follows:
/* ViewController.swift */
import UIKit
class ViewController: UIViewController, UITextFieldDelegate {
@IBOutlet weak var button1: UIButton!
@IBOutlet weak var button2: UIButton!
@IBOutlet weak var button3: UIButton!
@IBOutlet weak var textBox: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
button1.enabled = false
button2.enabled = false
button3.enabled = false
textBox.delegate = self
}
func setEnableValueForAllButtons(toValue toValue: Bool, exceptForButton: String) {
let buttons = Mirror(reflecting: self).children.filter { $0.value is UIButton && ($0.label ?? "") != exceptForButton}
for button in buttons {
(button.value as? UIButton)?.enabled = toValue
}
}
// UITextFieldDelegate
func textFieldShouldReturn(textField: UITextField) -> Bool {
textField.resignFirstResponder()
setEnableValueForAllButtons(toValue: true, exceptForButton: "")
setEnableValueForAllButtons(toValue: false, exceptForButton: textField.text ?? "")
return true
}
}
If it's important for you to use triggers "bt1"
, "bt2"
and so on, you could just rename the names of the button outlets to these values.
Upvotes: 1
Reputation: 3842
UPDATED:
As I understand it you want to enable/disable buttons depending on some text entered into a textField. I'm assuming you have a method which is called from one of the textField delegate methods. I'm also assuming that there is a 1 to 1 mapping from the text you enter to the buttons i.e that the user has to type exactly "btn1" - they can't do "button1" or "button 1" or any other variation. This is quite an odd requirement - are you sure this is what you really want?
First, as before put the buttons in an 'IBOutlet' collection:
@IBOutlet var allButtons : [UIButton]!
Then, use an enumeration to map the textbox text to the index of the buttons in the collection
enum ButtonMapping : String {
case button1 = "btn1"
case button2 = "btn2"
//and so on
func buttonIndex() -> Int {
switch(self) {
case button1: return 0
case button2: return 1
//and so on
}
}
}
Then just do something like:
func disableButtonsForText(text:String) {
if let mapping = ButtonMapping(rawValue:text) {
let activeButton = allButtons[mapping.buttonIndex]
for button in allButtons {
if button != activeButton {
button.enabled = false
}
}
}
}
This will change the state of the buttons only when the let binding is successful - i.e. when the string supplied to the ButtonMapping
constructor is a valid button name. In all other cases, the state of the buttons won't change. You might want to consider adding an else
clause to reset the state of the buttons to normal if the text is not recognised - not sure what you want here.
Upvotes: 1
Reputation:
You can create an IBOutletCollection
of UIButton
.
And accessing them like that:
button[0].enabled = false
Iterate through the array to disable all button.
Upvotes: 1