Can't connect IBOutlet with Xcode 4.2.1, iOS 5.0 and storyboards

I am trying to connect an IBOutlet in class (DataViewController) to another class (RootViewController) so that I can access the RootViewController instance in DataViewController.

No compilation warnings or errors. When I select the DataViewController in the IB scene, I see the output that I defined in the Connections Inspector-> Outlets. But when I try to drag the connection from the socket to the RootViewController it doesn't work. It just fails without any error, or points out what is wrong.

I have verified that the RootViewController script has a custom class "RootViewController".

Here's my code:

//RootViewController.h
#import <UIKit/UIKit.h>

@interface RootViewController : UIViewController <UIPageViewControllerDelegate>
@property (strong, nonatomic) UIPageViewController *pageViewController;
@end


//DataViewController.h
#import <UIKit/UIKit.h>
@class RootViewController;

@interface DataViewController : UIViewController < UIWebViewDelegate > {
    IBOutlet UIWebView *webView;
}
@property (strong, nonatomic) IBOutlet RootViewController *rvc; //this one won't connect. Why?
@property (strong, nonatomic) IBOutlet UILabel *dataLabel;
@property (strong, nonatomic) id dataObject;
@end

//DataViewController.m
#import "DataViewController.h"
#import "RootViewController.h"

@implementation DataViewController

@synthesize rvc;

//...
@end

      

What am I doing wrong?

0


source to share


1 answer


You cannot do this. You need to configure the delegate protocol. See this tutorial and look for the words "new delegate" and explain how this is done. This is the design pattern you need to use. There are several steps, so keep an eye on them. It's worth exploring. Delegation protocols are common in iPhone applications.

In the current project, I have created a delegate protocol for communication between two controllers: SelectNoteViewController (Select) and EditNoteViewController (Edit). The basic idea is that Select is used to select from a list of notes and Edit is used to edit those notes. Now I need Edit to be able to access the data and methods stored in the Select, because I have buttons in the editor to call the previous or next note from the list that Select manages, so I am implementing the delegate protocol. Select a delegate to edit. This means Select does things for Edit. Here's the main code.

SelectNoteViewController.h:

// this next statement is need to inform Select of the protocols defined in Edit
#import "EditNoteViewController.h" // STEP 1


@interface SelectNoteViewController : UITableViewController <EditNoteViewControllerDelegate> { ... // STEP 2: this says Select implements the protocol I created
...
// STEP 3: EditNoteViewController Delegate Methods - these are the methods in the protocol
- (Notes *)selectPreviousNote;
- (Notes *)selectNextNote;

      

SelectNoteViewController.m:

// STEP 4: the protocol methods are implemented
- (Notes *)selectPreviousNote {
    if (isPreviousToSelectedNote) {
        NSIndexPath *indexPath, *previousIndexPath;
        indexPath = [self.tableView indexPathForSelectedRow];
        previousIndexPath = [NSIndexPath indexPathForRow:indexPath.row+1 inSection:0];
        // update the selected row
        self.selectedNote = [self.fetchedResultsController objectAtIndexPath:previousIndexPath];
        [self.tableView selectRowAtIndexPath:previousIndexPath animated:NO scrollPosition:UITableViewScrollPositionMiddle];
        [self setPreviousNote];
        [self setNextNote];
    } 
return selectedNote;
}

- (Notes *)selectNextNote {
    if (isNextToSelectedNote) {
        NSIndexPath *indexPath, *nextIndexPath;
        indexPath = [self.tableView indexPathForSelectedRow];
        nextIndexPath = [NSIndexPath indexPathForRow:indexPath.row-1 inSection:0];
        // update the selected row
        self.selectedNote = [self.fetchedResultsController objectAtIndexPath:nextIndexPath];
        [self.tableView selectRowAtIndexPath:nextIndexPath animated:NO scrollPosition:UITableViewScrollPositionMiddle];
        [self setPreviousNote];
        [self setNextNote];
    }
return selectedNote;
}
...
    ...
if ([[segue identifier] isEqualToString:@"editNote"])  {
    // STEP 5: this is where Edit is told that its delegate is Select
    [[segue destinationViewController] setEditNoteViewControllerDelegate:self]; // STEP 5

      



Select now for the structure to be a delegate for editing. Now Edit must define a protocol at its end that it will use to get these methods into the Select.

EditNoteViewController.h

#import ... // put protocol after import statements
// STEP 6
@protocol EditNoteViewControllerDelegate <NSObject>

- (Notes *)selectPreviousNote;
- (Notes *)selectNextNote;

@end


@interface ...
// STEP7: Edit needs a property to tell it who the delegate is - it was set back in Select.m
@property (weak) id <EditNoteViewControllerDelegate> editNoteViewControllerDelegate; 

      

EditNoteViewController.m

// STEP 8: the property is synthesized
@synthesize editNoteViewControllerDelegate;

...

// STEP 9: now when any method needs to call selectPreviousNote or selectNext Note it does it like this:
selectedNote = [self.editNoteViewControllerDelegate selectPreviousNote];
// or
selectedNote = [self.editNoteViewControllerDelegate selectNextNote];

      

That's all. Of course, protocol methods are similar and others, and they can be passed parameters that you need to do in order to pass the data that was your question in the first place. Note that I can pass data from Select to Edit without protocol by creating properties in Edit and setting those properties in the prepareForSegue Select method. This gives me one chance to set some options when instantiating Edit. My use of the delegate protocol goes back to Select and whether it has another note passing (previous or next) to Edit. Hope this helps. You can see that there are several steps to create a delegate protocol. I numbered them 1-9. If no data is returned, I usually find that I forgot one of the steps.

+3


source







All Articles