在窗口中删除和添加视图时键盘/工具栏中断

Posted

技术标签:

【中文标题】在窗口中删除和添加视图时键盘/工具栏中断【英文标题】:Keyboard/Toolbar breaks when removing and adding views in window 【发布时间】:2021-03-21 03:20:22 【问题描述】:

在您的应用程序中执行以下行会以某种方式破坏键盘及其工具栏。工具栏从键盘“分离”并开始在状态栏下方的屏幕顶部滑入和滑出。

if #available(ios 13.0, *) 
    for scene in UIApplication.shared.connectedScenes 
        guard let windowScene = scene as? UIWindowScene else  continue 
        for window in windowScene.windows 
            for view in window.subviews 
                view.removeFromSuperview()
                window.addSubview(view)
            
        
    
 else 
    for window in UIApplication.shared.windows 
        for view in window.subviews 
            view.removeFromSuperview()
            window.addSubview(view)
        
    
    

我知道这很“hacky”,我只是偶然发现它,现在我很好奇为什么删除和添加视图会导致这种行为。有人有想法吗? (系统添加的工具栏也会发生这种情况,例如在 web 视图中)

在这里很难看到,但您可以看到左侧工具栏按钮:

【问题讨论】:

【参考方案1】:

问题是总是有多个窗口,其中一个是UITextEffectsWindow,它负责显示键盘(可能还有其他视图,因为它是一个私有API,所以没有任何官方文档)。

在遍历窗口时忽略UITextEffectsWindow 将解决您的键盘问题。

for window in windowScene.windows.reversed() 
    if NSStringFromClass(window.classForCoder) == "UITextEffectsWindow" 
        NSLog("===== Ignore UITextEffectsWindow")

        return
    

    for view in window.subviews.reversed() 
        view.removeFromSuperview()
        window.addSubview(view)
    

但由于UITextEffectsWindow 是一个私有API,如果窗口是UIWindow,也许你应该做相反的事情并且只删除视图。

【讨论】:

这是我一直在寻找的答案,非常感谢:full_moon_with_face: :P【参考方案2】:

removeFromSuperView() 方法将删除所有引用被删除视图的自动布局约束,以及该视图的子视图。它们不会因为您重新添加视图而神奇地恢复存在,因此您最终会得到视图的框架恰好是什么。

由于您在这里进行试验,您可以尝试这个来查看视图是否恢复了它们的约束:

        for view in window.subviews 
            let constr = view.constraints
            view.removeFromSuperview()
            window.addSubview(view)
            NSLayoutConstraint.activate(constr)
        

【讨论】:

以上是关于在窗口中删除和添加视图时键盘/工具栏中断的主要内容,如果未能解决你的问题,请参考以下文章

在 Swift 中关闭键盘时,UIToolbar 不再显示在视图中

自定义键盘附件视图输入

在ACCESS 中,单击数据库窗口工具栏中的()按钮,即可在视图中打开相应的表。

键盘出现时 UITextView 向上移动

在不添加完成键的情况下关闭数字键盘式键盘

视图加载后是不是可以在工具栏上添加、删除或隐藏按钮?