在 Main.storyboard 和 AppDelegate.h 之间建立连接
Posted
技术标签:
【中文标题】在 Main.storyboard 和 AppDelegate.h 之间建立连接【英文标题】:Making connections between Main.storyboard and AppDelegate.h 【发布时间】:2013-10-10 09:55:00 【问题描述】:对于 Xcode 5.0,我正在尝试遵循 Big Nerd Ranch book 2nd edition,这似乎有点过时了。
有一个带有 2 个标签和 2 个按钮的示例测验项目。
我已经从书中复制了源代码,尤其是。 AppDelegate.h
:
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
int currentQuestionIndex;
NSMutableArray *questions;
NSMutableArray *answers;
IBOutlet UILabel *questionField;
IBOutlet UILabel *answerField;
@property (strong, nonatomic) UIWindow *window;
- (IBAction)showQuestion:(id)sender;
- (IBAction)showAnswer:(id)sender;
@end
书中没有提到MainWindow.xib
,但我确实有一个Main.storyboard
,我在其中放置了标签和按钮:
我可以在源代码编辑器左侧(在上面的屏幕截图中间)和“连接检查器”(例如“Touch Up Inside”)中看到 4 个空心小圆圈,但我只是不能让他们联系起来。我尝试从小圆圈拖动和 ctrl-拖动到按钮/标签,有一条蓝线,但它没有连接。
当我右键单击按钮/标签时,会出现一个关于“Outlets”的灰色菜单,但那里没有列出我的 IBOutlets/IBActions。
请问如何将连接添加到标签和按钮?
更新:
根据 Rob 的建议(谢谢 +1),我已将属性和方法移至 ViewController.*
并能够连接标签和按钮。当我单击按钮时,我看到了正在调用的方法。
但现在我的问题是ViewController
类的init
方法没有运行,因此两个数组都为零。
请问还有什么提示吗?而且我不确定为什么将我的问题结束的建议“过于宽泛” - 我附上了(短)代码和屏幕截图,我的 2 个问题非常具体(可能是基本的)。
ViewController.h:
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
int currentQuestionIndex;
NSMutableArray *questions;
NSMutableArray *answers;
IBOutlet UILabel *questionField;
IBOutlet UILabel *answerField;
- (IBAction)showQuestion:(id)sender;
- (IBAction)showAnswer:(id)sender;
@end
ViewController.m:
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (id)init // XXX is never called??
self = [super init];
if(self)
questions = [[NSMutableArray alloc] init];
answers = [[NSMutableArray alloc] init];
[questions addObject:@"What is 7 + 7?"];
[answers addObject:@"14"];
[questions addObject:@"What is the capital of Vermont?"];
[answers addObject:@"Montpelier"];
[questions addObject:@"From what is cognac made?"];
[answers addObject:@"Grapes"];
return self;
- (IBAction)showQuestion:(id)sender // XXX runs ok when clicked
currentQuestionIndex++;
if (currentQuestionIndex == [questions count])
currentQuestionIndex = 0;
NSString *question = [questions objectAtIndex:currentQuestionIndex];
NSLog(@"displaying question: %@", question);
[questionField setText:question];
[answerField setText:@"???"];
- (IBAction)showAnswer:(id)sender // XXX runs ok when clicked
NSString *answer = [answers objectAtIndex:currentQuestionIndex];
[answerField setText:answer];
- (void)viewDidLoad
[super viewDidLoad];
- (void)didReceiveMemoryWarning
[super didReceiveMemoryWarning];
@end
【问题讨论】:
Storyboard 是从 XIB 开始的合理大小更改。我要么创建没有故事板的项目,要么找到特定的故事板教程来了解基础知识。 【参考方案1】:您的IBOutlet
引用应该在视图控制器类中,而不是应用委托类中。场景的基类(在您选择场景下方的栏后显示在“身份检查器”中)是视图控制器,因此您的 IBOutlet
引用将与此相关联。当您控制从情节提要拖到视图控制器类时,您会发现它会开始按照您的预期行事。
应用程序委托旨在定义应用程序在启动、进入后台等时的行为。对于用户与应用程序交互时的行为,您通常将其放在视图控制器类中。
【讨论】:
这是令人讨厌的 xCode 事情之一,它似乎在助理编辑器之上随机切换到手动,并且当人们认为助理编辑器正在显示适当的补充文件时,这可能会让人们感到厌烦。随机=很可能是我的错。 谢谢 Rob,现在我可以连接了,但没有调用init
(请查看我更新的代码),您有什么建议吗?
@AlexanderFarber 把所有的东西都放在 viewDidLoad 中。
@AlexanderFarber 仅供参考,对于故事板实例化的视图控制器,它调用initWithCoder
,而不是init
。但通常viewDidLoad
是您放置此类代码的地方。
@AlexanderFarber 每次加载情节提要的该场景的新实例时都会调用它(仅考虑推/模态转场,是当您推/模态到该场景时,而不是当您弹出时/dismiss/unwind 回到它)。 init
/initWithCoder
在创建控制器时被调用,viewDidLoad
在稍后创建控制器视图时被调用。见Initializing a View Controller。以上是关于在 Main.storyboard 和 AppDelegate.h 之间建立连接的主要内容,如果未能解决你的问题,请参考以下文章
IBOutlets 和 IBActions 未显示在 main.storyboard 的视图控制器中
在 Main.storyboard 和 AppDelegate.h 之间建立连接
查看项目在 Main.StoryBoard 中不可见 [重复]