Setting delegate for custom protocol interferes with UIScrollViewDelegate methods
I'm using a custom subclass of UIScrollView
called ImageScrollView
. I need to know when the user taps the scroll view, so I created a protocol. I implement the protocol in my RootViewController
and everything looks ok. When I build it, theres a warning
C开发者_如何学运维lass 'ImageScrollView' does not implement the 'TapDetectingImageViewDelegate' protocol".
After inspecting the init
method in the ImageScrollView
class, I see that self.delegate = self;
is causing the problem. I declare myself the delegate for the UIScrollView
delegate methods, but I also am the delegate for my own protocol (Delegate for my protocol must be RootViewController
, not ImageScrollView
).
- (id)initWithFrame:(CGRect)frame{
if ((self = [super initWithFrame:frame])) {
self.showsVerticalScrollIndicator = NO;
self.showsHorizontalScrollIndicator = NO;
self.bouncesZoom = YES;
self.decelerationRate = UIScrollViewDecelerationRateFast;
self.delegate = self;
}
return self;
}
Do you guys know how can I solve that? Or a better idea to tell my RootViewController
that user has tapped the UIScrollView
/UIImage
.
Declaration of protocol in ImageScrollView.h
@protocol TapDetectingImageViewDelegate <NSObject>
@optional
- (void)tapDetectingImageView:(ImageScrollView *)view gotSingleTapAtPoint:(CGPoint)tapPoint;
@end
Header file of class that implements it
#import <UIKit/UIKit.h>
#import "ImageScrollView.h"
@interface AppleScrollViewViewController : UIViewController <UIScrollViewDelegate, TapDetectingImageViewDelegate>{
UIScrollView *pagingScrollView;
}
-(void)configurePage:(ImageScrollView *)page forIndex:(NSUInteger)index;
- (CGRect)frameForPageAtIndex:(NSUInteger)index;
- (CGRect)frameForPagingScrollView;
- (UIImage *)imageAtIndex:(NSUInteger)index;
- (NSString *)imageNameAtIndex:(NSUInteger)index;
- (CGSize)imageSizeAtIndex:(NSUInteger)index;
- (NSArray *)imageData;
@end
Protocol method in .m class that implements it
-(void)tapDetectingImageView:(ImageScrollView *)view gotSingleTapAtPoint:(CGPoint)tapPoint{
NSLog(@"SingleTap");
}
If you want the view controller to be its delegate, then don't set the delegate within the initializer. When you're creating the ImageScrollView
instance, you should set it to the view controller.
ImageScrollView * aScrollView = [[ImageScrollView alloc] initWithFrame:aFrame];
aScrollView.delegate = self;
[..]
If you are creating it this via IB i.e. renaming the class name of a UIScrollView
to ImageScrollView
, you will have to create an outlet for it and then set the delegate in the viewDidLoad
method of the view controller.
However, there is an issue with this approach. If ImageScrollView
is the subclass of a UIScrollView
as the name suggests, the delegate
property of the scroll view is lost. You should take that into consideration as well.
You will be having an declaration of RootViewController
delegate in the .h file of ImageScrollView
,
Change the name of root delegate to rootDelegate
;
In ImageScrollView.h
RootViewControllerDelegate* rootDelegate;
@property(nonatomic,assign) RootViewControllerDelegate* rootDelegate;
in ImageScrollView.m file
@synthesize rootDelegate;
- (id)initWithFrame:(CGRect)frame{
if ((self = [super initWithFrame:frame])) {
self.showsVerticalScrollIndicator = NO;
self.showsHorizontalScrollIndicator = NO;
self.bouncesZoom = YES;
self.decelerationRate = UIScrollViewDecelerationRateFast;
self.delegate = self;
// Root controller delegate.
self.rootDelegate = self;
}
return self;
}
精彩评论