I have a Calculator app. if a user press equal I want to change the background color of all my button(digit 1 to 9) should i have an outlet for each button(each button represent a digit) or there is a way to have one outlet that covers all buttons ?
You want an IBOutletCollection.
In Objective-C, it would look like this:
#property (nonatomic, strong) IBOutletCollection(UIButton) NSArray* buttons;
In Swift:
#IBOutlet var buttons: [UIButton] = []
Then connect each of your buttons to the buttons outlet in Interface Builder, and you can iterate through each easily.
You can loop all the elements in the UIView and change it programmatically using the code below
for view in self.view.subviews as [UIView] {
if let btn = view as? UIButton {
//do your changes here
btn.backgroundColor = UIColor.redColor()
}
}
There is a way
control drag each button to the same outlet from the storyBoard. This should hook up each button to one outlet if I am remembering correctly, give it a try and then update your background colors to see if this works.
Of course yes, you can have an outlet for each button if you wish
Related
I have just started coding not too long ago, so apologies in advance for any glaringly obvious mistakes.
I have created both buttons using the storyboard. I understand that you can change the sender button's title like how this solution stated it, but I was still not sure how to change the other button title when the first one is clicked. I have tried referencing tags, but nothing happened when I clicked the first button. Is it possible to do this? Please give an example if it is.
Goal: Change the title of one button by clicking another button, both created with Storyboard.
There are two solution to achieve this:
By using IBOutlets
By using Storyboard tags
Using IBOutlets, you can create an outlet of second button e.g.
#IBOutlet weak var btnSecond: UIButton!
Now change the title of this button in action of first button like this:
#IBAction clickFirstBtn(sender: UIButton){
btnSecond.set("New Title", for: .normal)
}
Using storyboard tags, you can give any tag to second button except 0. For example let the tag of second button = 10.
Now you change the title like this:
#IBAction clickFirstBtn(sender: UIButton){
if let btnSecond = view.viewWithTag(10) as? UIButton{
btnSecond.set("New Title", for: .normal)
}
}
(I'll answer to this question even if there already are correct answers because they both are showing swift solutions even if the question is expicitly about Objective C)
The simplest way, as stated in this other answer, is to assign outlets to the buttons. Ctrl-drag from the button in Interface Builder to the #interface of your ViewController and give the button an outlet name:
#interface ViewController ()
#property (weak, nonatomic) IBOutlet UIButton *button2;
#end
Then, in the first button's IBAction, call the setTitle:forControlState: method of the second button outlet
- (IBAction)button1Tapped:(id)sender {
[self.button2 setTitle:#"new title" forState:UIControlStateNormal];
}
As an alternative, you can also use storyboard tags (the fact that i used a UIView and then checked if isKindOfClass is to avoid crashes in case you mistakenly assign the same tag to some non-UIButton object):
- (IBAction)button1Tapped:(id)sender {
UIView *buttonView = [self.view viewWithTag:1002];
if ([buttonView isKindOfClass:[UIButton class] ]) {
[(UIButton *)buttonView setTitle:#"new title" forState:UIControlStateNormal];
}
}
Lets say you have Button1 and Button2 and you want to set the title of Button2 onclick of Button1.
You can do it by creating an action on the click of Button1 and setting the title of Button2 on this action..
Swift 3
override func viewDidLoad() {
super.viewDidLoad()
Button1.addTarget(self, action: #selector(setTitle), for: .touchUpInside)
}
#objc func setTitle()
{
Button2.setTitle("Button Title",for: UIControlState.Normal)
}
I try to do something like this #IBoutlet var buttons : [UIButton]
but I can't drag button to this outlet
Any idea, how can I achieve that?
It's possible to do that.
Here is how:
Create an array of IBOutlets
Add multiple UIElements (Views) in your Storyboard ViewController interface
Select ViewController (In storyboard) and open connection inspector
There is option 'Outlet Collections' in connection inspector (You will see an array of outlets there)
Connect if with your interface elements
-
class ViewController2: UIViewController {
#IBOutlet var collection:[UIView]!
override func viewDidLoad() {
super.viewDidLoad()
}
}
To add a button to an existing array outlet, drag the other way 'round: from the circle in the margin of the view controller to the button. (No need to hold the control key while doing this drag.)
I have one button in .xib file.
I want that if I will click on that button .xib file color of viewController should be changed.
How can I do that?
Should I use NSNotification or is there any other way to do this?
A UIViewController doesn't have a color. You might be talking about its root view, maybe tintColor from a UINavigationBar if it's embedded in a UINavigationController?
In any case, a IBAction connected to your UIButton will do what you want.
Connect your UIButton on xib with an IBAction within your class inherited from UIViewController and change the view property of UIViewController. You can do it using self.view.backgroundColor
Here is simple code snippet to do that. Hope it helps.
#IBAction func myButtonPressed(sender: AnyObject) {
self.view.backgroundColor = UIColor.redColor() //Or any color of your choice
}
I'm trying to use a UIBarButtonItem to put a title on my UIToolbar. I'm using the plain style and that looks fine, but I can't seem to get it to stop highlighting on touch. The Shows Touch When Highlighted option isn't available for the bar button items. Is there a quick and easy way to do this? I'm trying to do the building in interface builder so I can see what I'm doing. I'd prefer not to build the toolbar in the view did load every time.
The property responsible for this is accessible in the UIButton class:
myButton.showsTouchWhenHighlighted = NO;
You can access this (programmatically) in a UIBarButtonItem by assigning a UIButton to the bar button item's customView property, and configuring the button. You can do this in Interface Builder too: drag a UIButton onto a UIToolbar, and it will automatically embed it in a UIBarButtonItem for you - then look for the "Shows Touch On Highlight" checkbox under the button's settings.
Incidentally, I don't know how you're customising your buttons so feel free to ignore this, but if your button looks and behaves like a standard toolbar item then users will expect the glow effect.
I wanted a solution that could be used without any modification to my XIB structure.
The most obvious and simple one worked: subclass UIBarButtonItem:
UITitleBarButtonItem.h:
//
// UITitleBarButtonItem.m
// Created by Guillaume Cerquant - MacMation on 09/08/12.
//
/*
* A UIBarButtonItem that does not show any highlight on the touch
* Drag and drop a normal UIBarButtonItem in your xib and set its subclass to UITitleBarButtonItem
*/
#interface UITitleBarButtonItem : UIBarButtonItem
#end
UITitleBarButtonItem.m:
#import "UITitleBarButtonItem.h"
#implementation UITitleBarButtonItem
// Only caring about UITitleBarButtonItem set up in Interface Builder. Update this class if you need to instantiate it from code
- (void) awakeFromNib {
UIView *theView = [self valueForKey:#"view"];
if ([theView respondsToSelector:#selector(setUserInteractionEnabled:)]) {
theView.userInteractionEnabled = NO;
}
}
#end
Tested on iOS 5 and the one we aren't allowed to talk yet.
Alternative: Use a UIBarButtonItem in the plain style and additionally cover the toolbar in the appropriate area with a UIView that has a clear background. The view consumes the taps and hides them from the bar button item. Make sure you set the autoresizing mask correctly.
My solution was to set it to disabled, and adjust the titleAttributes for each UIControlState
let attributes: [NSAttributedStringKey: Any] = [
.font: UIFont.boldSystemFont(ofSize: 16),
.foregroundColor: UIColor.white
]
barButton.setTitleTextAttributes(attributes, for: .enabled)
barButton.setTitleTextAttributes(attributes, for: .disabled)
barButton.isEnabled = false
I want to make an array with a bunch of UIImageViews I have in Interface Builder. Instead of having 20 or 30
IBOutlet UIImageView *img1;
and linking them all that way, and then putting them into an array, is there a way to declare an array of IBOutlet UIImageViews?
Just so I don't have so many declarations in my header file.
It is possible, it’s called outlet collection. This is the way to define an outlet collection:
#property(retain) IBOutletCollection(UIImageView) NSArray *images;
Now you can stick more than one object into the outlet in the Interface Builder, the array will be created for you when the interface is loaded.
I'm a little late here but it may be easier to set the tag property of each ImageView in IB, then access them like [some_superview viewWithTag:tag] rather than keep a separate handle to each one.
Here is more easier way to do it.
Follow these steps to create an array of outlets an connect it with IB Elements:
Create an array of IBOutlets
Add multiple UIElements (Views) in your Storyboard ViewController interface
Select ViewController (In storyboard) and open connection inspector
There is option 'Outlet Collections' in connection inspector (You will see an array of outlets there)
Connect if with your interface elements
-
class ViewController2: UIViewController {
#IBOutlet var collection:[UIView]!
override func viewDidLoad() {
super.viewDidLoad()
}
}
Swift 3 and above:
#IBOutlet var stuckLabels: [UIImageView]
There's not, unfortunately, but you can keep all of the declarations on a single line:
IBOutlet UIImageView *img1, *img2, *img3, *img4;
The other option (probably best, since you have so many of these) would be to create them programatically and store them in an array, then add them to the view from your view controller class, using, for each,
[self.view addSubview:img];
Also, keep in mind that if the elements are static (like background elements), and you don't actually need to access them, you don't need to declare outlets for each; you can just add them to the nib file and forget about them.
Same goes for UIButton instances. If you don't need to change anything about the button, you can access it from the method that it calls, like so:
-(IBAction) buttonPressed:(id)sender {
UIButton *button = (UIButton *)sender;
// method guts
// stuff with button -- access tag, disable, etc
}