目标 C - [self.view viewWithTag] 返回 null
ObjectiveC - [self.view viewWithTag] returning null
我完全被难住了,已经研究了好几天了。可能是我遗漏的非常简单的东西。
我有一个 ViewController
,其中包含一个名为 GameView 的自定义 UIView
,以及一个名为 buttonBox 的 UIView
,其中包含一个 "next level" 按钮。我想要实现的是当关卡在 GameView 中完成时,它会在我的 ViewController
中触发一个显示按钮框的函数,以便用户可以单击 "next level" 按钮。它根本行不通。
我尝试了 3 种方法,都没有用:
- 在
ViewController
中创建一个 IBOutlet
,将其连接到隐藏的 UIView
(并且确实已连接)并调用 setHidden:NO
.
- 调用
[self.view viewWithTag:xxx]
然后调用 setHidden:NO
.
- 使用
hidden=NO
代替 setHidden:NO
。
ViewController
的相关代码如下:
@interface PlayViewController : UIViewController
@property GameView *gv;
@property (strong, nonatomic) IBOutlet UIView *buttonBox;
-(void) showButtonBox;
@end
@implementation PlayViewController
@synthesize buttonBox;
...
- (IBAction)showButtonBox {
UIView *uiv = (UIView*) [self.view viewWithTag:999];
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Showing box function");
NSLog(@"%@", uiv);
uiv.hidden = NO;
});
}
@end
我的自定义视图:
@implementation GameView
...
dispatch_async(bgQueue, ^{
_loopRunning = true;
//NSLog(@"Calling main loop...");
while ([self loopRunning])
{
...
PlayViewController * pvc = [[PlayViewController alloc]init];
[pvc showButtonBox];
...
}
@end
问题是,变量 uiv 在 NSLog
中返回 null,这显然是 hidden 不起作用的原因,但我不知道为什么。当我使用 IBOutlet
.
时它也不起作用
此外,NSLog 的当前输出如下:
2015-11-24 00:18:38.612 ib[12579:1264539] Showing box function
2015-11-24 00:18:38.612 ib[12579:1264539] (null)
提前致谢。
正确答案:
问题是我使用 StoryBuilder 来构建我的 UI,但是通过使用 alloc init 方法创建了一个新的视图控制器(从未显示)而不是正确引用视图控制器正在显示。这是通过将正在显示的视图控制器传递给 viewDidLoad 函数中的视图来实现的,见下文:
@implementation PlayViewController
@synthesize buttonBox;
@synthesize gv;
- (void)viewDidLoad
{
[super viewDidLoad];
gv = [self.view viewWithTag:777];
[gv setPlayViewController:self];
}
...
伙计,这很简单。一起来看看:
@implementation GameView
...
dispatch_async(bgQueue, ^{
_loopRunning = true;
//NSLog(@"Calling main loop...");
while ([self loopRunning])
{
...
PlayViewController * pvc = [[PlayViewController alloc]init];
[pvc showButtonBox];
...
}
@end
这里有问题:
dispatch_async(bgQueue, ^{
我假设,bgQueue
代表 "background queue",这意味着这不是由主线程(UI 线程)提供的。
话虽如此,期望
是相当天真的
[pvc showButtonBox];
才能正常工作。只需将此代码移至主线程即可。例如,您可以将上述代码行包装到主队列中的 dispatch_async
中。如果您的 outlets and/or 标签没问题,那应该可以解决您的问题。干杯。
[[PlayViewController alloc]init];
这将创建 PlayViewController
的新实例。您在哪里定义了您的渠道和观点?
- 在情节提要中?你不能使用这个初始化器 - 故事板中的任何东西都不会被拾取,你必须使用 segue 或
initializeViewControllerWithIdentifier:
。
- 在 xib 文件中?是叫
PlayViewController.xib
吗?如果不是,它不会被初始化器拾取。视图控制器的普通 alloc/init
只会找到 documentation of the nibName property 中描述的 nib 文件。
- 你真的想要 alloc / init 吗?您真的想制作一个 新 视图控制器,还是已经在屏幕上了?
从您的评论来看,选项 3 似乎是正确的答案。 PlayViewController
已经在屏幕上,alloc/init
正在创建它的一个新实例,它永远不会被放在屏幕上,无论故事板或笔尖如何,它都不会加载任何视图。
您需要获取对 PlayViewController
的 现有 实例的引用。在不知道您的应用程序结构的情况下,很难说出它是如何完成的——它是否呈现游戏视图?游戏视图是视图控制器视图的子视图吗?您可能需要在创建游戏视图时在 viewDidLoad
处传递对游戏视图的引用(弱),或者在情节提要中设置出口。
我完全被难住了,已经研究了好几天了。可能是我遗漏的非常简单的东西。
我有一个 ViewController
,其中包含一个名为 GameView 的自定义 UIView
,以及一个名为 buttonBox 的 UIView
,其中包含一个 "next level" 按钮。我想要实现的是当关卡在 GameView 中完成时,它会在我的 ViewController
中触发一个显示按钮框的函数,以便用户可以单击 "next level" 按钮。它根本行不通。
我尝试了 3 种方法,都没有用:
- 在
ViewController
中创建一个IBOutlet
,将其连接到隐藏的UIView
(并且确实已连接)并调用setHidden:NO
. - 调用
[self.view viewWithTag:xxx]
然后调用setHidden:NO
. - 使用
hidden=NO
代替setHidden:NO
。
ViewController
的相关代码如下:
@interface PlayViewController : UIViewController
@property GameView *gv;
@property (strong, nonatomic) IBOutlet UIView *buttonBox;
-(void) showButtonBox;
@end
@implementation PlayViewController
@synthesize buttonBox;
...
- (IBAction)showButtonBox {
UIView *uiv = (UIView*) [self.view viewWithTag:999];
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"Showing box function");
NSLog(@"%@", uiv);
uiv.hidden = NO;
});
}
@end
我的自定义视图:
@implementation GameView
...
dispatch_async(bgQueue, ^{
_loopRunning = true;
//NSLog(@"Calling main loop...");
while ([self loopRunning])
{
...
PlayViewController * pvc = [[PlayViewController alloc]init];
[pvc showButtonBox];
...
}
@end
问题是,变量 uiv 在 NSLog
中返回 null,这显然是 hidden 不起作用的原因,但我不知道为什么。当我使用 IBOutlet
.
此外,NSLog 的当前输出如下:
2015-11-24 00:18:38.612 ib[12579:1264539] Showing box function
2015-11-24 00:18:38.612 ib[12579:1264539] (null)
提前致谢。
正确答案:
问题是我使用 StoryBuilder 来构建我的 UI,但是通过使用 alloc init 方法创建了一个新的视图控制器(从未显示)而不是正确引用视图控制器正在显示。这是通过将正在显示的视图控制器传递给 viewDidLoad 函数中的视图来实现的,见下文:
@implementation PlayViewController
@synthesize buttonBox;
@synthesize gv;
- (void)viewDidLoad
{
[super viewDidLoad];
gv = [self.view viewWithTag:777];
[gv setPlayViewController:self];
}
...
伙计,这很简单。一起来看看:
@implementation GameView
...
dispatch_async(bgQueue, ^{
_loopRunning = true;
//NSLog(@"Calling main loop...");
while ([self loopRunning])
{
...
PlayViewController * pvc = [[PlayViewController alloc]init];
[pvc showButtonBox];
...
}
@end
这里有问题:
dispatch_async(bgQueue, ^{
我假设,bgQueue
代表 "background queue",这意味着这不是由主线程(UI 线程)提供的。
话虽如此,期望
[pvc showButtonBox];
才能正常工作。只需将此代码移至主线程即可。例如,您可以将上述代码行包装到主队列中的 dispatch_async
中。如果您的 outlets and/or 标签没问题,那应该可以解决您的问题。干杯。
[[PlayViewController alloc]init];
这将创建 PlayViewController
的新实例。您在哪里定义了您的渠道和观点?
- 在情节提要中?你不能使用这个初始化器 - 故事板中的任何东西都不会被拾取,你必须使用 segue 或
initializeViewControllerWithIdentifier:
。 - 在 xib 文件中?是叫
PlayViewController.xib
吗?如果不是,它不会被初始化器拾取。视图控制器的普通alloc/init
只会找到 documentation of the nibName property 中描述的 nib 文件。 - 你真的想要 alloc / init 吗?您真的想制作一个 新 视图控制器,还是已经在屏幕上了?
从您的评论来看,选项 3 似乎是正确的答案。 PlayViewController
已经在屏幕上,alloc/init
正在创建它的一个新实例,它永远不会被放在屏幕上,无论故事板或笔尖如何,它都不会加载任何视图。
您需要获取对 PlayViewController
的 现有 实例的引用。在不知道您的应用程序结构的情况下,很难说出它是如何完成的——它是否呈现游戏视图?游戏视图是视图控制器视图的子视图吗?您可能需要在创建游戏视图时在 viewDidLoad
处传递对游戏视图的引用(弱),或者在情节提要中设置出口。