3

何かが足りません。このコードは正常に機能しますが、コンパイラの警告をすべてクリアしたいと思います。

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

この警告メッセージの過去の経験では、警告に2つのプロトコルが記載されていることに気づきませんでした。十分に公平です。この場合、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

重要なのは、UIImagePickerControllerDelegateの採用を含む@interface宣言です。

私の実装では、タッチに注意を払っています(これを書いた時点では、このクラスはUIViewとして機能し始めたため、setTarget:forAction:forControlStateを使用していなかったと思います):

- (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

私はこのボタンをプログラムで作成しているので、完全を期すために、使用しているinitは次のとおりです。

- (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'sdelegateプロパティは、とプロトコルの両方に準拠するオブジェクトを想定しています。これは、画像ピッカーUIにナビゲーションコントローラーが含まれているためです。そのプロトコルのメソッドはオプションであるため、何もする必要がない場合は、それらを実装する必要はありません。UIImagePickerControllerDelegateUINavigationControllerDelegate

ただし、両方のプロトコルへの準拠を宣言する必要があります。

@interface GSBBuilderImageButton : UIButton <UIImagePickerControllerDelegate, UINavigationControllerDelegate>

コードの残りの部分は、コンパイラの警告とは無関係です。


更新:関連するヒントがあります。クラスの実装内でのみプロトコル準拠を使用する場合は、ヘッダーファイルで宣言する必要はありません。.m代わりに、ファイルのクラス拡張子で適合を宣言できます。

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