我完全难过,并且已经研究了好几天。可能是我遗失的非常简单的东西。
我有一个ViewController
,其中包含一个名为GameView的自定义UIView
,以及一个名为buttonBox的UIView
,其中包含一个"下一个级别"按钮。我想要实现的是当在GameView中完成关卡时,它会在我的ViewController
中触发一个显示buttonBox的函数,这样用户就可以点击"下一级"按钮。它根本行不通。
我尝试了3种方式,但都没有效果:
IBOutlet
中创建ViewController
,将其连接到隐藏的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,这显然是隐藏不起作用的原因,但我不明白为什么。当我使用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];
}
...
答案 0 :(得分:1)
男人,这很简单。我们来看看:
@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
代表“后台队列”,这意味着主线程(UI线程)不提供此服务。
话虽如此,期待
[pvc showButtonBox];
正常工作。只需将此代码移动到主线程中即可。例如,您可以将上述代码行包装到主队列中的dispatch_async
。如果您的插座和/或标签没问题,这应该可以解决您的问题。欢呼声。
答案 1 :(得分:0)
[[PlayViewController alloc]init];
这将创建PlayViewController
的新实例。你在哪里定义了你的网点和观点?
initializeViewControllerWithIdentifier:
。 PlayViewController.xib
吗?如果没有,它将不会被初始化者接收。视图控制器的普通alloc/init
只会找到documentation of the nibName property中所述的nib文件。 从您的评论看来,选项3似乎是正确的答案。 PlayViewController
已经在屏幕上,alloc/init
正在创建一个新的实例,它永远不会被放在屏幕上,无论故事板还是笔尖都不会加载任何视图。
您需要获得对PlayViewController
的现有实例的引用。如果不知道应用程序的结构,那么说它是如何完成的 - 它是不是很容易呈现游戏视图?游戏视图是视图控制器视图的子视图吗?您可能需要在创建游戏视图时将参考(弱)传递到viewDidLoad
,或在故事板中设置插座。