views:

119

answers:

1

I have a simple project to present a modal view controller and transfer back a string based on which button in the modal VC that gets pressed. I based it all on watching the Stanford class on iTunes U. It looks like I have everything correct, but I get a couple of compiler warnings.

First I get one called passing argument 1 of 'setDelegate:' from incompatible pointer type in TransferViewController.m

Second I get four warnings called Invalid receiver type 'id <MyModalViewControllerDelegate>*' but these aren't displayed in the build results area, rather next to the offending lines in MyModalViewController.m, both lines in each of the button actions.

Here's the code...

//  TransferViewController.h

#import <UIKit/UIKit.h>
#import "MyModalViewController.h";

@interface TransferViewController : UIViewController <MyModalViewControllerDelegate> {
    UILabel *label;
    UIButton *button;
}

@property (nonatomic, retain) IBOutlet UILabel *label;
@property (nonatomic, retain) UIButton *button;

- (IBAction)updateText;

@end

//  TransferViewController.m

#import "TransferViewController.h"

@implementation TransferViewController

@synthesize label;
@synthesize button;

- (IBAction)updateText {
    MyModalViewController *myModalViewController = [[MyModalViewController alloc] init];
    myModalViewController.delegate = self; // I get the warning here.
    [self presentModalViewController:myModalViewController animated:YES];
    [myModalViewController release];
}

- (void)myModalViewController:(MyModalViewController *)controller didFinishSelecting:(NSString *)selectedDog {
    label.text = selectedDog;
    [self dismissModalViewControllerAnimated:YES];
}

@end

//  MyModalViewController.h

#import <UIKit/UIKit.h>

@protocol MyModalViewControllerDelegate;

@interface MyModalViewController : UIViewController {
    UIButton *abby;
    UIButton *zion;
    id <MyModalViewControllerDelegate> delegate;
}

@property (assign) id <MyModalViewControllerDelegate> delegate;

- (IBAction)selectedAbby;
- (IBAction)selectedZion;

@end

@protocol MyModalViewControllerDelegate <NSObject>

@optional

- (void)myModalViewController:(MyModalViewController *)controller didFinishSelecting:(NSString *)selectedDog;

@end

//  MyModalViewController.m

#import "MyModalViewController.h"

@implementation MyModalViewController

@synthesize delegate;

- (IBAction)selectedAbby {
    if ([self.delegate respondsToSelector:@selector (myModalViewController:didFinishSelecting:)]) {
        [self.delegate myModalViewController:self didFinishSelecting:@"Abby"];
    }
}

- (IBAction)selectedZion {
    if ([self.delegate respondsToSelector:@selector (myModalViewController:didFinishSelecting:)]) {
        [self.delegate myModalViewController:self didFinishSelecting:@"Zion"];
    }

}
+3  A: 

Get rid of those *s after id <something> and before delegate.

So make this

id <MyModalViewControllerDelegate> *delegate;

this

id <MyModalViewControllerDelegate> delegate;
Douwe Maan
Thanks again! I guess I lied in my other question when I said I understood the concept of using a delegate, but I think I do now. When I define a delegate method in the parent VC, since it's implemented in the parent, it has access to the ivars in the parent. When the modal VC uses that method, it gets a conduit back to the parent.
Steve
Regarding the invalid type issue, I think this is one of those cases where Objective-C being so permissive bit me. It was happy to let me incorrectly define the delegate as a pointer, but only got upset when I actually tried to use it that way - a hint about how I defined it would be nice in the compiler warning. Maybe in xCode 4!
Steve
Yup, looks like you get it :)A delegate still points to an object, so if you'd say SomeDelegateClass *delegate, you'd still need the *, the thing is that id already has this * 'inside' it, so you don't need to explicitely write it.
Douwe Maan
I just got a chance to try the fix, and it gets rid of the 4 warnings called `Invalid receiver type 'id <MyModalViewControllerDelegate>*'` but I still get a `Passing argument 1 of 'setDelegate:' from incompatible pointer type` warning. It occurs on the line in `TransferViewController.m` where I do this: `myModalViewController.delegate = self;` I noted it above and removed the 1*`.
Steve
Also got the `*` in the `@protocol` definition. This got it to compile, but now when it runs, the modal doesn't display, it just turns white. Weird. More fiddling...
Steve
Wow. What a pain! Apparently you can't change the name of a nib file. I changed `MyModalViewController.xib` to `ModalView.xib` because I thought it was more descriptive. Won't do that again!
Steve
You can change the name of a nib file just fine, you just have to make sure you change all references to that file to the new filename, also inside OTHER nib files, and it looks like you didn't do that ;)
Douwe Maan
When it crashed, it made some comment about not finding the nib, which was the clue I needed to change the name back. xCode is a complicated beast that will take a lot of working with to understand all the subtleties! I'll play around with the two nibs and see if I can find the connections. It would be nice to have the flexibility to name a nib anything I want. In the meantime, I'm just happy I got it working - another tool in my toolbox!
Steve
When you want to rename something, it's better to use the Refactor option in the Edit menu than to look for all places where the name is used yourself. This Refactor method does this for you ;)
Douwe Maan