【问题标题】:ObjectiveC - [self.view viewWithTag] returning null目标 C - [self.view viewWithTag] 返回 null
【发布时间】:2015-11-24 08:35:21
【问题描述】:

我完全被难住了,已经研究了好几天。可能我错过了一些非常简单的东西。

我有一个 ViewController,其中包含一个名为 GameView 的自定义 UIView,还有一个名为 buttonBox 的 UIView,其中包含一个“下一级”按钮。我想要实现的是,当关卡在 GameView 中完成时,它会在我的ViewController 中触发一个函数,该函数显示按钮框,以便用户可以单击“下一级”按钮。它根本行不通。

我尝试了 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];
}
...

【问题讨论】:

  • 您确定您有一个标签为 999 且位于 self.view 中(而不是位于 self.view 中的另一个视图中)的视图吗?
  • 您的游戏视图是否重叠并位于您的按钮上方?在运行时检查 xcode 中的可视化编辑器并确认 plz
  • 你能看到按钮吗?点击注册了吗?到底出了什么问题?
  • @Fonix 该视图是 self.view 的子视图。
  • @SahebRoy 游戏视图不重叠。 UIV 返回 null,所以 setHidden 肯定不起作用。

标签: ios objective-c uiview hidden


【解决方案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 显示按钮框];

正常工作。只需将此代码移至主线程即可。例如,您可以将上述代码行包装到主队列上的dispatch_async 中。如果您的网点和/或标签没问题,那应该可以解决您的问题。干杯。

【讨论】:

  • 这似乎是正确的......永远不要在后台队列中做任何与 UI 相关的事情,必须在 showButtonBox 之前使用 dispatch_async(dispatch_get_main_queue()
  • 我是这么想的。但我以为我已经在 showButtonBox 函数中做到了这一点。那就是在主线程中执行setHidden,不是吗?... "dispatch_async(dispatch_get_main_queue()..."
  • 然后移动 UIView uiv = (UIView) [self.view viewWithTag:999];也进去看看会发生什么。
  • 这是不正确的;您不应该在主线程中运行 while 循环。正确答案是在主线程only调用UI代码
  • @trojanfoe,当然不是。我们只讨论“缺失视图”的原因。
【解决方案2】:

[[PlayViewController alloc]init];

这将创建PlayViewController 的新实例。你在哪里定义了你的出口和观点?

  • 在故事板中?您不能使用此初始化程序 - 故事板中的任何内容都不会被拾取,您必须使用 segue 或 initializeViewControllerWithIdentifier:
  • 在 xib 文件中?是不是叫PlayViewController.xib?如果没有,它不会被初始化程序拾取。视图控制器的普通alloc/init 只会找到documentation of the nibName property 中描述的nib 文件。
  • 您真的想要 alloc / init 吗?你真的想制作一个新的视图控制器,还是已经在屏幕上?

从您的 cmets 看来,选项 3 是正确答案。 PlayViewController 已经在屏幕上,alloc/init 正在创建它的一个新实例,它永远不会被放在屏幕上,无论故事板或笔尖如何,它都不会加载任何视图。

您需要获得对PlayViewController现有 实例的引用。在不知道你的应用程序结构的情况下,很难说出它是如何完成的——它是在呈现游戏视图吗?游戏视图是视图控制器视图的子视图吗?在创建游戏视图时,您可能需要在 viewDidLoad 处传递对游戏视图的引用(弱),或者在情节提要中设置一个出口。

【讨论】:

  • 嗨@jrturton。出口和视图已在故事板中定义。鉴于此,我将如何使用 segue?我目前正在使用 segue 从关卡选择器屏幕启动到此问题中引用的游戏屏幕。
  • 是的。我能看到它。 GameView 就在其中。 GameView 是想要触发函数以显示隐藏框的视图。它正在尝试调用 playViewController 来执行此操作,但它不起作用。
  • 感谢 JRTurton。你的回答很有道理,我认为这绝对是我的问题的原因。让我看看。生病回来并很快更新。但是,是的,您对第三个项目符号绝对正确。我想在现有控制器中触发一个功能,该功能已经在屏幕上,但在控制器视图的子视图中。
  • 是的!你有它。我会用答案更新问题...感谢您的帮助。我目前正在将一个 Android 应用程序移植到 ObjectiveC 并在此过程中不断学习。在大多数情况下,它的工作原理相同,但这让我陷入了困境。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多