无法使用 Xcode 4.2.1、iOS 5.0 和 Storyboard 连接 IBOutlet [英] Can't connect IBOutlet using Xcode 4.2.1, iOS 5.0 and Storyboards

查看:26
本文介绍了无法使用 Xcode 4.2.1、iOS 5.0 和 Storyboard 连接 IBOutlet的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

There are no compile warnings or errors. When I select DataViewController in the IB scene, I can see the outlet I've defined in Connections Inspector->Outlets. But when I try to drag a connection from the outlet to RootViewController, it doesn't work. It just fails without any error or indication of what's wrong.

我已验证 RootViewController 场景具有自定义类RootViewController".

I've verified that the RootViewController scene has Custom Class "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

我做错了什么?

推荐答案

你不能那样做.您需要设置委托协议.请参阅本教程并向下搜索新代表"一词,它将解释如何完成.这就是您需要使用的设计模式.涉及多个步骤,因此请密切关注.值得学习.委托协议在 iPhone 应用程序中很常见.

You can't do that. You need to setup a delegate protocol. See This tutorial and search down for the words "new delegate" and it will explain how that is done. That is the design pattern you need to use. There are several steps involved so follow closely. It is worth learning. Delegate protocols are common in iPhone Apps.

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

In a current project I created a delegate protocol to communicate between two controller: 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 have access back into the data and methods kept by Select because I have buttons in edit to call up the previous or next note from the list which is managed by Select so I implement a delegate protocol. Select is a delegate for Edit. That means Select does things for Edit. Here is the essential code.

SelectNoteViewController.h:

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:

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 现在具有可以作为 Edit 代表的结构.现在 Edit 需要在其末端定义协议,它将用于访问 Select 中的那些方法.

Select now has the structure to do be a delegate for Edit. Now Edit needs to define the protocol on its end that it is going to use to get to those methods in Select.

EditNoteViewController.h

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

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.如果数据没有返回,我通常会发现我忘记了其中一个步骤.

That is it. Of course the protocol methods are like and other method and they can be passed parameters which what you need to do to pass data back which was your question in the first place. As a side note, see that I can pass data from Select to Edit without a protocol by creating properties in Edit and setting those properties in the prepareForSegue method of Select. Doing so gives me one shot to set some parameters when Edit is instantiated. My use of a the delegate protocol goes back to Select and has it pass another note (previous or next) to Edit. I hope that helps. You can see there are several steps to creating a delegate protocol. I numbered them 1-9. If the data is not making it back, I usually find I forgot one of the steps.

这篇关于无法使用 Xcode 4.2.1、iOS 5.0 和 Storyboard 连接 IBOutlet的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆