无法使用Xcode 4.2.1,iOS 5.0和Storyboard连接IBOutlet

时间:2012-01-28 07:57:20

标签: ios5 xcode4.2 storyboard iboutlet

我正在尝试将类(DataViewController)中的IBOutlet连接到另一个类(RootViewController),以便我可以访问DataViewController中的RootViewController实例。

没有编译警告或错误。当我在IB场景中选择DataViewController时,我可以看到我在Connections Inspector-> Outlets中定义的插座。但是当我尝试将连接从插座拖到RootViewController时,它不起作用。它只是失败而没有任何错误或表明错误。

我已经验证了RootViewController场景具有自定义类“RootViewController”。

这是我的代码:

//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

我做错了什么?

1 个答案:

答案 0 :(得分:3)

你做不到。您需要设置委托协议。见This tutorial 并搜索“新代表”这个词,它将解释如何完成。这是您需要使用的设计模式。涉及几个步骤,因此密切关注。值得学习。委托协议在iPhone应用程序中很常见。

在当前项目中,我创建了一个委托协议,用于在两个控制器之间进行通信:SelectNoteViewController(Select)和EditNoteViewController(Edit)。基本思想是Select用于从笔记列表中进行选择,Edit用于编辑这些笔记。现在,我需要编辑才能访问由Select保留的数据和方法,因为我在编辑中有按钮来调用列表中的上一个或下一个注释,该注释由Select管理,因此我实现了委托协议。 Select是Edit的委托。这意味着Select为Edit做了一些事情。这是基本代码。

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

现在选择具有要成为编辑委托的结构。现在,Edit需要在其结束时定义协议,以便在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];

就是这样。当然协议方法和其他方法一样,它们可以传递参数,你需要做的就是把数据传回来,这首先是你的问题。作为旁注,通过在Edit中创建属性并在Select的prepareForSegue方法中设置这些属性,可以看到我可以在没有协议的情况下将数据从Select传递到Edit。这样做可以让我在实例化Edit时设置一些参数。我对委托协议的使用可以追溯到Select并让它将另一个注释(上一个或下一个)传递给Edit。我希望有所帮助。您可以看到创建委托协议有几个步骤。我把他们编号为1-9。如果数据没有回复,我通常会发现我忘了其中一个步骤。