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

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.

Related

Calling views from subclasses

I have an iPhone app primarily made of two views, let's call them fullScreen and cardViews (the cardViews are presented as subViews of the full screen views). I've handled all of the animations in presenting the card Views by having a masterCardViewClass and a masterFullScreenViewClass. All specific cardViews are subclasses of the masterCardView, all specific fullScreenViews are subclasses of the masterFullScreenView.
I present a cardView with a method from the masterFullScreenViewClass. I dismiss the cardView with a delegate method from the masterCardView. However, I'm having a problem calling a method to present a cardView from another cardView. All cardView presenting methods are contained in the masterFullScreenViewController class.
How do I access these methods without copying a pasting them locally where I need them.
One way of doing it is by using protocols.
In a nutshell, your masterCardView class would implement a protocol method that presents a cardView (for the sake of simplicity, let's say that you invoke cardViews with a certain index):
masterCardView.h:
#protocol CardPresenterDelegate <NSObject>
- (void)presentCardViewWithIndex:(int)index;
#end
#interface MasterCardView:UIViewController <CardPresenterDelegate>
...
masterCardView.m:
- (void)presentCardViewWithIndex:(int)index
{
// Code for presenting a cardView
}
You would also need to create a delegate (weak) property in your cardView:
cardView.h
#property (weak) id<CardPresenterDelegate> cardPresenterDelegate;
And then by accessing that property in your cardView, you can tell the masterCardView to do something for you:
cardView.m
[self.cardPresenterDelegate presentCardViewWithIndex:5];
Oh, and, don't forget to set the delegate property on your cardViews when creating them in your masterCardView:
back in masterCardView.m:
cardView.cardPresenterDelegate = self;

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>

iPhone - UIImagePickerControllerDelegate inheritance

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.

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.

iPhone: Switching Views From Outside Root Controller

I am using a UINavigationController to switch between views. What I would like is for each view to have the ability to control when it is swapped out for another view by having buttons within the view. All of the samples I've seen thus far have placed buttons on a toolbar, which is located on the root view containing the Switch View Controller rather than the views, them self. Is it possible to do what I want? I can't figure how to wire up the connection back to the UINavigationController.
I'm having a difficult time wording this, so please feel free to let me know if you need additional clarification.
Read about delegates. Delegates are a common method to signal stuff from objects to their "parents" or any other objects.
You should have a "delegate" property (can really be called anything, this is just a convention) on your child views. You can have buttons in your child views.
You declare the delegate like this:
interface ChildView : UIViewController {
id delegate;
}
#property (assign) id delegate;
implementation ChildView
#synthesize delegate;
Then, when you set up your child views inside your UINavigationController, you do:
ChildView *childView = [[ChildView alloc] init...]
childView.delegate = self;
Inside your child view, you have a button method:
- (IBAction) didPressButton:(id)sender {
[self.delegate didPressButtonToSwapView];
}
Inside your UINavigationController, you have a method:
- (void) didPressButtonToSwapView {
[self popViewController]; // use the right names, I made these up :)
[self pushAnotherViewController];
}
You should also read about protocols which would make the above code more robust and would help you make sure you only call the right methods on delegate, but I did not want to complicate this example.
EDIT: yes, the cleanest way to get rid of the warning is to use a protocol. Just put this in a separate .h file:
#protocol SwitchingDelegate
- (void) didPressButtonToSwapView;
#end
Include this .h in the UINavController header, and say the UINavController implements the protocol:
#interface MyNav: UINavController <SwitchingDelegate> { ...
Implement the method in the implementation (you don't need anything more in the interface).
In your ChildView, say that the delegate must implement the protocol: change all the declarations to:
id<SwitchingDelegate> delegate;
The compiler then helps you by checking whether the delegate objects really implement the protocol. You should not get any warnings when you have completed all of this correctly.