IBAction 未从子视图按钮单击调用

tom*_*rsd 3 objective-c hierarchy uiviewcontroller ios

所以我整个晚上都在试图解决我的问题,即单击位于 UIViewController 中的按钮不会触发 IBAction。

我的情况

我正在使用故事板构建我的应用程序,我的主要 ViewController 是一个 TabBarViewController。所述 TabBarViewController 的其中一项是,让我们称之为MainViewController

后面MainViewControllerBackgroundViewController仅包含相机预览而没有其他内容的内容。

BackgroundViewController在里面添加MainViewController如下:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
BackgrondViewController *bckgController = (BackgrondViewController *)[storyboard instantiateViewControllerWithIdentifier:@"background"];

[self.view addSubview:bckgController.view];
[self.view sendSubviewToBack:bckgController.view];
Run Code Online (Sandbox Code Playgroud)

到目前为止一切正常,我之所以提到它,是因为这可能是相关的。

顶部控制器

现在我想将另一个 ViewController 添加到MainViewController,这次是在顶部。让我们将顶视图控制器称为TopViewController.

所以首先我像这样设置它:

TopViewController *topController = (TopViewController *)[storyboard instantiateViewControllerWithIdentifier:@"top"];
topController.view.backgroundColor = [UIColor clearColor];
Run Code Online (Sandbox Code Playgroud)

我添加了 clearColor 因为在我的应用程序中需要它并且它确认这没有任何改变(相信我,我试过)。

好的,现在我添加新创建的视图如下(我们还在里面 MainViewController

 [self.view addSubview:topController.view];
 [self.view bringSubviewToFront:topController.view];
Run Code Online (Sandbox Code Playgroud)

事实上,它确实显示透明视图,中间只有一个按钮。

问题

无论我尝试什么,我都无法让按钮调用其 IBAction 方法。

已知事实和我的尝试

  • TopViewController实际上是在MainViewController视图之上,我通过获取 的所有子视图MainViewController,获取最后一个元素并将其与TopViewController的视图进行比较来检查。
  • IBAction 正确链接到我需要单击的按钮(通过故事板和鼠标悬停方法插座确认)
  • 添加TopViewController到 TabBar 工作正常,按钮完成它的工作
  • 按钮在视觉上是可点击的,并且在点击时执行默认动画
  • 设置topController.view.userInteractionEnabled = YES不起作用
  • TopViewController在屏幕上添加单击处理程序并单击屏幕上的任意位置不起作用,但是将其添加到MainViewController确实有效(尽管位于屏幕TopViewController顶部,但单击屏幕上的任意位置会触发定义的操作)
  • 所有尺寸、id 和相应的类都经过验证
  • viewDidLoadTopViewController获取调用

请帮我摆脱这个困境。谢谢!

Kev*_*Low 5

您是否topController通过使用实例变量或属性来保留?

一种简单的方法是在 MainViewController.h 文件中创建一个属性。

@interface MainViewController : UIViewController
    @property (nonatomic, strong) TopViewController *topViewController;
@end
Run Code Online (Sandbox Code Playgroud)

或者在 MainViewController.m 文件的顶部

@interface MainViewController ()
    @property (nonatomic, strong) TopViewController *topViewController;
@end
Run Code Online (Sandbox Code Playgroud)

然后在创建属性后随时设置它。

self.topViewController = topController;

解释

-[UIView addSubview:]保留视图,但不保留视图控制器。如果不保留视图控制器,则 ARC 将在函数结束时释放视图控制器。您可以通过覆盖-[TopViewController dealloc]. 当您按下按钮时,它会尝试向现在的nil视图控制器发送消息。