I’m missing something. This code functions fine, but I like to clear up all compiler warnings.
Sending 'GSBBuilderImageButton *const __strong' to parameter of incompatible type 'id<UINavigationControllerDelegate,UIImagePickerControllerDelegate>'
In past experiences with this warning message, I never noticed two protocols being mentioned in the warning — and fair enough, in this case I have no idea why there is a reference to a UINavigationControllerDelegate.
But here’s my interface first:
#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
Of importance is the @interface declaration which includes the UIImagePickerControllerDelegate adoption.
Over in my implementation I pay attention to a touch (I think at the time I wrote this I wasn’t using setTarget:forAction:forControlState: because this class started life as a 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];
So the way I read that is that the local object, imagePicker, is being told that it’s delegate is this instance of a GSBBuilderImageButton, which in its interface declares that it conforms to the UIImagePickerControllerDelegate protocol. That seems perfectly valid and something we do all the time. While it’s true that my GSBBuilderImageButton has its own delegate, that shouldn’t bear on this unless I’ve done something wrong.
There’s more after that, of course, including implementation of the optional protocol method
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
I’m building this button programatically, so for completeness, here’s the init I’m using:
- (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;
}
(Note: Don’t get hung up on my definition of setImageData… that’s a wrapper method that calls UIButton’s setImage but also a few other tasks and it’s legacy is the same UIView heritage — for version 2.0 of this app I’ll override setImage:!
It’s just what the warning message says:
UIImagePickerController‘sdelegateproperty expects an object which conforms to both theUIImagePickerControllerDelegateandUINavigationControllerDelegateprotocols. This is because the image picker UI includes a navigation controller; the methods in that protocol are optional, so you don’t need to implement them if you don’t need to do anything with them.But you do still need to declare conformance to both protocols:
The rest of your code is irrelevant to the compiler warning.
Update: Here’s a related tip. If you make use of protocol conformance only within your class’ implementation, you don’t need to declare it in the header file. You can declare conformance in a class extension in your
.mfile instead: