Swift. Changing multiple UIButtons with IBOutlet - ios

So, I have 20 UI buttons on a single viewcontroller. I also have 2 other buttons there that will change the currentTitle or background color of different groups of those buttons. (for example, pressing one of those 2 buttons will change the color of 10 other buttons, while pressing the other button will change the background of 15 of those buttons.)
Am I doomed to having to create 20 different IBOutlets like:
#IBOutlet weak var button1: UIButton!
#IBOutlet weak var button2: UIButton!
#IBOutlet weak var button3: UIButton!
.
.
.
and then having to write an additional 25 lines of:
button1!.setTitleColor(UIColor.redColor(), forState: .Normal()
button2!.setTitleColor(UIColor.redColor(), forState: .Normal()
button3!.setTitleColor(UIColor.redColor(), forState: .Normal()
Surely theres an easier way to do this? I can't link more than one UI with IBOutlet, and changing the tags for the buttons don't do much either because I still have to write the darn things down 25 times regardless.
Is it possible to put those buttons into groups where I can write a single line of code to change ALL things in that group?

Set your button tags in series like 101 to 125 and on click of any button perform this operation
for(UIButton *button in <parent view of buttons>.subviews){
if(button.tag >= 101 && button.tag <= 125){
button.setTitleColor(UIColor.redColor(), forState: .Normal()
}
}
For Swift
for subview in self.createBugView.subviews {
if let button = subview as? UIButton {
// this is a button
if(button.tag >= 101 && button.tag <= 125){
button.setTitleColor(UIColor.red, for: .normal)
}
}
}

Related

Why does my UIButton affect my UIImageView in Swift?

I'm building a simple app in Swift, and the app contains a png image, a UISegmentedControl, and a UIButton. Selecting different controls on the UISegmentedControl resizes an image of a pizza. When I click on "Large" in the UISegmentedControl, and then I press a button on the interface called submitOrderDisplay, it shrinks the image from its large size to its small size. I know it has something to do with the setTitle method I am using at the very bottom of the code, but I don't understand why that causes the image to reset to its default small size. If I remove the setTitle method, the resizing does not occur after I click the UIButton. I don't want the image to change size after the button is pressed. How do I achieve that?
import UIKit
class SecondViewController: UIViewController{
#IBOutlet weak var sizeChoiceControl: UISegmentedControl!
#IBOutlet weak var submitOrderDisplay: UIButton!
#IBOutlet weak var myImageView: UIImageView!
#IBAction func sizeSelected() {
if(sizeChoiceControl.titleForSegmentAtIndex(sizeChoiceControl.selectedSegmentIndex)! == "Small"){
myImageView.setHeight(height: 85)
myImageView.setWidth(width: 85)
myImageView.setX(x: 146)
myImageView.setY(y: 63)
}
else if(sizeChoiceControl.titleForSegmentAtIndex(sizeChoiceControl.selectedSegmentIndex)! == "Medium"){
myImageView.setHeight(height: 100)
myImageView.setWidth(width: 100)
myImageView.setX(x: 139)
myImageView.setY(y: 55)
}
else if(sizeChoiceControl.titleForSegmentAtIndex(sizeChoiceControl.selectedSegmentIndex)! == "Large"){
myImageView.setHeight(height: 115)
myImageView.setWidth(width: 115)
myImageView.setX(x: 131)
myImageView.setY(y: 48)
}
}
#IBAction func SubmitOrderClicked(sender: UIButton) {
submitOrderDisplay.setTitle("Update Order", forState: UIControlState.Normal)
}
}
Write the configuration of the button inside the viewDidLoad function:
submitOrderDisplay.setTitle("Update Order", forState: UIControlState.Normal)
I understand that you want to put the title Update Order.
If you want to change the title when pressed, you must call it for another State of the button like:
submitOrderDisplay.setTitle("Update Order", forState: UIControlState.Highlihgted)
If you change the configuration of the button for different states when an event happens, that must be why the size is ressetting.

Swap the label text of two buttons in Swift

I have 2 button like picture below, their text label are: "Input location...". Now i want to click on the swap button on the right, so the text label of these button will swap. It's look like you have 2 location and you want to swap it. Please any one can point me how to do it. Thank you very much.
On click just set their text to each other.
var tempString = secondButton.titleLabel.text
secondButton.setTitle(firstButton.titleLabel.text, forState: UIControlState.Normal)
firstButton.setTitle(tempString, forState: UIControlState.Normal)
#IBOutlet var firstButton: UIButton!
#IBOutlet var secondButton: UIButton!
#IBAction func didTouchUpInsideSwapButton() {
let firstButtonText = firstButton.titleLabel?.text
firstButton.setTitle(secondButton.titleLabel?.text, for: .normal)
secondButton.setTitle(firstButtonText, for: .normal)
}

UIButton text content keeps resetting every second update

I am trying to update a button with a test value and I have noticed that every second update the button title text shows the test value for a fraction of a second but then resets to the Button's default value.
It seems to be a bug, but I wanted to see if there is a simpler explanation.
I have tried waiting up to 10 seconds before pushing the button but this seems to be consistently occurring.
Any ideas how to make UIButton function as expected?
import UIKit
class ViewController: UIViewController {
var testEntry = "its working"
#IBOutlet weak var testButton: UIButton!
#IBOutlet weak var testLabel: UILabel!
#IBAction func runTest(sender:
UIButton) {
// The button value should equal the value of the label value, but every 2nd button press of the test button results in the title of the button value resetting to the default value
dispatch_async(dispatch_get_main_queue()) {
self.testLabel.text = "\(self.testEntry)"
self.testButton.titleLabel?.text = "\(self.testEntry)"
}
}
Here is the github project.
You shouldn't be directly setting the text of the button title label, you should only set the font directly onto the label. The text should be set by calling
func setTitle(_ title: String?, forState state: UIControlState)
The text toggles because you're selecting and de-selecting the button, which is switching between some of its states which have different titles.
You should set the button title text by using the following method...
self.testButton.setTitle(self.testEntry, forState: .Normal)
instead of titleLabel property.
Swift 5
self.testButton.setTitle("hello", for: .normal)

Xcode how to connect view to view using button ? (swift)

I'm making a custom keyboard using swift on Xcode.
I have created some views(xib files) which are of keyboards.
and I wanna connect these views each other like when I press [123]button, the view changes to the numeric one so I can type numbers :)
Actually I finished globe button(which is next keyboard button which is auto-created when I added custom keyboard target) but can't understand the codes ;-;
What I want to do is to connect button(as an IBOutlet or IBAction) with view(xib)
Take two views in xib or storyboard and IBOutlet them. One view has the buttons for alphabets and other view has buttons for numbers.
You have to do code something like below :
#IBOutlet var alphabelView: UIView!
#IBOutlet var numericView: UIView!
#IBOutlet var toggleBtn: UIButton!
btn.setTitle("ABC", forState: .Normal)
btn.setTitle("123", forState: .Selected)
toggleBtn.addTarget(self, action: #selector(self.toggleButtonsClicked(_:)), forControlEvents: .TouchUpInside)
Numeric view will be hidden initially. When user press on 123 do code like below lines of code:
func toggleButtonsClicked(button: UIButton) {
button.selected = !butto.selected
alphabelView.hidden = true
numericView.hidden = false
}

Re-write some basic swift code, with big if-statements

I am working on a project, with a UITabBarcontroller, in Xcode using swift code.
In this project the users can (among other stuff) choose their favorite images. These favorite images will be set on 30 buttons I have on my favorites UIViewController.
To accomplish what I want, I developed some very basic code: I assigned 30 IBOutlets for the 30 buttons and I made 30 (big) if-statements. It in fact works, but I know this code can be done in a simpler and more concise manner. And I am not yet able to do that.
I really want to learn, so can anybody help me with a way to rewrite this code? Help is much appreciated :). Just a push in the right direction would already be great
Should I for example assign tag values to the 30 buttons, and ‘find’ the appropriate buttons with .viewWithTag (instead of the 30 IBOutlets). And should I for example use some sort of loop for dealing with the different counts of the array? (see below)
Here is my code:
// I have created a subclass of UITabBarController
class TabBarData: UITabBarController {
/* In this class I have initialized an empty array to share between the various tabs.
The array will be populated with the favorites chosen by the user. */
var array = [Int]()
}
/* There are multiple ViewControllers in my project that have the same
code for adding a favorite. So for now I describe one example ViewController */
class exampleVC: UIViewController {
/* A variable that identifies the image by the number. There a a few
hundred images in the project, every images has its own identifying number */
var imageNumber = 0
// This function will execute if user adds a favorite:
func userAddedFavorite(imageNumber: Int) {
// The ViewController within the TabBarController getting acces to the properties
if let tbc = self.tabBarController as? TabBarData {
// The Array can not be bigger then a count of 30:
if tbc.array.count < 30 {
// When a user adds a new favorite image, the array gets filled with a new value:
tbc.array.append(imageNumber)
// Now I set the button images, in viewWillAppear, for my favorites VC:
class Favorites: UIViewController {
// IBOutlets for the 30 buttons
#IBOutlet weak var button1: UIButton!
#IBOutlet weak var button2: UIButton!
#IBOutlet weak var button3: UIButton!
// etcetera…
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
if let tbc = self.tabBarController as? TabBarData {
if tbc.array.isEmpty {
print("The user has no Favorites at the moment. The array is empty")
} else if tbc.array.count == 1 {
// At the moment the images in my project have been named: test1/test2/test3 etc...
button1.setImage(UIImage(named: "test\(tbc.array[0])"), forState: .Normal)
} else if tbc.array.count == 2 {
button1.setImage(UIImage(named: "test\(tbc.array[0])"), forState: .Normal)
button2.setImage(UIImage(named: "test\(tbc.array[1])"), forState: .Normal)
} else if tbc.array.count == 3 {
button1.setImage(UIImage(named: "test\(tbc.array[0])"), forState: .Normal)
button2.setImage(UIImage(named: "test\(tbc.array[1])"), forState: .Normal)
button3.setImage(UIImage(named: "test\(tbc.array[2])"), forState: .Normal)
} else {
print("etcetera.....,the if-statements getting bigger each count up......")
}
Instead of making 30 IBOutlets (one for each button,) make a single IBOutletCollection that holds all thirty:
#IBOutlet var buttons: [UIButton]!
Then you can:
for (index, item) in tbc.array.enumerate() {
buttons[index].setImage(UIImage(named: "test\(item)"), forState: .Normal)
}

Resources