3

我错过了一些东西。这段代码运行良好,但我喜欢清除所有编译器警告。

Sending 'GSBBuilderImageButton *const __strong' to parameter of incompatible type 'id<UINavigationControllerDelegate,UIImagePickerControllerDelegate>'

在过去使用此警告消息的经验中,我从未注意到警告中提到了两个协议——而且很公平,在这种情况下,我不知道为什么会引用 UINavigationControllerDelegate。

但首先是我的界面:

#import <UIKit/UIKit.h>
#import "GSBImageButtonDelegate.h"

@interface GSBBuilderImageButton : UIButton <UIImagePickerControllerDelegate>
{
    UIPopoverController *popover;
    UIImage *imageData;
    NSURL *mediaURL;
    id <GSBBuilderImageButtonDelegate> _delegate;
}
@property (strong, nonatomic) NSURL *mediaURL;
@property (strong, nonatomic) UIImage *imageData;
@property (strong, nonatomic) id <GSBBuilderImageButtonDelegate> delegate;
- (void)removePicture;
- (void)setImageData:(UIImage *)theImageData;

@end

重要的是 @interface 声明,其中包括 UIImagePickerControllerDelegate 采用。

在我的实现中,我注意了一个触摸(我想在我写这个的时候我没有使用 setTarget:forAction:forControlState: 因为这个类从 UIView 开始):

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    // really need to check to see that the touch ended while within our bounds

    UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];

    [imagePicker setSourceType:UIImagePickerControllerSourceTypeSavedPhotosAlbum];
    [imagePicker setSourceType:UIImagePickerControllerSourceTypePhotoLibrary];
    [imagePicker setDelegate:self];

所以我读到的方式是本地对象 imagePicker 被告知它的委托是 GSBBuilderImageButton 的这个实例,它在其接口中声明它符合 UIImagePickerControllerDelegate 协议。这似乎完全有效,也是我们一直在做的事情。虽然我的 GSBBuilderImageButton 确实有自己的委托,但除非我做错了什么,否则不应该对此产生影响。

当然,在那之后还有更多内容,包括可选协议方法的实现

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info

我正在以编程方式构建这个按钮,所以为了完整起见,这是我正在使用的初始化:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        [[self imageView] setContentMode:UIViewContentModeScaleAspectFill];
        UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(removePicture)];
        [self addGestureRecognizer:longPress];
    }
    return self;
}

(注意:不要挂断我对 setImageData 的定义......这是一个调用 UIButton 的 setImage 的包装器方法,还有一些其他任务,它的遗产是相同的 UIView 遗产——对于这个应用程序的 2.0 版,我会覆盖 setImage:!

4

1 回答 1

12

这正是警告消息所说的:UIImagePickerController'delegate属性需要一个同时符合协议UIImagePickerControllerDelegateUINavigationControllerDelegate对象。这是因为图像选择器 UI 包含一个导航控制器;该协议中的方法是可选的,因此如果您不需要对它们执行任何操作,则无需实现它们。

但是您仍然需要声明符合这两种协议:

@interface GSBBuilderImageButton : UIButton <UIImagePickerControllerDelegate, UINavigationControllerDelegate>

您的其余代码与编译器警告无关。


更新:这是一个相关的提示。如果仅在类的实现中使用协议一致性,则不需要在头文件中声明它。您可以在.m文件中的类扩展中声明一致性:

@interface GSBBuilderImageButton () <UIImagePickerControllerDelegate, UINavigationControllerDelegate>
@end
于 2012-06-11T18:02:15.293 回答