iPhone - UIImagePickerControllerDelegate inheritance - iphone

I have added a UIImagePickerController to a UIViewController. I have also assigned the UIImagePickerControllerDelegate to that UIViewController.
When I execute the following line,
myPicker.delegate = self;
Xcode gifts me with the following message:
warning: assigning to
id
from incompatible type 'RootViewController'
Then I added the UINavigationControllerDelegate protocol to the same UIViewController and the error message vanished.
So, do I have to add both protocols to the UIViewController when I add a UIImagePickerController?
If the UIImagePickerController is a subclass of UINavigationController as stated in the docs, shouldn't this be automatic? Why do I have to add its parent's delegate protocol and not just the UIImagePickerControllerDelegate protocol?
Is this a bug or am I missing something?

As you noted, UIImagePickerController inherits from UINavigationController. It uses the same delegate property though and doesn't declare a (hypothetical) "imagePickerDelegate" of its own, so your delegate has to conform to both protocols. It makes sense, because you're also assigning the same delegate to the UINavigationController part (that knows nothing about the image picker).
The API design is a bit questionable here in my opinion, but anyway, all methods in UINavigationControllerDelegate are optional, so it suffices to declare that you conform to the protocol and be done with it.

Add these code like below,you can see the warning disappear.
#interface viewController : UIViewController <UIImagePickerControllerDelegate, UINavigationControllerDelegate> { }
#end
The Protocol of UIImagePickerController and UINavigationController must be added in your interface, this can make the warning invisible.

Related

Assigning ViewController to a delegate, Is it good?

I am newbie in iOS programming, Recently I came across a tutorial where author assigned a ViewController to a textField delegate. Is it good to do this? As Xcode is giving me warning.
discussIDTextField.delegate = self;
self is DiscussViewController and above code is inside DiscussViewController.m
Code works fine but I don't like yellow bubbles showing on my screen while writing codes. If I want to get rid of this warning what should I do?
Warning : Assigning id from incompatible type
'DiscussViewController'.
The view controller (self) has to implement the UITextFieldDelegate protocol. So your #interface definition should look something like this:
#interface DiscussViewController : UIViewController <UITextViewDelegate>
And then of course in the implementation implement some of the delegated protocol methods.
In your .h file add UITextFieldDelegate between < > so that your view controller becomes text field delegate and then in the .m file implement delegate methods that you need.
#interface DiscussViewController : UIViewController <UITextFieldDelegate>

How to access variables of a ViewController in a subclass?

I guess this is basic, but I can't get my head around this.
I used to have only one ViewController in which all my variables were defined, e.g. an UITextView named myTextView. I also had methods in this ViewController for handling events that relate to myTextView, such as - ()hideKeyboard { // do something with myTextView or - (void)keyboardWillShow:(NSNotification *)notification { // do something with myTextView.
As my program became bigger and bigger, I thought about using subclasses, especially for other views. So I started a subclass, eg. mySubClass.h and mySubClass.m, in which I had another UITextView (for argument's sake myOtherTextView). In order to incorporate mySubClass, I #imported it into my ViewController and added a #class mySubClass; and could then produce instances of this class so as to use it in my App.
So far so good. As you can imagine, all the nice methods I defined in my ViewController for what should happen when an UITextView is edited (such as hiding keyboard etc.) didn't work for the UITextView in mySubClass.
It was then suggested to me that I should make another class in which I had all the keyboard events and subclass my ViewController and mySubView to it:
#interface ViewController : MyKeyboardEventsViewController
Now, the problem I am seeing is that I won't be able to access all the views, textviews, textfields etc. that I have created in my ViewController (e.g. myTextView which I mentioned earlier).
How can I achieve that all the variables that I have defined in my ViewController will also be available for MyKeyboardEventsViewController? Or is there another way to handle this?
Basically, I don't get how MyKeyboardEventsViewController will be able to access variables in my ViewController which it will need (e.g. the UITextView in question, or the accessoryView which will pop up etc. etc.).
Any suggestions would be very much welcome.
Example:
Class A contains a ivar UITextField textField
Class B subclasses Class A and thus it already contains ivar textField
Note: it's not the other way around. Class A does not "see" what ever is created in Class B.
When ever you subclass a class you give your new class the same ivars end methods of that subclassed class.
I hope this is what you were asking for.
EDIT
So for your example I would do the follwing:
Create a class "MyUIKeybordEventResponder"
Implement all the responder methods like - (BOOL)textFieldShouldReturn:(UITextField *)textField
Subclass your ViewController from "MyUIKeybordEventResponder"
Note method textFieldSHouldReturn has a parameter UITextField so it knows which textfield was pressed. So in a way it receives your textField from the subclass.
If I'm understanding this correctly, you have a UIViewController with MyKeyboardEventsViewController as an instance variable and you want to communicate between the two? If that is the case, one option would be to create a protocol.
#protocol MyKeyboardDelegate
- (void)closeAccessoryView;
#end
(Note - make whatever methods in the protocol that you need, this is simply an example)
In your MyKeyboardEventsViewController you then include the protocol file, and create an ivar
id <MyKeyboardDelegate> delegate;
Also make it a property and synthesize it.
Whatever class that is going to create the keyboardviewcontroller should delcare themselves as conforming to the protocol.
#interface MyViewController : UIViewController <MyKeyboardDelegate>
...
#end
When you create the MyKeyboardEventsViewController, set the delegate.
MyKeyboardEventsViewController *eventsVC = [[MyKeyboardEventsViewController alloc] init];
[eventsVC setDelegate:self];
Now just implement the delegate method and perform whatever action that is necessary.

Calling View Controller Method in ApplicationDelegate - warning me ... but also works

I need to set my root UIViewController as the delegate for one of its modal child UIViewControllers (runwayAnalysisViewController). I implemented a delegate protocol which my root UIViewController adopts.
[runwayAnalysisViewController setSettingsDelegate: self];
(self being the parent UIViewController)
Unfortunately, I am receiving the classic error, "runwayAnalysisViewController may not respond to "-setSettingsDelegate: method."
the delegate is declared as such in the RunwayAnalysisViewController class:
id <SettingsRequestDelegate> settingsDelegate;
-thence:
#property(nonatomic, assign) id <SettingsRequestDelegate> settingsDelegate;
it is synthesized in the .m file as well.
I have tried synthesizing the accessor & mutator methods for the delegate as well as manually writing the same but to no avail.
(other attempt, methods declared in interface and implemented as shown:)
-(void)setSettingsDelegate:(id)aDelegate {
settingsDelegate = aDelegate;
}
-(id)settingsDelegate {
return settingsDelegate;
}
Strangely enough, while this warning persists, I implemented the single method of this delegate as follows:
#pragma mark - SettingsRequestDelegate Methods
-(void)userDidRequestSettingsAccess:(id)sender {
NSLog(#"User did request settings access");
}
I am able to get a successful message sent from the delegate to the parent UIViewController! Any help would be appreciated.
Are you importing your child controller's *.h file at the beginning of the *.m file of the parent view controller?
(and is the #property line you mention contained in that *.h file?)
You need to declare that your root UIViewController conforms to SettingsRequestDelegate in its header file. So where you currently may have:
#interface RootViewController: UIViewController
You'll instead want:
#interface RootViewController: UIViewController <SettingsRequestDelegate>
It's just a warning because in Objective-C all method call dispatches are resolved dynamically and which methods an object responds to can be changed at runtime (albeit not in a very syntactically pretty way). So even though the compiler thinks at compile time that you've probably made a mistake, it isn't really in a position to be certain.
All you're doing with formal protocols is trying to give the compiler something useful to go on for giving you helpful warnings. They weren't in early versions of Objective-C at all and some informal protocols (ie, the delegate has to have certain methods but you document them only in the API documentation — the compiler is completely out of the loop) survived even into early versions of iOS.

Setting delegate in subclass when theres two possible delegates in parent classes

I'm getting a warning when I set the delegate for UIImagePickerController. It's because UIImagePickerController and its parent UINavigationController both have delegates that can be used. The code works fine but just wondering how to handle delegates and inheritance properly and lose the warning.
So basically I've created my own MyImagePickerController which is subclass UIImagePickerController.
UIImagePickerController is a sub class of UINavigationController.
so the inheritance tree is
UINavigationController > UIImagePickerController > MyImagePickerController
MyImagePickerController is also the delegate for UIImagePickerController.
So I add to my #interface.
#interface MyImagePickerController : UIImagePickerController <UIImagePickerControllerDelegate>...
Then I set MyImagePickerController to be the delegate to itself in loadView
- (void) loadView
{
...
self.delegate = self;
...
}
And I implement the UIImagePickerControllerDelegate delegate methods and it all works.
But I get a warning
warning: class 'MyImagePickerController' does not implement the 'UINavigationControllerDelegate' protocol
The problem is that both parent classes have their own Delegates
UINavigationController > UIImagePickerController > MyImagePickerController
UINavigationControllerDelegate > UIImagePickerControllerDelegate > MyImagePickerController
And in the definition for UIImagePickerController the delegate method can take either UINavigationControllerDelegate or UIImagePickerControllerDelegate
#interface UIImagePickerController : UINavigationController <NSCoding> {
#property(nonatomic,assign) id <UINavigationControllerDelegate, UIImagePickerControllerDelegate> delegate;
The app works, the UIImagePickerControllerDelegate methods in MyImagePickerController are being called but is there a proper way to set the delegate so someone reading the code knows we're trying to implement UIImagePickerControllerDelegate methods and for a newbie to clear the warning.
And what happens if you want to implement both UIImagePickerControllerDelegate and UINavigationControllerDelegate methods in the UIImagePickerControllerDelegate? How would you set the single delegate in Obj-C?
Cheers
Read the warning. It tells you everything you need to know.
warning: class
'MyImagePickerController' does not
implement the
'UINavigationControllerDelegate'
protocol
This Line:
#property(nonatomic,assign) id <UINavigationControllerDelegate, UIImagePickerControllerDelegate> delegate;
Does not mean that the delegate object (Note delegate object, not delegate method) can be a UINavigationControllerDelegate or a UIImagePickerControllerDelegate. It means that the delegate object must be a UINavigationControllerDelegate and a UIImagePickerControllerDelegate (it must conform to both these protocols).
You seem to be slightly confused about subclassing and inheritance. The problem isn't that both parent classes have their own Delegates. UINavigationController has a delegate property UINavigationControllerDelegate and because UIImagePickerController is a UINavigationController it also has this delegate, which is still UINavigationControllerDelegate, but it has also added extra behaviour, as subclasses tend to do, and the delegate must now not only implement UINavigationControllerDelegate methods but also UIImagePickerControllerDelegate methods.
So the problem isn't "what happens if you want to implement both..". You have to implement both.

why we need to implement UiNavigationcontroller delegate in ImagePickerController in iphone

hello all I am using Uiimagepickercontroller to record a video there I need to implement two delegates.. 1 is UINavigationcontroller delegate and 2 is UIImagepickercontroller delegate.If we not use navigationcontroller delegate its giving me warning at the code picker.delegte=self;
what is the necessity of UINavigationControllerDelegate..
My requirement is I am recording a vedio automatically.. so after it stops recording It should go to the Screen saying that useThis ,Discard options and it plays the video what is captured?
Is there any way.. to do that ..
could any one tell me the way for this and what is the UINavigtaioncontrollerdelegate exactly?
Thank you all
UIImagePickerController is a subclass of UINavigationController. It requires its delegate to implement the UIImagePickerControllerDelegate protocol while still implementing the UINavigationControllerDelegate protocol for its superclass.
That means you need to declare your delegate class like this:
#interface MyDelegate : NSObject <UIImagePickerControllerDelegate,
UINavigationControllerDelegate>
And then implement the required methods for both protocols.