I am reasonably new to Xcode and Objective C.
I have successfully loaded all of the GUI objects on one of my views dynamically..
Now i want to repeat the same dynamically loaded content onto all or most of my views..
I have a method in the main view like this:
-(void)loadinfo:(id)sender{
//All dynamically loaded content etc..
}
I currently have the main view calling this method like so.
[self loadinfo];
So now i need to know (without copying and pasting the method into all of my views) how to call the method from the main view into other views?
I hope this all makes sense.
Edit
I am more knowledgeable in PHP so if i was to do the same thing in php i would make a file called functions.php and include that file into all of the pages.. Is it the same concept?
The concept is different from the approach you find with functions in PHP. In Objective C one works with objects. To share behavior (your PHP functions, called methods in Objective C) between objects you need to slot that behavior somewhere into your class hierarchy.
So for your specific case you would implement the loadinfo method in a generic class which is a subclass of NSView, say MyGenericView. Both your view1 and view2 classes would then subclass from that generic class and inherit the loadinfo method.
In case you want to divert from the implementation of loadinfo in your base class, you can override it partially by doing (in view1 or view2):
- (void) loadview {
[super loadview]; // perform the default implementation
[self doSomethingDifferint]; // perform subclass specific stuff
}
... or:
- (void) loadview {
[self doSomethingDifferint]; // perform subclass specific stuff
[super loadview]; // perform the default implementation
}
... or override completely by doing:
- (void) loadview {
[self doSomethingCompletelyDifferent]; // perform subclass specific stuff
}
Just on a side note: it's good practice to follow CamelCase standards when naming your classes and methods in Objective C, so your classes would be View1 and View2 and the method would be loadInfo.
Further, you might want to read up on generic OO principles and Objective C's specific aspects of it to take full advantage of the language and its features.
You should subclass the view that has all your dynamically-loaded UI content. So if you have:
#interface MyCustomView : UIViewController
{
}
#property (strong, nonatomic) UIView *aView;
-(void)someMethod;
#end
You can create a subclass that will inherit all of the properties, methods, etc:
#interface FirstView : MyCustomView
{
}
//all properties and methods of MyCustomView are inherited
#end
Do this for any number of views that you want to create.
Related
I want to implement two functionalities as color filling and view magnifying in my app. But the problem is that i can't be able to implement these two functionalities at same time. Because i have to specify two difference class reference for two functionalities to my UIView, which can't be possible.
In other words, I have one view and i have given class reference as UIView (for color function). But for magnify function , i have to give class reference as MagnifyingView to that view. So, it is not possible to implement these two functionalities at same time.
So how can i give UIView and ACMagnifyingView two different class reference to single UIView at different conditions?
How can i do this ?
Thanks.
Have you tried Categories? check this tutorial http://iphone-obsessed.blogspot.com.br/2010/05/tutorial-creating-class-categories-in.html
can you provide more information? maybe if you provide more info i could help you more
EDIT
How Categories work:
you have a UIView class and you want some methods to use that you repeat a lot. what do you do: you create a category of UIView and add this method to your category, like this:
file UIView+CustomView.h
#import <UIKit/UIKit.h>
#interface UIView (CustomView)
- (void)myCustomMethod;
#end
file UIView+CustomView.m
#import "UIView+CustomView.h"
#implementation UIView (CustomView)
- (void)myCustomMethod {
// Whatever you want to do with this UIView
}
#end
now, every time you need to use the myCustomMethod you just have to import UIView+CustomView.h and all UIView objects inside that class will have access to this method.
like this:
file MainViewController.m, header:
#import "UIView+CustomView.h"
file MainViewController.m, body, inside any method:
[myView myCustomMethod];
with this in mind i believe you could add your ACMagnifyingView as a subclass and this category to use your custom view
I need to use the same set of code in 4 view controllers. I am writing this code in -(void)viewWillAppear.
Is there any possibility that I can write this code once and use it in all 4 view controllers?
You could make a subclass of UIViewController with the common code, and then change each of your existing UIViewController subclasses to be a subclass of that new class.
You can create a static class and call the method from there:
#interface myClass : NSObject
+(void)myMethod{
#end
+(void)myMethod{
//Do my stuff
}
And then you call the method from wherever you want:
[myClass myMethod];
Write the code in viewWillAppear in a custom class which subclass of UIViewController.
Then create that 4 classes by subclassing of your custom class.
And call [super viewWillAppear].
Are there alternatives to "delegates" to pass back data from one controller to another?
Just seems like a lot of work implementing a delegate just to pass back the result from a child controller, back to the parent controller. Is there not another method? Are "blocks" one answer, and if so some example code would be great.
Delegates aren't a lot of work, aren't a lot of code, and are commonly the most appropriate solution. In my opinion they're neither difficult nor messy.
Five lines of code in the child's interface. Before #interface:
#protocol MyUsefulDelegate <NSObject>
- (void)infoReturned:(id)objectReturned;
#end
Inside #interface:
id <MyUsefulDelegate> muDelegate;
After #inteface's #end:
#property (assign) id <MyUsefulDelegate> muDelegate;
One line of code in the child's implementation:
[[self muDelegate] infoReturned:yourReturnObject];
One addition to an existing line of code in the parent's interface:
#interface YourParentViewController : UIViewController <MyUsefulDelegate>
Three lines of code in the parent's implementation. Somewhere before you call the child:
[childVC setMuDelegate:self];
Anywhere in the implementation:
- (void)infoReturned:(id)objectReturned {
// Do something with the returned value here
}
A total of nine lines of code, one of which is merely an addition to an existing line of code and one of which is a closing curly brace.
It's not as simple as a returning a value from a local method, say, but once you're used to the pattern it's super straightforward, and it has the power of allowing you do do all kinds of more complex stuff.
You could use many ways:
Calling a method of the super controller, needs casting maybe
Notifications
Simple Key-Value-Observing
Core Data
Example for for 1.
interface of your MainViewController: add a public method for the data to be passed
- (void)newDataArrivedWithString:(NSString *)aString;
MainViewController showing ChildController
- (void)showChildController
{
ChildController *childController = [[ChildController alloc] init];
childController.mainViewController = self;
[self presentModalViewController:childController animated:YES];
[childController release];
}
Child Controller header / interface: add a property for the mainViewController
#class MainViewController;
#interface ChildController : UIViewController {
MainViewController *mainViewController;
}
#property (nonatomic, retain) MainViewController *mainViewController;
Child Controller passing data to the MainViewController
- (void)passDataToMainViewController
{
NSString * someDataToPass = #"foo!";
[self.mainViewController newDataArrivedWithString:someDataToPass];
}
KVO or notifications are the way to go in many cases, but delegation gives a very good foundation to build upon. If you plan on extending the relationship between the view controllers in the future, consider using delegation.
Blocks are not really relevant to the above, but in short - it is a technique introduced with iOS 4, where you pass around blocks of code as variables/ parameters. It is very powerful and has many uses. For example, here is how you enumerate objects in an array using a block:
[someArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop){
NSLog(#"obj descriptions is - %#", [obj description]);
}];
The part from the ^ until the } is a block. Note that I've passed it in as parameter. Now, this block of code will be executed for every object in the array (i.e. output will be the description of each object).
Blocks are also very efficient performance-wise, and are used heavily in many new frameworks.
Apple's blocks beginners guide is quite good.
Check out NSNotificationCenter — NSNotificationCenter Class Reference
Folks pay a lot of attention the the V and the C in MVC, but often forget the M. If you've got a data model, you can pass it from one controller to the next. When one controller makes changes to the data stored in the model, all the other controllers that share the same model will automatically get the changes.
You might find using a singleton is practical. Just use it as a central storage for all your shared data.
Then throw in saving the state of your application too;)
This may be a silly question but I haven't found any information on it.
Let's say several of the classes in my program derive from 'MySubView' which is derived from another class, UIViewController.
I would declare it like this:
#interface NewViewController : MySubView {
// code ...
}
#end
In the future the client wants a change, and desires another view with a table. So I would need to make another class, called MySubTableView, that is a UITableViewController subclassed from MySubView.
I was thinking this would be easier if I could do something like this:
#interface NewViewController : UITableViewController : MySubView {
// code ...
}
#end
But this doesn't work.
Is there a way to do this with Xcode, or do I have to specifically make the class itself?
EDIT:
I'm not looking for multiple inheritance. A straight inheritance hierarchy would follow:
NewViewController
UITableviewController
MySubView
UIViewController
No, Objective-C doesn't support declaring those kind of (vertical) inheritance chains. You can only specify the direct super class.
Even if it was possible, there would be problems like calling the correct initializers as they won't be called automatically. Consider a hierarchy like A : B : C - now you can initialize B using e.g. [super init] in As initializer, but how would B know what initializer you want it to call for C?
Objective-C doesn't support multiple inheritance... But Objective-C programmers rarely miss it, because you can accomplish many of the same tasks using Categories instead. Read up on Objective-C Categories.
My question is simple actually, how do I create an object to act as a delegate, instead of including the delegate methods in my view?
For example, I have x functionality that requires delegate methods, and they're currently setup to use self as the delegate. I'd like to put those methods in their own object so that the delegate methods can be called and do stuff if the view has ended.
What's the best way?
for example, NSXMLParser delegate methods - they exist, the delegate is defined, but I dont want to call them as self in my view controller... what other option do I have?
You can specify another custom class to handle the delegate methods, if you wish. Simply create a class, call it MyXMLParserDelegate or something similar. Then, all you have to do is tell your NSXMLParser object that it should use an instance of your class as its delegate.
If you are using Interface Builder, add a new object to the XIB file, set its class to MyXMLParserDelegate, and then drag a connection from your NSXMLParser object's delegate selector to the new object.
If you are doing it programmatically, the basic operation looks like this:
MyXMLParserDelegate * myDelegate = [[MyXMLParserDelegate alloc] init];
[someXMLParser setDelegate:myDelegate];
Keep in mind, however, that delegates are not retained, so in order to do this without leaking memory, you should add an ivar of type MyXMLParserDelegate to your viewController class, and then do the following:
// in your #interface block:
{
...
MyXMLParserDelegate * myDelegate;
}
// in your init method:
myDelegate = [[MyXMLParserDelegate alloc] init];
// in your awakeFromNib method (or anywhere else it seems appropriate):
[someXMLParser setDelegate:myDelegate];
// in your dealloc method:
[myDelegate release];
Check out this answer, I think it covers what you need: How to use custom delegates in Objective-C