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];
Related
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 :)
I am experimenting creating views that contain View based TableViews, ie: NSOutlineView and would like to better understand the correct connections that are made within IB.
At the moment, I have created a MainWindow that has the AppDelegate assigned to it.
On top of this, I have introduced a NSOutlineView which ultimately have an array as its data source.
I would like to have a separate Controller to look after this and its sub-views.
The NSOutlineView is made up of:
NSTableColumn
NSTableViewCell
NSTextField
With my NSTableCellView I have added two NSTextFields, the top one will be used as a Title and the second is a mini and will be used for displaying descriptions.
The issue I am facing is what controls need to have an IBOutlet connected to it.
My logic is; the only controls that will exhibit a change are the NSTableView as there needs to be a separate TableView within the TableColumn which will be a result of the item.count in the array.
Secondly, I am assuming that an IBOutlet will need to point to each of the TextField’s in the TableViewCell which will allow them to display the correct information for each item.count in the array.
So, all I need to do is design a Controller that has three IBOutlets.
Have I got my basics right….. or am I way off track?
I don't get everything you are asking for but first of all you don't set outlet to your NSTableView you need to use a NSArrayController, KVC and bindings.
1) in your AppDelegate.h create an IBOutlet to your NSArrayController:
#interface AppDelegate : NSObject <NSApplicationDelegate>
{
IBOutlet NSArrayController *yourArrayController;
}
2) in AppDelegate.m put your input or whatever in the NSArrayController:
yourItem *newItem = [[yourItem alloc] init];
[newItem setValue:[_inputVar stringValue] forKey:#"name"]; //use Key Value Coding
...
[yourArrayController addObject:newItem];
3) now go to your .xib and draw a NSArrayController object (green bubble with 3 blue cubes) in the dock (the area left to the .xib).
4) in your tableview click three times at each row and open the Bindings inspector
5) go to "Value" and activate "Bind to", select yourArrayController
6) set Controller Key to "arrangedObjects"
7) write the appropriate key in Model Key Path
Do that for each tableview column and you should be fine basically. No IBOutlet from the controller to you NSTableView!
The NSArrayController is taking care about user input back an forth to and from your tableview which is pretty convenient. I know not to answer all your questions but it might help you to get started. Good luck!
I created a custom view. It has a delegate that it will notify when some of its buttons are pressed.
I added this to the view controller's viewDidLoad:
self.myCustomView.delegate=self;
So far everything works fine.
But that's not cool enough. I want to do it the table view style where I can just right drag from the view to the File's Owner and (ta-da!) it's automatically set.
Add the IBOutlet keyword to the delegate property of your class:
#property (nonatomic, assign) IBOutlet id<MyViewDelegate> delegate;
The IBOutlet keyword tells the nib editor to let you make a connection to that property.
You could also say this:
#property (nonatomic, assign) IBOutlet MyView *delegate;
And then IB will only allow you to connect it to a MyView. But a protocol or id is more flexible.
EDIT: One point has been lost due to focus on IB
You said:
I created a custom view. It has a delegate that it will notify when some of its buttons are pressed.
Receiving button events is the role of a view controller, sometimes however a delegate will be used for finer grained control of certain events.
In general dont create a delegate for button presses on a view that is a primary window in which case you should be handling your button events in a ViewController. Buttons sit on a parent view that will forward events up the responder chain (you still need to connect them to a target). Im not saying you shouldn't ever use the delegate pattern for button presses but, buttons have their own connections to view controllers in IB with drag and drop as you wish. But there are situations like yours which are perfectly valid.
I know the differences between IBAction and IBOutlet, but I don't know when I should use one over the other.
For example, I'm trying to make a calculator. I have ten buttons and one label to display a result. Must I create ten IBOutlets in my interface? If not, why not?
An IBOutlet is a connection to an object, and an IBAction is a connection to a method to be invoked as a callback. For example, you might have ten buttons and one label, but you might connect to the label using an IBOutlet (so you can update its value), and a single function - (IBAction)buttonPressed:(id)sender; that is connected to the onTouchUpInside event of each of the ten buttons. The buttonPressed: method's implementation will then need to inspect the sender to figure out what its value is.
You should not need to have an IBOutlet for each button if this is all you need to do.
Ok, IBOutlets and IBActions serve two separate purposes.
IBActions are basically methods that can be connected to UI elements through IB. They provide ways for your object to be notified when something has happened with the UI. They also provide the sender argument when they are called so that you can access the UI Element that sent the message from within the method.
An IBOutlet on the other hand offers a way to get a reference to the UI element within your code at any point, it is used when you need to change aspects of the UI.
For your situation you don't really need to have IBOutlets for the buttons because you don't need to change anything about them, you just need to be notified when they have been pressed.
As a note, if you have that many buttons, and you for some reason needed a way to access them from within your code to change something about them i would not recommend using 10 IBOutlets. Instead, i would use the viewWithTag: method, and set each buttons tag accordingly so that you don't have to go to the trouble of creating IBOutlets for each one.
In your case, I would create one IBOutlet for the label, and one IBAction for the buttons. The IBOutlet for the label would be to update the text when the user pressed a button. Your IBAction would look something like this:
-(IBAction)digitPressed:(UIButton *)sender{
//First you have to check if there is currently any text in the label
//If there is not, the below line of code is performed
NSString *textWithDigit = [[yourLabel.text] stringByAppendingString: sender.titleLabel];
//This line updates the label's text
label.text = textWithDigit;
}
I only put in the code relevant to IBActions and IBOutlets (you need an IBOutlet for the label in order to update the text, and you need the IBAction to change the label's text to the digit pressed); there is much more code needed (code needed to check if the user is currently in the middle of typing a number, code for operations like +, -, *, /), but this was just a start.
Hope this helps!
I so far only have the interface builder layout
I'm not clear on the syntax to reference all of these items from the layout
I know that IBOutlet has to be used somewhere, but I need a bit more handholding on what this objective C is doing. Nothing I've read tells me exactly why some declarations start with + and others with -
What I want to do is click a button in my layout, have a modal view pop up and change the background on the entire layout.
so the first step is referencing all these items I've made in the nib. help? (or post a link to more intuitive tutorials that you know about)
So you probably want to create an IBOutlet for your background view. Maybe it's a UIImageView that you can set it's image property based on what the user selects in the modal view. For this you would just declare the UIImageView you have in your IB file
UIImageView *imageView;
and then declare it as a property
#property (nonatomic,retain)IBOutlet UIImageView *imageView;
and synthesize it in your .m file
#synthesize imageView;
Don't forget to release it if you're not using ARC.
Then you can open up interface builder and if you click on your view controller File's Owner and go to the connections inspector you will see there is a new connection there for imageView. Just drag that connection over to your UIImageView in the IB file and that's it. You now have a reference in your code that connects to your UIImageView in IB.
That will allow you to set the UIImageView in your code by typing something like
self.imageView.image = [UIImage imageNamed:theNameTheUserJustPicked];
In order to get the modal view, you need an IBAction to trigger a method in your code so declare one like this in your .h file of your main nib.
- (IBAction)displayViewBackgroundChooser;
and then define it in your .m file.
- (IBAction)displayViewBackgroundChooser {
//present your new view on screen here
}
Then go back to interface builder and click on the File's Owner again. You should see it there in the connections inspector and then you can connect it to a button, for example, that would trigger that method.
Hope this helps to clear things up a bit on IBOutlets and IBActions.
You can make your UI elements created in IB interact with your code by means of IBOutlets and IBActions.
In your case, I would associate an action to the button, so that it is fired when the button is clicked; the action would open a modal view, and you could change the background of that view in the viewDidLoad method of the associated controller.
Here you find a video tutorial about adding an outlet. And here, the same about actions.
About your doubt on + and -, - identifies a normal method defined in a class; + defines a class method, i.e., a method that you can call on the class directly, without having to instantiate it first. Have a look at this S.O. article for more.