在主窗口上创建新的UIWindow

boh*_*han 36 uiwindow ios

在我的应用程序中,我想UIWindow在主UIWindow 上创建一个新的,我编写如下,但它不起作用.首先,我创建一个UIWindow作为主窗口,然后使其键和可见,然后创建一个新的UIWindow叠加,但没有任何反应.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    self.window.backgroundColor = [UIColor redColor];
    ViewController *vc = [[ViewController alloc]initWithNibName:@"ViewController" bundle:nil];
    self.window.rootViewController = vc;
    [self.window makeKeyAndVisible];
    UIWindow *window1 = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 320)];
    window1.backgroundColor = [UIColor redColor];
    window1.windowLevel = UIWindowLevelAlert;
    [window1 makeKeyAndVisible];
    return YES;
}
Run Code Online (Sandbox Code Playgroud)

boh*_*han 59

UIWindow *window1 = [[UIWindow alloc] initWithFrame:CGRectMake(0, 0, 320, 320)];
window1.backgroundColor = [UIColor redColor];
window1.windowLevel = UIWindowLevelAlert;
[window1 makeKeyAndVisible];
Run Code Online (Sandbox Code Playgroud)

最后我知道它为什么不起作用,因为window1是一个方法var,它会在方法执行后丢失.所以我宣布一个新的@property,因为

@property (strong, nonatomic) UIWindow *window2;
Run Code Online (Sandbox Code Playgroud)

并改变代码

UIWindow *window2 = [[UIWindow alloc] initWithFrame:CGRectMake(0, 80, 320, 320)];
window2.backgroundColor = [UIColor redColor];
window2.windowLevel = UIWindowLevelAlert;
self.window2 = window2;
[window2 makeKeyAndVisible];
Run Code Online (Sandbox Code Playgroud)

有用!

  • 为什么不:`self.window2 = [[UIWindow alloc] initWithFrame:CGRectMake(0,80,320,320)]; self.window2.backgroundColor = [UIColor redColor]; self.window2.windowLevel = UIWindowLevelAlert; [self.window2 makeKeyAndVisible];`? (3认同)
  • 在这里几乎是相同的,但是通常-尤其是在并发线程的情况下-最好是用其所有属性完全填充对象实例,然后分配给拥有的属性。如果在主线程位于块中间时其他某个线程将开始更改self.window2属性,则您将不知道所分配对象的最终属性-可能是许多不同替代状态的混合。 (2认同)

小智 14

如果您使用的是窗口场景,请尝试以下操作:

private var overlayWindow: UIWindow!

if let currentWindowScene = UIApplication.shared.connectedScenes.first as?  UIWindowScene {
        overlayWindow = UIWindow(windowScene: currentWindowScene)
    }
overlayWindow.windowLevel = UIWindow.Level.alert
overlayWindow.rootViewController = UIViewController()//your controller or navController
overlayWindow.makeKeyAndVisible()
Run Code Online (Sandbox Code Playgroud)

  • `UIWindow(windowScene:)` 初始化器是完成这项工作的关键,谢谢! (2认同)

Swi*_*ect 12

Xcode 8 + Swift

class ViewController: UIViewController {
    var coveringWindow: UIWindow?

    func coverEverything() {
        coveringWindow = UIWindow(frame: (view.window?.frame)!)

        if let coveringWindow = coveringWindow {
            coveringWindow.windowLevel = UIWindowLevelAlert + 1
            coveringWindow.isHidden = false
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

根据文档,要接收没有相关坐标值的事件,例如键盘输入,请将其key改为! isHidden:

coveringWindow.makeKeyAndVisible()
Run Code Online (Sandbox Code Playgroud)

您甚至可以控制其背景的透明度,以获得烟雾效果:

coveringWindow.backgroundColor = UIColor(white: 0, alpha: 0.5)
Run Code Online (Sandbox Code Playgroud)

请注意,此类窗口需要处理方向更改.


小智 8

您的window1对象是局部变量,当代码用完此方法时,此对象不再存在.UIWindow我们创建的任何对象都将被添加到[[UIApplication sharedApplication] windows],但是这个数组只保留一周引用任何UIWindow对象,所以由你自己的代码来保持窗口[UIApplication sharedApplication]对象存在.为什么苹果这样实现,我猜,对象存在的时间很长当应用程序运行时,这样做是为了避免保留UIWindow只需要存在一段时间才能永久存在于内存中的对象.

更重要的是,您的代码可以与MRC一起运行.


Mr.*_*Oak 5

环球银行金融电信协会5

在 iOS13 及更高版本中,您必须UIWindow使用windowScene:初始化程序进行创建,如下所示let overlayWindow = UIWindow(windowScene: YourScene)。对于较低的 iOS 版本,您应该使用frame:初始化程序,如下所示let overlayWindow = UIWindow(frame: YourFrame)

创建UIWindow实例后,您可以使用代码来显示窗口,如 @Nick Greg 答案中所写:

overlayWindow.windowLevel = UIWindow.Level.alert
overlayWindow.rootViewController = UIViewController()//your controller or navController
overlayWindow.makeKeyAndVisible()
Run Code Online (Sandbox Code Playgroud)