UIButton is disabled - Swift - ios

I'm new to swift programming and I'm trying to disable the save button until all other required buttons are selected, but when I try to do that with the button.isEnabled = false, it doesn't change even when all the buttons are selected. here is a sample code:
func disableButton () {
if firstButton.isSelected && rightButton.isSelected {
saveButton.isEnabled = true
} else {
saveButton.isEnabled = false
}
}
when I remove the last line the save button works but when I put it back it's disabled even when the two other buttons are selected.

Assuming you have used Storyboard you have to link the 2 buttons into #IBActions , and within those #IBAction methods manipulate the isSelected property. Refer the example below.
NOTE - Read the comments
class ViewController: UIViewController {
// 2 buttons that we will set the isSelected property
#IBOutlet weak var button1: UIButton!
#IBOutlet weak var button2: UIButton!
// Button to disable/enable
#IBOutlet weak var finalButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
finalButton.isEnabled = false // setting the button as disabled
}
/// This is the function triggered when you click on the "button1"
#IBAction func didPressButton1(_ sender: UIButton) {
// Here we will set the isSelected property of "sender" parameter, which is the button that calls this function. That is button 1
sender.isSelected = sender.isSelected ? false : true
//calling this function to make any updates to the UI if needed
disableButton()
}
/// This is the function triggered when you click on the "button2"
#IBAction func didPressButton2(_ sender: UIButton) {
// Here we will set the isSelected property of "sender" parameter, which is the button that calls this function. That is button2
sender.isSelected = sender.isSelected ? false : true
//calling this function to make any updates to the UI if needed
disableButton()
}
func disableButton () {
if button1.isSelected && button2.isSelected {
finalButton.isEnabled = true
} else {
finalButton.isEnabled = false
}
}
}
What happens here is you will set the isSelected property of the button that calls the function in the function itself, and run the disableButton() function every time it is invoked for UI updates.
The final result will be,

Related

Press search button to show the searchBar from isHidden to isSelected

How can I make an if statement in swift that when I click the search button as shown in the picture below to show the search bar from isHidden to isSelected
Basically when I press the searchImage the searchBar will show from its initial isHidden to isSelected
pic
#IBAction func searchButton(_ sender: Any) {
}
#IBOutlet weak var searchField: UISearchBar!
I don't know what you need exactly but if you need to switch isHidden or isSelected you can add var to keep the search bar state like:
var isSearchFieldHidden: Bool = false{
didSet{
self.searchField.isHidden = isSearchFieldHidden
}
}
#IBAction func searchButton(_ sender: Any) {
isSearchFieldHidden.toggle()
}
#IBOutlet weak var searchField: UISearchBar!
Try to use
Button(action: {
isHidden.toggle()
}) {
Image("search_icon")
}
!isHidden{
// any view: Button, TextField etc.
your_searchBarView()
}
and read: https://developer.apple.com/documentation/swiftui/text/hidden()#declaration

How can I deselect a button when other consecutive button is pressed?

I'm creating a test that has 5 buttons, each button corresponds to a specific color, the problem is that when I select a consecutive 2nd button, the previous button is still selected, how can I make my code select only one button at a time and deselect the previous one?
How can I fix this?
This is my code
class ViewController: UIViewController {
var buttonPressed: Bool = false
#IBOutlet weak var button1: UIButton!
#IBAction func buttonAction1(_ sender: UIButton) {
if buttonPressed {
buttonPressed = false
button1.setImage(UIImage(named: "Bolinha-5"), for: .normal)
}
else {
buttonPressed = true
button1.setImage(UIImage(named: "Bolinha-4"), for: .normal)
}
}
#IBOutlet weak var button2: UIButton!
#IBAction func buttonAction2(_ sender: UIButton) {
if buttonPressed {
buttonPressed = false
button2.setImage(UIImage(named: "Bolinha-5"), for: .normal)
}
else {
buttonPressed = true
button2.setImage(UIImage(named: "Bolinha-4"), for: .normal)
}
}
#IBOutlet weak var button3: UIButton!
#IBAction func buttonAction3(_ sender: UIButton) {
if buttonPressed {
buttonPressed = false
button3.setImage(UIImage(named: "Bolinha-2"), for: .normal)
}
else {
buttonPressed = true
button3.setImage(UIImage(named: "Bolinha-4"), for: .normal)
}
}
#IBOutlet weak var button4: UIButton!
#IBAction func buttonAction4(_ sender: UIButton) {
if buttonPressed {
buttonPressed = false
button4.setImage(UIImage(named: "Bolinha-3"), for: .normal)
}
else {
buttonPressed = true
button4.setImage(UIImage(named: "Bolinha-4"), for: .normal)
}
}
#IBOutlet weak var button5: UIButton!
#IBAction func buttonAction5(_ sender: UIButton) {
if buttonPressed {
buttonPressed = false
button5.setImage(UIImage(named: "Bolinha-3"), for: .normal)
}
else {
buttonPressed = true
button5.setImage(UIImage(named: "Bolinha-4"), for: .normal)
}
}
}
What you are going to accomplish is called Radio Buttons, unfortunately iOS (unlike macOS) doesn't provide this functionality.
My suggestion takes advantage of the option to assign different images to different states in Interface Builder – in this case the Default and Selected state – and to create an outlet collection, an array representing a sequence of UI elements of the same type.
The suggestion doesn't support an empty selection, by default the first button is selected.
In ViewController
create an outlet collection
#IBOutlet var buttons : [UIButton]!
and one IBAction
#IBAction func buttonAction(_ sender: UIButton) { }
In Interface Buider
set the images to the Default and Selected states of each button in the Attribute Inspector.
connect the buttons in the proper order to the outlet collection.
assign the tags 0 to 4 to the buttons in the same order.
connect all buttons also to the (same) IBAction.
In ViewController
create a property for the tag of the currently selected button
var selectedButton = 0
in viewDidLoad select the first button
override func viewDidLoad() {
super.viewDidLoad()
buttons[selectedButton].isSelected = true
}
Complete the IBAction, it deselects the previous button and selects the current.
#IBAction func buttonAction(_ sender: UIButton) {
let tag = sender.tag
buttons[selectedButton].isSelected = false
buttons[tag].isSelected = true
selectedButton = tag
}
let's consider you have named your buttons as follows: 1st button: "opt1Button", 2nd button: "opt2Button", 3rd button: "opt3Button" and so on...
create an IBAction with name "optionSelected" The function will look like:
#IBAction func optionSelected(_ sender: UIButton) {
opt1Button.isSelected = false
opt2Button.isSelected = false
opt3Button.isSelected = false
opt4Button.isSelected = false
opt5Button.isSelected = false
sender.isSelected = true
}
As soon any of the options is selected all the buttons will go to 'isSelected' false condition i.e all the buttons will be deselected at first and the selected button will be marked as selected. Same process will be followed again when any of the button is selected, everything will get deselected and the button user has pressed will be marked as selected.
Found this answer from (https://developer.apple.com/forums/thread/685124) and it worked for me.

How to unhide the button after all switches in ON condition?

I have 2 UISwitch and a Button, in viewDidLoad, I set the button to be hidden and disabled, I want only my button to be not hidden if those 2 switch is in ON state, otherwise, I want my button to hide again. is there any method from UI Switch delegate that can be used ? how do I do that in Swift ?
here is the code I use
import UIKit
class AskingAuthorizationVC: UIViewController {
#IBOutlet weak var locationSwitch: DesignableSwitch!
#IBOutlet weak var notificationSwitch: DesignableSwitch!
#IBOutlet weak var nextButton: DesignableButton!
override func viewDidLoad() {
super.viewDidLoad()
// initial state
nextButton.isHidden = true
nextButton.isEnabled = false
notificationSwitch.isOn = false
locationSwitch.isOn = false
}
#IBAction func signUpButtonDidPressed(_ sender: Any) {
performSegue(withIdentifier: "toAuthenticationVC", sender: nil)
}
}
Hook both of the UISwitch-s as IBActions & IBOutlets
#IBAction func oweSwitch(_ sender: UISwitch) {
self.mybutton.isHidden = !(switch1.isOn && switch2.isOn)
}

Radio Button Group Swift 3 Xcode 8

I have searched various sources and could not find a clear and simple solution for creating the equivalent of a radio button group in Swift 3 with Xcode 8.3 for an iOS application.
For example if I have 3 buttons in one group and only one should be selected at a time. Currently I am implementing this by changing the state of 2 buttons in the group to not selected when the other one is selected and vice versa.
#IBAction func buttonA(_ sender: Any) {
buttonB.isChecked = false
buttonC.isChecked = false
}
#IBAction func buttonB(_ sender: Any) {
buttonA.isChecked = false
buttonC.isChecked = false
}
#IBAction func buttonC(_ sender: Any) {
buttonA.isChecked = false
buttonB.isChecked = false
}
However I would expect a more efficient way to do this.
Any help on a more efficient solution will be appreciated.
You can connect all your button's IBAction to one single method.
#IBAction func buttonClick(_ sender: UISwitch) { // you're using UISwitch I believe?
}
You should add all the buttons into an array:
// at class level
var buttons: [UISwitch]!
// in viewDidLoad
buttons = [buttonA, buttonB, buttonC]
Then, write the buttonClick method like this:
buttons.forEach { $0.isChecked = false } // uncheck everything
sender.isChecked = true // check the button that is clicked on
Alternatives:
Try using a UITableView. Each row contains one option. When a row is selected, change that row's accessoryType to .checkMark and every other row's to .none.
If you are too lazy, try searching on cocoapods.org and see what other people have made.
Just make a single selector for all three button's touchUpInside event, and set radio_off image for normal state and radio_on image for selected state in your IB, then only you have to connect btnClicked method to all button's touchUpInside event
class ViewController: UIViewController {
#IBOutlet weak var btnFirst:UIButton!
#IBOutlet weak var btnSecond:UIButton!
#IBOutlet weak var btnThird:UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func btnClicked(sender:UIButton){
let buttonArray = [btnFirst,btnSecond,btnThird]
buttonArray.forEach{
$0?.isSelected = false
}
sender.isSelected = true
}
Depending on your UI, you could take multiple approaches.
UITableView - Use a UITableView with a checkmark decorator. If your layout for these radio buttons is fairly traditional, this is the correct paradigm. If the layout is a grid instead of a list, you could use UICollectionView.
You can use the func table(_ table: WKInterfaceTable, didSelectRowAt rowIndex: Int) in UITableViewDelegate to capture the selection. You can call indexPathForSelectedRow on the tableView when you want to commit the change to determine which cell was selected.
Apple's tutorial on UITableView can be found at:
https://developer.apple.com/library/content/referencelibrary/GettingStarted/DevelopiOSAppsSwift/CreateATableView.html
Manage a group of UIButtons - You could store an array of references to UIButton objects that are part of your radio button group.
protocol RadioButtonDelegate: class {
func didTapButton(_ button: UIButton)
}
class RadioButtonGroup {
private var buttons: [UIButton] = []
weak var delegate: RadioButtonDelegate?
var selectedButton: UIButton? { return buttons.filter { $0.isSelected }.first }
func addButton(_ button: UIButton) {
buttons.append(button)
}
#objc private func didTapButton(_ button: UIButton) {
button.isSelected = true
deselectButtonsOtherThan(button)
delegate?.didTapButton(button)
}
private func deselectButtonsOtherThan(_ selectedButton: UIButton) {
for button in buttons where button != selectedButton {
button.isSelected = false
}
}
}
class MyView: UIView {
private var radioButtonGroup = RadioButtonGroup()
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
let button1 = UIButton(type: .custom)
button1.setTitle("Eeeny", for: .normal)
let button2 = UIButton(type: .custom)
button2.setTitle("Meeny", for: .normal)
let button3 = UIButton(type: .custom)
button3.setTitle("Miny", for: .normal)
self.radioButtonGroup.addButton(button1)
self.radioButtonGroup.addButton(button2)
self.radioButtonGroup.addButton(button3)
addSubview(button1)
addSubview(button2)
addSubview(button3)
}
}
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var maleLB: UIButton!
#IBOutlet weak var femaleLB: UIButton!
#IBOutlet weak var otherLB: UIButton!
var gender = "Male"
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
if gender == "Male"{
femaleLB.isSelected = true
}
}
#IBAction func maleBtn(_ sender: UIButton) {
if sender.isSelected {
sender.isSelected = false
femaleLB.isSelected = false
otherLB.isSelected = false
}
else{
sender.isSelected = true
femaleLB.isSelected = false
otherLB.isSelected = false
}
}
#IBAction func femaleBtn(_ sender: UIButton) {
if sender.isSelected {
sender.isSelected = false
maleLB.isSelected = false
otherLB.isSelected = false
}
else{
sender.isSelected = true
maleLB.isSelected = false
otherLB.isSelected = false
}
}
#IBAction func otherBtn(_ sender: UIButton) {
if sender.isSelected {
sender.isSelected = false
maleLB.isSelected = false
femaleLB.isSelected = false
}
else{
sender.isSelected = true
maleLB.isSelected = false
femaleLB.isSelected = false
}
}
}

Changing UITextfield from Non-Editable to Editable - Swift

I am trying to have two non-editable UITextField display name and age. I have an Edit UIBarButtonItem in my Navigation Bar that I want to be able to trigger the UITextField to be editable when that button is pressed.
In my Interface Builder, I have the User Interaction Enabled option unchecked for the two UITextFields. Do I need to add ageText.UserInteractionEnabled = true? I'm at a loss here.
class UserProfileVC: UIViewController,
UITextFieldDelegate, UINavigationControllerDelegate {
#IBOutlet weak var infoBorder: UILabel!
#IBOutlet weak var nameText: UITextField!
#IBOutlet weak var ageText: UITextField!
var textFields:[UITextField] = []
#IBAction func editButton(sender: UIBarButtonItem) {
nameText.becomeFirstResponder()
ageText.becomeFirstResponder()
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
var currentTextField = textFields[0]
if (currentTextField == textField) {
currentTextField = textFields[1]
currentTextField.becomeFirstResponder()
} else {
currentTextField.resignFirstResponder()
}
return true
}
}
Yes, you want to do
nameText.userInteractionEnabled = true
ageText.userInteractionEnabled = true
and possibly
nameText.becomeFirstResponder()
when the edit button gets pressed the first time. You will probably also want to change the "Edit" button do a "Done" button. When the user presses the done button, you'll want to make sure you disable user interaction and resign first responder for both text fields.
You should have a Bool Variable. Set it to 'false' then when the button is pressed you toggle it to 'true'. Depending on its state just run to different methods which essentially allows you to edit or not.
Something like this:
var editTextFieldToggle: Bool = false
#IBoutlet var textFieldToggle: UIButton!
#IBAction func textFieldToggle_Action(sender: UIButton){
editTextFieldToggle = !editTextFieldToggle //switches button ON/OFF
if editTextFieldToggle == true {
textFieldActive()
} else {
textFieldDeactive()
}
}
textFieldActive(){
//Turn things ON
nameText.enabled == true
ageText.enabled == true
}
textFieldDeactive(){ //Add anything else
//Turn things OFF
nameText.enabled == false
ageText.enabled == false
}

Resources