【问题标题】:Setting delegate for custom protocol interferes with UIScrollViewDelegate methods为自定义协议设置委托会干扰 UIScrollViewDelegate 方法
【发布时间】:2011-06-08 16:17:38
【问题描述】:

我正在使用 UIScrollView 的自定义子类,称为 ImageScrollView。我需要知道用户何时点击滚动视图,所以我创建了一个协议。我在RootViewController 中实现了该协议,一切看起来都很好。当我构建它时,有一个警告

“ImageScrollView”类未实现“TapDetectingImageViewDelegate”协议”。

检查ImageScrollView 类中的init 方法后,我发现self.delegate = self; 导致了问题。我声明自己是 UIScrollView 委托方法的委托,但我也是我自己协议的委托(我的协议的委托必须是 RootViewController,而不是 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;
 }

你们知道我该如何解决吗?或者更好的办法是告诉我的RootViewController 用户已经点击了UIScrollView/UIImage

ImageScrollView.h中的协议声明

@protocol TapDetectingImageViewDelegate <NSObject>

@optional
- (void)tapDetectingImageView:(ImageScrollView *)view gotSingleTapAtPoint:(CGPoint)tapPoint;

@end

实现它的类的头文件

#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

.m 类中实现它的协议方法

-(void)tapDetectingImageView:(ImageScrollView *)view gotSingleTapAtPoint:(CGPoint)tapPoint{
    NSLog(@"SingleTap");
}

【问题讨论】:

  • 你能发布你的协议声明和实现协议的类的 .h 吗?这听起来像是协议中方法声明的签名和实现不匹配。
  • 当我发布你问的内容时,注意到我在课堂上实现了错误的协议方法。我实施了正确的方法,它记录了“Single Tap”。但我仍然收到警告。有什么想法吗?

标签: objective-c cocoa-touch ios delegates protocols


【解决方案1】:

如果您希望视图控制器成为其委托,则不要在初始化程序中设置委托。创建ImageScrollView 实例时,应将其设置为视图控制器。

ImageScrollView * aScrollView = [[ImageScrollView alloc] initWithFrame:aFrame];
aScrollView.delegate = self;
[..]

如果您通过 IB 创建它,即将UIScrollView 的类名重命名为ImageScrollView,您必须为其创建一个出口,然后在视图控制器的viewDidLoad 方法中设置委托.

但是,这种方法存在一个问题。如果ImageScrollViewUIScrollView 的子类,顾名思义,滚动视图的delegate 属性就会丢失。您也应该考虑到这一点。

【讨论】:

  • 这就是我现在的位置。我的协议现在可以工作了,但是滚动视图的委托属性丢失了。您知道任何解决方法或提示吗?
  • 丢失是什么意思?你是如何初始化对象的?你是如何设置委托的?
  • 我在 ImageScrollView 类中通过其委托方法(UIScrollView 委托方法,因为 ImageScrollView 是 UIScrollView 的子类)所做的所有配置/外观不再有效。好像我的协议确实有效,但 UIScrollView 的协议无效。
  • 像这样声明你的协议@protocol TapDetectingImageViewDelegate &lt;UIScrollViewDelegate&gt;.
  • 在这种情况下,将ImageScrollView 类中的delegate 属性重命名为imageScrollViewDelegate 之类的名称。通过这种方式,您可以创建区别。委托变量不命名为delegate 是可以的。 Apple 的框架中有几个这样的实例
【解决方案2】:

您将在ImageScrollView.h 文件中声明RootViewController 委托,

将根代理的名称更改为rootDelegate;

在 ImageScrollView.h 中

  RootViewControllerDelegate* rootDelegate;
  @property(nonatomic,assign) RootViewControllerDelegate* rootDelegate;

在 ImageScrollView.m 文件中

@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;
 }

【讨论】:

  • 我遇到的问题是 ImageScrollView 声明了协议,并且“self.delegate = self”假设自己也必须实现协议,这是完全错误的。 ImageScrollView 声明了协议,我的 'RootViewController' 必须实现它。这就是 xcode 在 ImageScrollView 中抛出警告的原因。有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-01-13
相关资源
最近更新 更多