如果 UIWINdow 的子视图,UIButton 单击不起作用

Posted

技术标签:

【中文标题】如果 UIWINdow 的子视图,UIButton 单击不起作用【英文标题】:UIButton click not working if subview of UIWIndow 【发布时间】:2017-03-27 08:09:53 【问题描述】:

我正在创建一个 ios 库。从 AppDelegate 启动时,我的库将在屏幕顶部创建一个按钮。

我已经创建了按钮并且它正在显示。但是当我点击的时候,目标方法并没有被唤起。

这就是我创建按钮并在库中分配其操作的方式

- (void) addLoginButton 
UIWindow *appWindow = [[[UIApplication sharedApplication] delegate] window];
UIButton *loginButton = [UIButton buttonWithType:UIButtonTypeSystem];
[loginButton setFrame:CGRectMake((appWindow.frame.size.width/2)-35, 20, 70, 20)];
[loginButton setBackgroundColor:[UIColor blueColor]];
[loginButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[loginButton setTitle:@"Login" forState:UIControlStateNormal];
[loginButton addTarget:self action:@selector(auLoginClicked) forControlEvents:UIControlEventTouchUpInside];
[appWindow addSubview:loginButton];
if([appWindow.rootViewController isKindOfClass:[UINavigationController class]]) 
    UINavigationController *navCon = (UINavigationController *)(appWindow.rootViewController);
    if (!navCon.navigationBar.isHidden) 
        navCon.navigationBar.layer.zPosition = 0;
    

loginButton.layer.zPosition = 5;


- (void) auLoginClicked 
NSLog(@"Hello");

【问题讨论】:

我认为您必须先使用 Uiview,然后在窗口的上层添加。 uiview 应该添加按钮。试试这个 不要使用层loginButton.layer.zPosition = 5; 使用bringSubViewFront,如果不是。 [窗口 setUserInteractionEnabled:YES];我认为这可以工作。并始终添加上层 uibutton 你在使用故事板吗? 【参考方案1】:

我复制了你的代码并得到了相同的结果。这真的很奇怪,我仍在努力。我确认是故事板导致了结果,因为我在我的项目中使用了你的代码,而没有使用故事板,它工作正常。

但是请不要使用loginButton.layer.zPosition = 5;这不是正确的方式。

以下是一些建议:

但是如果你使用 UINavigationController 使用:

[self.navigationController.view.window addSubview:aView];

如果你在使用 UITabBarController 使用:

[self.tabBarController.view.window addSubview:aView];

在 AppDelegate 中,您可以直接将视图分配给窗口。在 appDelegatedidFinishLaunchingWithOptions 方法中使用:

[self.window addSubview:aView];

希望对你有帮助...

【讨论】:

我正在开发一个库,在 AppDelegate 中唯一的调用将是启动该库。使用我的库的开发人员将从 AppDelegate 初始化它,我必须添加按钮,无论它是什么类型的控制器。 也许您可以为您的用户提供一个 API,例如 showButtonInView:(UIView)view 并让您的用户选择显示按钮的容器 我需要所有视图控制器顶部的按钮。 你得到这个解决方案了吗@AravindGS @Abhishek .. 是的。我将其添加为答案【参考方案2】:

而不是将您的按钮添加为窗口的子视图添加此 那么你的按钮就会得到动作。 [appWindow.rootViewController.view addSubview:loginButton];

如果您将视图(按钮)添加为窗口的子视图,那么它将无法从用户那里获取事件。这就是您的按钮不响应事件的原因。 调试一下你就明白了:)

如果您希望它位于每个 viewController 的顶部,请检查 UINavigationController 是否不是 initialViewController,然后创建一个您自己的 NavigationController 并将其设置为 initialContoller。这将使您的按钮在整个应用程序中可见(直到用户自己呈现任何其他 VC)

【讨论】:

这种工作.. 但我需要按钮在所有视图中都存在。如果我添加一个模态视图控制器,那么按钮将不再可见。 您可以做一件事,为该按钮设置一个标签,然后使用 [window bringSubviewToFront:[window viewWithTag:1523]] 将该按钮置于前面; 仍然无法工作.. 考虑 rootview 控制器是 UINavigationController。当您将按钮作为子视图添加到导航控制器时,在该导航控制器上被推送(显示)的所有视图控制器都将获得该按钮。但是,当您呈现模态控制器时,按钮将位于下方 是的,如果您将 UINavigationController 视为 root,则在 NavigationController 的 topVC 中添加以下代码。 UIWindow *window = [[[UIApplication sharedApplication] delegate] window]; [窗口bringSubviewToFront:[窗口viewWithTag:1523]]; 我正在构建一个库。根视图控制器可以根据开发人员使用我的库的需要是任何东西。我需要一个通用的解决方案。 rootview 控制器可以是标签栏控制器、拆分视图控制器、页面控制器任何东西【参考方案3】:
UIWindow *appWindow = [UIApplication sharedApplication].keyWindow;
[appWindow addSubview:view];

您只需要获取应用程序的keyWindow 并将按钮添加为子视图。您不必设置zPosition

【讨论】:

以上是关于如果 UIWINdow 的子视图,UIButton 单击不起作用的主要内容,如果未能解决你的问题,请参考以下文章

将 UIView 添加到 UIWindow 的子视图时未检测到画外音

作为 UIWindow 子视图添加的 UIView 不响应点击

来自 UIWindow 的子视图并将其发送回 UIwindow

UIWindow 的 rootViewController 属性

UIWindow 在 addSubview 之后不更新子视图

UIButton 的子视图需要释放吗?