Initializing IB Controls Programmatically in iOS - objective-c

I have a simple app and I want to load initial settings for the UI elements. But I don't want to have to IBOutlet each one of them. Is there a way to address them programmatically and set their values. for example:
if (user hasn't created a default){
// load the default settings
button1 = 12;
label.text = text;
etc...
}

The entire purpose of IBOutlet is so that you can set and get their values programmatically, so I don't quite understand why you wouldn't use IBOutlet. Usually when you create in Interface Builder you use IBOutlets for anything you need to interact with programmatically. (Obviously, when create them programmatically, you don't need an IBOutlet.)
But if you really want to add the controls in Interface Builder and not use IBOutlets, you could set the numeric tag property with some unique value in the attributes inspector under the "view" settings. You can then programmatically retrieve the reference for that from your view controller as [self.view viewWithTag:tagNumber];. This is more awkward and less efficient, so I'd really encourage you to use IBOutlet. Is there some compelling reason not to?

For UIButtons is
[button addTarget:self action:#selector(signatureOfYourMethod) forControlEvents:UIControlEventTouchUpInside];

Related

Change a button's background image programmatically in cocoa

All of the topics that I have searched are outdated or not complete in Obj-c.
I need to learn how to change a button's background image programmatically, when having the actual button in the InterfaceBuilder. (This sounds odd, but I need it for NSCollectionView as I have many similar button with different background images).
In the interface builder I drag a button onto my view window, what should I do after?
I understand that:
I need to create a NSButton Class
Connect the button from the interface builder to the code
Set the image
I have been struggling with this.
So did you connect the button to an IBOutlet property? If so then all you need to do is use [button setImage:]
If you haven't already done so, make sure the object instance that you want to change the image from is in interface builder, I.e has been dropped in as one of those blue boxes. Then if you set the object's class and have an IBOutlet property in the header file you can just drag the button outlet in the outlets tab (looks like an arrow) to the actual button itself to link the two
Edit: So it appears you're having trouble with the actual connecting part of the button? Chances are your IB file looks a bit like this:
Look for the objects section in the left hand list. These are the actual objects in your code that you can connect your button to. You might see an app delegate object there, which is included in the default IB file generated when you first create a project. If you want to handle the image changing in your app delegate, then simply add this property to your AppDelegate.h file to create an outlet:
#property IBOutlet NSButton *button;
If you go back to interface builder and select the app delegate object, you can see the outlet that you just created under the outlet tab:
Drag the little circle thing to the button to connect it, that should be the easiest bit.
But I'm going to just presume that you want to call it from somewhere else other than your app delegate, and for that we'll need to do some more explaining. If the class you want to call it from is a subclass of NSView and is already in your interface builder, you can just add that line to your view's header file and it will appear under the view's outlet tab.
If you want to call this from another object that isn't a view or such, you'll need to do either two options:
Create the object instance in interface builder. This means that instead of creating in normally with alloc] init]; etc. you'll have to actually drag in an object into interface builder. This can change the structure of your object quite a bit as you'll no longer be able to create it at will, since it will automatically be instantiated whenever you load your .nib file. Also important to note is that your init function will not be called anymore and you'll need to use awakeFromNib instead. If you do choose to go down this route, just drag over an object:
Add your outlet property to the header file:
Set the object's class:
And connect the outlet:
If making objects XIB loaded just isn't your thing, you can always just connect the property outlet to your app delegate/view controller and access it from that instead. Hopefully this clears things up, if this was the problem you were having.
For iOS:
Don't need to create a NSButton subclass.
You only need to add button on Storyboard, set the IBOutlet property for your button (ctr+drag from your button to your view controller), and set the background image with:
[myButton setBackgroundImage:[UIImage imageNamed:#"ImageName"] forState:UIControlStateNormal]
For MacOS:
You can use
setImage:
as describe on Apple Doc, and changes its size/position
(Sorry for my bad English)
ofcourse as Duukee Said,i think no need to create any NSButton Or UIButton Instances Manually When We have an object in Interface Builder,We can just use it's outlet as follows,
UIImage* Desired_Image=[UIImage imageNamed:#"yourimage.png"];
[My_Button setimage:Desired_Image forState:UIcontrolstateNormal];
HTH!Happy Coding :)

iOS Objective C - A pointer to Interface Control on viewDidLoad

i am new into ObjC, unfortunately..
I have created a list and Tool bar at the bottom, with two buttons.
The first button does the list refresh,
the second one should be 'enabled' when you tap on a list item and when clicked it will perform additional work. This requires me to disable this button on start, but enable on didSelectRowAtIndexPath.
I want to grab a pointer to the second button on viewDidLoad method for later purposes.
Something like that would be great:
UIBarButtonItem* m_pButtonA = (UIBarButtonItem*) some_magic_function_to_call;
UIBarButtonItem* m_pButtonB = (UIBarButtonItem*) some_magic_function_to_call;
So i can later call the control method when required.
[m_pButtonRefresh method...]
Is this possible ? Thanks for any input.
In your custom view controller class, create an IBOutlet property, like this:
#property (nonatomic, weak) IBOutlet UIBarButtonItem* m_pButtonA;
#property (nonatomic, weak) IBOutlet UIBarButtonItem* m_pButtonB;
(I'd suggest using more descriptive names)
Then, in Interface Builder you can set those properties to be the Reference Outlet for each of those views (drag from the little (+) to the view control in the left sidebar in IB, and select the appropriate property).
You'll then be able to access those items using code along the lines of self.m_pButtonA. You don't need to manually create the reference to them, as the code will automatically generate them.
This is somewhat similar to the approach you would use when connecting GUI events to methods in the view controller (those would use methods labeled with type IBAction), that are triggered automatically when those events are raised. Both IBOutlet and IBAction are just little hints for Interface Builder (IBAction is actually just another name for void).
Sounds like you're coming from an Android background? You should read about outlets, the equivalent to what you're looking for.
See Apple's cheat sheet, Cocoa Application Competencies for iOS, which links to more thorough documentation if you need it.
Ok, i have found the answer here
Get UIButton reference from viewDidLoad
Long story short:
Just give tag to your button and access your button with tag value.
UIButton *btn = (UIButton*)[self.view viewWithTag:1];
[btn setHidden:YES];

MVC and the use of a UIButton to dynamically create UI elements

I understand the concept of MVC. At least I hope I do but there is a particular situation that I have encountered recently that makes me think that I actually have no idea.
Problem:
I am trying to create a class that when applied to an existing button adds the functionality of editing that button's title. It does so by dynamically generating a UITextField that will in turn be populated with the Button's new name. I hold the logic of adding the UITextField in a class called CustomAnimation and initializing it in the following way:
CustomAnimation *yar = [[CustomAnimation alloc] initWithButton:customButton];
The problem that I encounter is when I am trying to dynamically create a UIButton from a custom class like CustomAnimation and try to assign a target/action to it. Since the UIButton is actually generated inside the ViewController FROM the CustomAnimation class the former should get a pointer to the parent ViewController and then set it as the target.
[classButton addTarget:viewController action:#selector(dostuff:) forControlEvents:UIControlEventTouchUpInside];
All is good except one thing - dostuff method should reside inside the ViewController in order to be visible for that button and here everything turns into a hack.
What is the correct approach when you want to generate temporary UI elements from inside a Class instead of the Controller?
Thank you
There are lots of ways you can look at MVC in terms of granularity. If I understand your question correctly you are trying to implement MVC at a single control level which is - in my opinion - too finely grained. I try to aim for a more coarse approch where a controller manages a chunk of UI controls, e.g. a view or a window.
You could argue that the editability of the buttons label is bahavior that belongs to the button (encapsulated by it), hence its implementation is or should be part of the overall implementation of the button. Once you accept that, you could implement this as a subclass of UIButton and move the code that is in CustomAnimation to your subclass of UIButton. Or encapsulate CustomAnimation in your subclass of UIButton, whichever is more appriopriate.

Should I use IB or Subclass UIView

So, I developed a kind of drop down button class.
Let's call it DDButton.
I mainly export one function :
-(void) addButtonWithImage:(UIImage*)image andTarget:(id)target andSelector:(SEL)selector
which lets the user add another button to the drop down.
I will need to use DDButton in different screens of my app.
I would like to use it like:
DDButton* ddb = [[DDButton alloc] initWithFrame:rect];
[ddb addButtonWithImage....]
[ddb addButtonWithImage....]
My question is since I never subclassed UIView before how should I implement it, and how should I use it later ?
Do I use IB and create a stub UIView which I'll connect to the DDButton in the Identity Pane ?
if so , how exactly I instantiate the view later on.
Or,
Do I subclass UIView ? if so , what methods I should override ? Do you I setup my buttons in the initializer ? in LayoutSubView ? In drawRect ?
I would love to hear the best approach here.
Thanks!
Edit
Let's say I choose the IB way : I have a main button which I set regardless of the
addButtonWithImage() calls, actually all calls to addButtonWithImage just "append" to that button. I want to main button to be the size of the view, until other buttons are added and then the view grows appropriately. However, I want the size of the view to be chosen by the user at first...using setFrame I guess.
Meaning in the awakeFromNib I can't count on the frame size yet (it only take the xib size I assume). So where would I setup my main button ? LayoutSubView ? setFrame ? I'm not sure.
Add your view to the interface in IB as a UIView, then change the class in the identity pane. If you need to do initialization in code, use a -(void)awakeFromNib method. I would suggest setting up the buttons when they are added in addButtonWithImage....
I'd probably do a subclass, building views in code is a good thing to learn.
Override drawrect: to do any custom drawing you need to do, if you're just adding a UIImageview or something and doing positioning you could just override initWith...: and do your custom initialisations.

Add a second image to a custom UIButton

I've got an Custom UIButton. It's got
a "static" background image
a variable text (the Title) which gets set in the code
Now I would like to add an icon (UIImage/UIImageView) inside the button on the left of the text. (I use the indent to move the text slightly to the right). Is there an easy way of adding that icon (and referencing it from code, so I can change it) or would you recommend creating a completely new button e.g. based on a UIView? (e.g. a view, that responds to touches)?
I'm just trying to get a feel for what the best approach would be for this. Any experience?
Two ways:
I prefer doing this by subclassing a UIView and (as you mention) implement the UITouch-responder methods. You're also able to override drawRect: what I really like because it makes your app soooooo much faster!
Since UIButton is a subclass of UIView, you can add a UIImageView to your button by using addSubview:. If you save it in your main-class (#property (...) UIButton *button) you can always access it by calling [self button]. You can also subclass your UIButton and add this #property. That's up to you.
It's totally up to you. However I prefer the first way!