What is the best way to delegate UIButtons,UITextFields etc? - cocoa-touch

In all my apps I am delegating all my UIButtons,UITextField,pickers etc.I am able to delegate these by 3 ways.
1-I am simply control+dragging the buttons,text field etc from the story board to the .h file which creates the delegation directly.
2-In .h file I am creating the buttons,text fields etc and then making the connections.
3-Programmatically doing the delegations
I want to know which is the best way to do it.

Best way is to use storyboard for referencing outlets and delegates. If you are not able to use storyboards then you do by codding. Storyboards will save your time of codding there is no major difference then this.

That is depending on you,you can do any way based on your
requirement,but Final result is same for all three methods.
if you want to create dynamic labels and buttons at that time you must
use programatical method because you don't have any other solution
,like that you can do it by your choice based on your requirement.

They are equivalent. It's the same question as "is it better to write my UI programmatically or design it with Interface Builder?". The end result is the same; you should think about Interface Builder as simply a convenience tool and mechanism for creating interfaces and logic quickly. And if you need, you can mix both methods without problems.
When you drag your control from the IB sheet to your controller's code, you're creating a target-action association that is stored in the .xib file. When the .xib file is unpacked at runtime, your controls are created and their connections are restored, the same as if you did that programmatically.

Related

Objective-C: Creating a file purely for holding variables

I would like to add a file to my project, who's sole purpose would be to hold an array. I would then #import this file wherever I need to add/get from the array.
My problem is that when I create a new file (I'm using Xcode 4), I'm not sure what type of template to choose, and then what subclass to choose.
My reason for doing all of this is because I have a SplitView-Based app, and one of the views has a textfield, where I am trying to output data. My problem is that whenever I switch to a different view and then switch back, only the most recent entry is there. I am not 100% why that is but I suspect it is because when I switch to a different view, the current view is forgotten about, along with the variables in it.
This is not a good way to do it. There are many ways to do what you want: prepareForSegue: if you are using storyboards, delegation, instantiating your viewcontroller in code and setting a property in the header-file..those are just a few ways.
The way you are proposing is a slippery slope to bad Objective-C code and is only going to cause you more headaches in the future. Take the time to learn to do it right.
Check out this to get you thinking in the right direction.
How you save your data doesn't appear to be your problem. Take a look at the MVC design pattern and how view controllers implement it. They often rely on a dataSource protocol, which links the data from a "Model" to your "View" in a logical way to achieve your intended purpose.
The view controller should then be able to assign a delegate (usually itself (self) to keep the view populated with the correct data, whether the view gets unloaded or not.
If your view controller doesn't refer to a data source or a corresponding protocol, it would still be worth your time to see how you might take advantage of that design pattern. It will pay off in the long run to know this.
Instead of saving variables to a text file, you should consider using NSUserdefaults instead.
But I don't think that's the real solution to your problem, just wanted you know that there are other ways than saving stuff to a text file.

How to use classes to control windows in Objective-C

I have been making applications for Mac with Objective-C for about a year now but due to not really understanding how to use classes properly I have only ever used the 'AppDelegate' files. I want to start using classes as soon as possible because from what I understand it's very bad practice to clump it in to one class. Basically, how do I have two windows, each controlled by it's own class. I understand how to make objects similar to NSString or something but don't understand how to have classes that control windows etc.
Thanks
Edit: Basically I want to know how to split up my application in to classes.
If I understand you correctly then you need to create individual controller classes sporting their own IBOutlets and IBActions and hook these up to your UI elements. To split up an existing application into smaller classes requires some knowledge of Object Oriented programming.
Alternatively, you might benefit from reading this (or a similar) book:
'Cocoa Programming for Mac OS X' by Aaron Hillegass.
Try looking for NSWindowController in the docs. You create a custom subclass of NSWindowController and a xib file for it. In the xib file, make sure you set the class on the File's Owner to your custom subclass, and make sure its window outlet is connected to the window in the xib. If all that sounds totally foreign, head for the books! =)
Then, in the code where you want to bring this window onto the screen, you create an instance of your custom subclass and associate it with the xib, like so:
MyCustomWindowController *controller = [[MyCustomWindowController alloc] initWithWindowNibName:#"myxib"]
[controller showWindow:self];
The xib loading system will hook up all your custom outlets and actions on the new controller, and you can show it or do other wonderful NSWindowController things.

XCode/Cocoa Objective-C - A couple questions

Sorry for the stupid post, but I am new to Objective-C programming and Cocoa and have a couple of questions which I can't find the answers to, I'm hoping someone can enlighten me.
Firstly, in XCode, when using the Interface builder, when I want to create a new object I drag the object to my 'assets'. However I can't specify methods or anything without manually creating a new class file. Is there any point using the interface builder's 'object'?
The first app I built to test things with, I put most of the code in the AppDelegate class files. Research has shown me that the AppDelegate's purpose is simply handling application events like launching and closing. Was I wrong in putting the methods in this class? Does it make any difference?
Finally, if I have several class files created, each handling their own functionality with an interface built and linked to the classes, then what do I do with the 'main' file? It seems to me that the 'main' file and 'appdelegate' class files will be for the most case left as-is?
I hope that makes sense. Again i'm sorry for the silly-sounding questions but I can't find any answers.
Thanks in advance everyone!
Firstly, in XCode, when using the Interface builder, when I want to create a new object I drag the object to my 'assets'. However I can't specify methods or anything without manually creating a new class file.
Sure you can. Just set the class of the object using the inspector.
Note that you can only connect nib objects to an outlet or action. You can't specify any random methods, nor should you—the whole point of the IBOutlet, IBOutletCollection, and IBAction keywords is to declare in code that these properties/methods are used by a nib.
Is there any point using the interface builder's 'object'?
Yes, but pretty rarely. Usually you create objects in code and connect outlets to them.
The application's delegate is one object you may want to create in the MainMenu or MainWindow nib, if you build your application that way (the iOS templates have changed away from it for some reason).
The first app I built to test things with, I put most of the code in the AppDelegate class files. Research has shown me that the AppDelegate's purpose is simply handling application events like launching and closing. Was I wrong in putting the methods in this class?
Probably. The application's delegate generally should only handle business relating to the NS/UIApplicationDelegate protocol.
On the flip side, it's OK to make your root view controller the application's delegate, if it makes sense to do so (and the NS/UIApplicationDelegate implementation code is not too voluminous). The question you have to answer—and only you can answer it for your application—is whether you are making your root view controller the application's delegate or the application's delegate the root view controller. If in doubt, keep them separate.
Does it make any difference?
Long-term, yes. It's very easy, especially in the class of the application's delegate, to create a Big Ball of Mud class—one without well-defined and clearly-delineated responsibilities. Take dynamite to such a class as soon as possible.
Finally, if I have several class files created, each handling their own functionality with an interface built and linked to the classes, then what do I do with the 'main' file? It seems to me that the 'main' file and 'appdelegate' class files will be for the most case left as-is?
Yes. They're boiler-plate.
If you haven't written any code in the application's delegate (or have removed everything you had put there into new and better-delineated classes), such that all that's left are empty method bodies or none at all, you can safely remove the application's delegate. You can always create it again later if you change your mind.
Note that if you delete your application delegate class, you should also change the main.m file—or the MainMenu/MainWindow nib, if you have one—to not refer to it. Your application won't build if your UIApplicationMain call (or any other code) refers to a class that doesn't exist, and it will crash if your MainMenu/MainWindow nib (or any other nib) refers to a class that doesn't exist.
There is no shame in your application having a delegate if you need it to, but if you don't, removing it and the class you were using for it eliminates future temptation to stuff code there or use it to store third-order globals.
The point of using objects in interface builder is to connect methods of the object to UI elements.
It partly depends on what your methods are doing, but for the most part the app delegate class is going to be left alone. It isn't an actual requirement (your program will work either way) but it is common practice because it generally creates more maintainable code. The app delegate should just handle the application events ( using other classes to do any complex logic or heavy lifting ).
The 'main' file will most likely not change. I can't think of any reason to do so, but I wouldn't rule it out for some advanced cases.
To be honest I only used the Object thing in IB once, when I wanted a separate object to have some UI bindings.
About the app delegate and main file, yes, you'll leave them as-is most of the time. But if you try to do something besides test apps you'll need to handle open events to, for example, connect to a server, ask the user for a review, increment some launch counter, etc... Those are just examples!
The main file I advise you to left it alone and use the object oriented tools provided. You should have a view controller hierarchy, isolate your views from the data, and use the view controller to comunicate between view and model. Read about MVC if you want more info on how your application should be organized.

How to add a "lock" button that links two sliders together in Interface builder?

I want to add a button that when pressed will lock two sliders together such that the values for the two sliders will always be the same.
I have a solution for this using code, but I'm wondering if there is a way to do this with interface builder alone.
I am worried that the code based solution that one slider may lag behind the other in high CPU utilization environments.
No, there is no way to do this with Interface Builder alone.
Actually everything becomes code in the end, as far as I understand, Interface Builder was built to improve the development time, not necessarily to improve performance, I found this interesting quote on Apple's site about NIBs:
Xcode works in conjunction with these frameworks to help you connect
the controls of your user interface to the objects in your project
that respond to those controls.
Taking into account that, everything will become code (of some level). About NIB files.
At runtime, these descriptions are used to recreate the objects and
their configuration inside your application. When you load a nib file
at runtime, you get an exact replica of the objects that were in your
Xcode document. The nib-loading code instantiates the objects,
configures them, and reestablishes any inter-object connections that
you created in your nib file.
If you would really want to avoid such behavior probably the best you would be able to do is create the widget from scratch, but that would be a totally different question.
Just curious, why wouldn't you want to use code?
Locking the two sliders together in IB is easy. And I've never seen lag. Having that lock dependent on the press of a button is another story, that would have to be done in code, but it would not be too complicated. Assuming you have outlets connected in IB and declared in the controller
-(IBAction)lockSliders:(id)sender {
[slider1 setContinuous:YES];
[slider1 takeIntegerValueFrom:slider2]; // or takeFloatValueFrom or takeDoubleValueFrom
[slider2 setContinuous:YES];
[slider2 takeIntegerValueFrom:slider1];
}

"Global" UIImagePicker Functionality for Multiple Classes

I'm working on an app that (among other things) uses UIImagePicker to grab an image from the device once the user has selected the SourceType by tapping the appropriate button. Different sections of the app will need to use this functionality, as well as the variable holding the image information once selected. When I first started the project I had all of my code to do this in a single class named ViewController. I'm now working on moving the individual sections of the app into their own classes, but I'd like to be able to have them all use the UIImagePicker functionality from a central location.
Along with the necessary UIImagePickerController methods and protocols, I have a method that presents a view with buttons for each available SourceType. Each of these buttons then send a message to methods to show the appropriate picker (or the camera). Once an image is selected, it is applied to a variable for use by the different sections.
I wanted to get suggestions on the best way to approach this before I went to deep down the wrong rabbit hole.
Thanks!
If a lot of your classes use this functionality, you can create a superclass (itself being a subclass of UIViewController).
This class will expose some method to launch the process you described, and some other to gather the information collected.
If you don't want to use inheritance, or you already to with another class, you can also create a separate class responsible for this process.
This class, which is not necessary a UIViewController, has to be instantiated and then called the same way the superclass described above.