I want create a class that can inherit from two custom class. Do you have any idea to do this please? Please see below my example:
first class:
@interface UIZoomableView : UIView
{
UITapGestureRecognizer *_tapGestureRecognizer;
}
and implementation:
- (void)onDoubleTap:(UITapGestureRecognizer *)sender
{
CGSize newSize;
CGPoint centerPoint = self.center;
if ([self isSmall])
{
newSize = [self bigSize];
}
else
{
newSize = [self smallSize];
}
[UIView animateWithDuration:0.3 animations:^{
self.size = newSize;
self.center = centerPoint;
}];
}
Second class:
@interface UIDraggableView : UIView
UIPanGestureRecognizer *_panGestureRecognizer;
@end
implementation:
- (void)handlePan:(UIPanGestureRecognizer*)sender
{
..
}
i want to create a custom view that can be zoomable and draggable. Do you have any idea to do this please? (without copy code..)
I think something like protocols but i want default value for the base classes? How can i implement this using protocol or something like protocols.
Thanks for any response!
In this blog, we are going to learn about the multiple inheritances in Swift and their implementation in your iOS project. Swift is an Object-oriented programming language but it does not support multiple inheritances.
@virus : Yes you're correct, In iOS(Swift) Single and Multi-Level inheritance exists among the basic inheritances(Singe, Multi-level, Multiple). Multiple inheritance is not possible in Swift.
Interfaces provide an alternative to multiple inheritance. Java programming language does not support multiple inheritance. But interfaces provide a good solution.
Inheritance allows us to create a new class from an existing class. The new class that is created is known as subclass (child or derived class) and the existing class from which the child class is derived is known as superclass (parent or base class).
Objective-C doesn't support multiple inheritance. You could use a protocol, composition and message forwarding to achieve the same result.
A protocol defines a set of methods that an object must implement (it's possible to have optional methods too). Composition is basically the technique of include a reference to another object and calling that object when it's functionality is required. Message forwarding is a mechanism that allows objects to pass messages onto other objects, for example, an object that is included via composition.
Apple Reference:
So, in your case Composition might be a solution, below is the example code
@interface ClassA : NSObject {
}
-(void)methodA;
@end
@interface ClassB : NSObject {
}
-(void)methodB;
@end
@interface MyClass : NSObject {
ClassA *a;
ClassB *b;
}
-(id)initWithA:(ClassA *)anA b:(ClassB *)aB;
-(void)methodA;
-(void)methodB;
@end
@implementation MyClass
-(id)initWithA:(ClassA *)anA b:(ClassB *)aB {
a = anA ;
b = aB ;
}
-(void)methodA {
[a methodA] ;
}
-(void)methodB {
[b methodB] ;
}
@end
If you don't want to implement all the methods from ClassA and ClassB in MyClass, you can use Message Forwarding in MyClass to handle all the method invocations. Below works fine as long as ClassA and ClassB do not have any common methods.
@implementation MyClass
-(id)initWithA:(ClassA *)anA b:(ClassB *)aB {
a = anA ;
b = aB ;
}
//This method will be called, when MyClass can not handle the method itself
-(void)forwardInvocation:(NSInvocation *)anInvocation
{
if ([a respondsToSelector:[anInvocation selector]])
[a invokeWithTarget:someOtherObject];
else if ([b respondsToSelector:[anInvocation selector]])
[b invokeWithTarget:someOtherObject];
else
[super forwardInvocation:anInvocation];
}
@end
The closest that you can get to multiple inheritance in Objective C is with categories. These are a mechanism for adding additional methods to a class that already exists.
Note that this has some important limitations:
ScrollableZoomableView
which inherits from ScrollableView
and ZoomableView
. That's not possible in Objective C (unlike C++ for example).-ObjC
flag when linking files with categories, otherwise you'll get unrecognized selector
errors when you run your code;-init
or +initialize
, because those belong to the base class. You'll need to initialize your properties explicitly. You can still use +load
though;You want something like this:
@interface UIView (Zoomable)
@property (nonatomic) UITapGestureRecognizer * my_tapGestureRecognizer;
@end
@implementation UIView (Zoomable)
-(void)my_enableZooming() {
self.my_tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(my_onDoubleTap:)];
self.my_tapGestureRecognizer.numberOfTapsRequired = 2;
[self addGestureRecognizer:self.my_tapGestureRecognizer];
}
-(void)my_disableZooming() {
[self removeGestureRecognizer:self.my_tapGestureRecognizer];
self.my_tapGestureRecognizer = nil;
}
-(void)my_onDoubleTap:(UITapGestureRecognizer *)sender {
...
}
-(UITapGestureRecognizer)my_tapGestureRecognizer {
return objc_getAssociatedObject(self, @selector(my_tapGestureRecognizer));
}
-(void)setMy_tapGestureRecognizer:(UITapGestureRecognizer)value {
objc_setAssociatedObject(self, @selector(my_tapGestureRecognizer), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
@interface UIView (Draggable)
@property (nonatomic) UIPanGestureRecognizer * my_panGestureRecognizer;
@end
@implementation UIView (Draggable)
-(void)my_enableDragging() {
self.my_panGestureRecognizer = ...;
}
-(void)my_disableDragging() {
...
}
-(void)my_handlePan:(UIPanGestureRecognizer*)sender {
...
}
-(UIPanGestureRecognizer)my_panGestureRecognizer {
return objc_getAssociatedObject(self, @selector(my_panGestureRecognizer));
}
-(void)setMy_panGestureRecognizer:(UIPanGestureRecognizer)value {
objc_setAssociatedObject(self, @selector(my_panGestureRecognizer), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
@end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With