强制视图控制器重新加载以刷新UIAppearance更改

时间:2014-01-02 01:28:55

标签: ios objective-c interface-builder

我一直在寻找,但找不到答案。我正在开发一个iOS应用程序,并且有一个模式设置页面,只需点击一下按钮就会返回并返回一个segue。 我想要实现的一个选项是配色方案设置。我真的想避免手动更改页面上每个元素的颜色。

Apple有这种事情的UIAppearance协议(因此我可以设置所有按钮的文本颜色等。 他们的文件说:

  

注意:当视图进入窗口时,iOS会应用外观更改,但它不会更改已在窗口中的视图的外观。要更改当前在窗口中的视图的外观,请从视图层次结构中删除该视图,然后将其放回。

我的问题是如何做到这一点。我试过没有运气调用viewWillAppear和setNeedsDisplay。

10 个答案:

答案 0 :(得分:20)

尝试使用此代码段:

NSArray *windows = [UIApplication sharedApplication].windows;
for (UIWindow *window in windows) {
    for (UIView *view in window.subviews) {
        [view removeFromSuperview];
        [window addSubview:view];
    }
}

http://snipplr.com/view/75259/refresh-uiappearance-after-application-loaded/

使用UIAppearance

更改应用主题后,它对我来说非常适合

答案 1 :(得分:8)

具体来说,要获取当前视图及其超级视图,请尝试:

UIView *currentview = self.window.rootViewController.view;
UIView *superview = currentview.superview;
[currentview removeFromSuperview];
[superview addSubview:currentview];

适合我。

答案 2 :(得分:5)

对于Swift:

let windows = UIApplication.sharedApplication().windows
for window in windows {
    for view in window.subviews {
        view.removeFromSuperview()
        window.addSubview(view)
    }
}

答案 3 :(得分:5)

对于Swift 3.0.2:

for window in UIApplication.shared.windows {
    for view in window.subviews {
        view.removeFromSuperview()
        window.addSubview(view)
    }
    // update the status bar if you change the appearance of it.
    window.rootViewController?.setNeedsStatusBarAppearanceUpdate()
}

答案 4 :(得分:4)

请注意,最重要的答案会对您的系统键盘行为产生不利影响。

事实证明,每当显示键盘时,iOS都会在幕后使用UITextEffectsWindow类创建一个新的系统窗口。如果将其删除,则可能会对键盘行为产生负面影响。例如,除了导航控制器中的短暂闪烁外,输入的附件视图将与键盘分离,并且不可见。

您可以通过使用其他检查来解决此问题,例如:

for window in UIApplication.shared.windows {
    // Whenever a system keyboard is shown, a special internal window is created in application
    // window list of type UITextEffectsWindow. This kind of window cannot be safely removed without
    // having an adverse effect on keyboard behavior. For example, an input accessory view is
    // disconnected from the keyboard. Therefore, a check for this class is needed. In case this class
    // that is indernal is removed from the iOS SDK in future, there is a "fallback" class check on
    // NSString class that always fails.
    if !window.isKind(of: NSClassFromString("UITextEffectsWindow") ?? NSString.classForCoder()) {
        window.subviews.forEach {
            $0.removeFromSuperview()
            window.addSubview($0)
        }
    }
}

请注意,UITextEffectsWindow是内部的,将来可能会更改。这就是为什么我不使用!解开变量,而是提供备用负NSString类(没有任何窗口类型属于NSString类)的原因。

注意:对于简单的应用程序,您可以通过使用UIApplication.shared.keyWindow作为解决方法。

答案 5 :(得分:2)

尝试

[self.yourView removeFromSuperView];
[self addSubView:yourView];

答案 6 :(得分:1)

对于swift 4:

let windows = UIApplication.shared.windows
for window in windows {
    for view in window.subviews {
        view.removeFromSuperview()
        window.addSubview(view)
    }
}

答案 7 :(得分:0)

这是 Swift 4.2 的单行代码:

UIApplication.shared.windows.forEach { $0.subviews.forEach { $0.removeFromSuperview(); self.window?.addSubview($0) }}

答案 8 :(得分:0)

对于将语言从 LTR 更改为 RTL ,但有时 标签栏导航标题 导航栏标题 不会得到翻译。我使用以下代码解决了问题

if let app = UIApplication.shared.delegate as? AppDelegate, let window = app.window {
    window.rootViewController = TabNavigationController()
    let tab = window.rootViewController as? UITabBarController
    tab?.selectedIndex = 3
    window.makeKeyAndVisible()
}

答案 9 :(得分:0)

目标 c

<块引用>

self.view.window.overrideUserInterfaceStyle = UIUserInterfaceStyleDark;

如果我想在所有视图控制器中更改overrideUserInterfaceStyle,我会使用此代码