how to give two different class reference to single UIView? - iphone

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

Related

How to Use Objective-C Categories

When you implement a category of a class in a file, will all the instances of that class be of the category by default?
I'm new to Objective-C and I'm trying to make my uneditable UITextView non-selectable. I came across this answer using a category:
https://stackoverflow.com/a/8013538/1533240
Which has the following solution:
#implementation UITextView (DisableCopyPaste)
-(BOOL) canBecomeFirstResponder
{
return NO;
}
#end
I added the snippet to my code, but it doesn't seem to be working in that I can still select the text. My declaration of the UITextView is the usual:
titleLabel = [[UITextView alloc] initWithFrame:frame];
I tried changing the declaration to [DisableCopyPaste alloc] but that didn't seem to work.. haha.
Thanks!
You misunderstand the point of categories. Categories add methods to an existing class. They must never be used to override existing methods. Doing so is undefined behavior (technically only undefined in one case, but you can't predict that case, so you must assume it applies).
If you need to override methods, you must subclass, not use categories. See the top answer to the question you linked.
When you implement a category of a class in a file, will all the
instances of that class be of the category by default?
Yes. If you create a category, the methods in that category are added to the class. For example, if you create a category on NSString that returns the checksum of a string, you can use that method on any instance of NSString.
I added the snippet to my code, but it doesn't seem to be working in that I can still select the text.
Don't use categories to override existing methods.
For one thing, it's bad form. You're effectively changing the behavior of the class in a way that the author didn't expect. For another thing, you can't count on the override to work -- the order in which categories are added to classes isn't defined, so you never know if some other category might come along and replace the method that you tried to replace. It's simply not reliable. If you need to override methods, create a subclass instead.
What you need to do is to declare category in header .h file:
such as:
#interface UITextView (DisableCopyPaste)
-(BOOL) methodName
#end
then in .m define as
#implementation UITextView (DisableCopyPaste)
-(BOOL) methodName
{
return NO;
}
#end
You can do two thing,
You can write it in a class and import that to all classes you need this functionality.
Or write these lines eachs .h and .m (respectively) you need it.

iOS - How can I use a common view to draw different views depending on a property?

I have 2 views named 'AA' and 'AB' (and in a near future I'll have more: 'AC', 'AD', etc...).
Right now in my viewControllers, I need to import all my UIView subclass and test something in order to know which subview I need to create and add to the view hierarchy.
My idea was to create a view named 'A' which will figure out which subviews it needs to draw and 'change' it's class to a private one which could be 'AA' or 'AB'.
But I don't know how to do it.
Of course, I could test what needs to be tested and then add the new view as a subview but the idea was to have only one view and not a view within a view.
Thanks for your answers
You can use a variation of the State Design Pattern to implement a system where an object needs to configure its activities at run time. Rather than creating views within a view, you could create a single view that keeps a list of things that know how to draw in a view without themselves being UIView objects.
Here is an example:
#interface ViewDraw
-(void)drawInView; // the UIView caller can pass parameters here
#end
#interface ViewDrawA : ViewDraw
-(void)drawInView;
#end
#interface ViewDrawB : ViewDraw
-(void)drawInView;
#end
#interface ViewDrawC : ViewDraw
-(void)drawInView;
#end
Now your ViewA class can keep an NSArray of ViewDraw objects, configure it with the view draw objects that it needs to draw, and then call upon them to do the drawing. Reconfiguring the list of ViewDraw objects will have the effect of ViewA changing its behavior at run time.

Xcode Dynamically loaded GUI for all views

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.

need multiple inheritance in Objective C

I want to implement a movable UIView class (view moves when you touch on it and move your finger), e.g.:
#interface MovableView : UIView {
some members;
}
-touchesBegan;
-touchesMoved;
#end
How can I apply this code to UILabel, UIButton etc without multiple inheritance? In C++, I'd do it like this (with UIView as a virtual base to MovableView):
struct MovableLabel : UILabel, MovableView {};
Categories are offered as an alternative to multiple inheritance but I definitely don't want to extent UIView using categories because that would apply to all views in my application. I only want some of my views to be movable.
My current strategy to avoid code duplication is putting MovableView code in a header file and including it everytime I need some class to use it. Besides that I have to add members of MovableView to whatever class I am writing. It is pure code ugliness but better than copy/pasting code all over my project.
Does anyone have any other ideas to get around this Objective C limitation [of not having multiple inheritance]?
Thanks,
Altan
Objective-C won't let you do this mixin inheritance thing, except by adding the same category to each of the classes you care to augment. And then, you won't get extra instance variables.
For your specific problem, I might approach it by designing MovableView as a container class that was just an object that has a child view (UILabel, UIButton, etc) that you want to move as its subview.
Categories would not help anyway because replacing the real touchesBegan method on UIButton would be pretty bad... you can't call [super] from a category.
Another solution would be to inject a method into those class definitions with something like:
Method origMethod = class_getClassMethod([UIButton class], #selector(touchesBegan));
Method newMethod = class_getClassMethod([TemplateClass class], #selector(replacementTouchesBegan));
method_exchangeImplementations(origMethod, newMethod);
But that's pretty fiddly. Although if it's really where you want to go, it's worth looking into...
What I would do is make a MovableView class that inherits from UIView, and simply add whatever you want movable as a subview of that view (which I think might be slightly different than what quixoto was saying, my apologies if not). It gets to respond to touches first and passes along whatever it doesn't need to the next responder... no need to build up a special class with a single subview. Then in IB you can just place these movable views wherever and put things inside of them.
In general compositional techniques like this are very handy across UIKit rather than modifying core classes.

when and where to put #class declarations

I am working on a project with several custom classes. I have a CardModel (NSObject) that has some integer properties to hold data, and a Deck (NSObject) that has an array to hold a bunch of CardModels and then a CardView (UIView) that has a CardModel as a property that I make when I select a CardModel from a Deck. And then I've got a bunch of UIViewControllers that I move around on a UINavigationController.
My question is about where and when to use the #class compiler directive.
If I subclass a UIViewController by making a new file and subclassing it, should I use the #class MyViewController in the header of MyViewController.h or .m and does it go in the header of the file that actually uses the controller (like when one controller is going to instantiate another controller type and push it to the stack). Or do I need to use it at all? Is it only required if I actually add new properties to my class beyond what's in the stock implementation? It seems like I'm putting #class all over the place just make sure I don't get errors but I don't fundamentally understand when I need it.
Thanks!
You use it in the .h to inform it about a custom class without including the .h for the custom class.
Example:
Two custom classes: Car and Wheel
Car.h
----------------
#interface Car : NSObject {
}
- (void)addWheel:(Wheel*)newWheel;
#end
Car.h doesn't know about the class 'Wheel' so it would throw an error so you could import the Wheel.h like so:
Car.h
----------------
#import "Wheel.h"
#interface Car : NSObject {
}
- (void)addWheel:(Wheel*)newWheel;
#end
BUT you dont need to do this either. Car.h doesn't need to know anything about the Wheel class, it just needs to know it exists. So what you use is the #class to just say that "Hey, this class exists. Take my word for it."
Car.h
----------------
#class Wheel;
#interface Car : NSObject {
}
- (void)addWheel:(Wheel*)newWheel;
#end
Then inside of the Car.m, when you actually need to know about the Wheel class (properties, methods, etc) you should import the Wheel.h there.
The #class directive is used when you need a header to know about a class but you don't want to import the class's header file; e.g., when you need to avoid circular dependencies.