kee*_*n3d 10 ios swift swiftui
有没有一种方法可以将SwiftUI视图的状态栏更改为白色?
我可能缺少一些简单的东西,但是似乎找不到在SwiftUI中将状态栏更改为白色的方法。到目前为止,我只是看到.statusBar(hidden: Bool)。
Dan*_*and 33
状态栏文本/色调/前景颜色可以通过设置被设置为白色View的.dark或.light使用模式的配色方案.preferredColorScheme(_ colorScheme: ColorScheme?)。
层次结构中使用此方法的第一个视图将优先。
例如:
var body: some View {
ZStack { ... }
.preferredColorScheme(.dark) // white tint on status bar
}
Run Code Online (Sandbox Code Playgroud)
var body: some View {
ZStack { ... }
.preferredColorScheme(.light) // black tint on status bar
}
Run Code Online (Sandbox Code Playgroud)
Muv*_*otv 21
在 info.plist 中,你可以简单地设置
无需将任何内容更改为您的代码...
Ark*_*ann 15
现有答案涵盖了您只想更改状态栏颜色一次的情况(例如,在整个应用程序中使用浅色内容),但如果您想以编程方式执行此操作,那么首选项键是实现此目的的一种方式。
完整的例子可以在下面找到,但这里是我们要做的事情的描述:
PreferenceKey,这将被Views 用来设置他们首选的状态栏样式UIHostingController可以检测偏好更改并将它们桥接到相关 UIKit 代码的子类View以获得一个看起来几乎是官方的 APIstruct StatusBarStyleKey: PreferenceKey {
static var defaultValue: UIStatusBarStyle = .default
static func reduce(value: inout UIStatusBarStyle, nextValue: () -> UIStatusBarStyle) {
value = nextValue()
}
}
Run Code Online (Sandbox Code Playgroud)
class HostingController: UIHostingController<AnyView> {
var statusBarStyle = UIStatusBarStyle.default
//UIKit seems to observe changes on this, perhaps with KVO?
//In any case, I found changing `statusBarStyle` was sufficient
//and no other method calls were needed to force the status bar to update
override var preferredStatusBarStyle: UIStatusBarStyle {
statusBarStyle
}
init<T: View>(wrappedView: T) {
// This observer is necessary to break a dependency cycle - without it
// onPreferenceChange would need to use self but self can't be used until
// super.init is called, which can't be done until after onPreferenceChange is set up etc.
let observer = Observer()
let observedView = AnyView(wrappedView.onPreferenceChange(StatusBarStyleKey.self) { style in
observer.value?.statusBarStyle = style
})
super.init(rootView: observedView)
observer.value = self
}
private class Observer {
weak var value: HostingController?
init() {}
}
@available(*, unavailable) required init?(coder aDecoder: NSCoder) {
// We aren't using storyboards, so this is unnecessary
fatalError("Unavailable")
}
}
Run Code Online (Sandbox Code Playgroud)
extension View {
func statusBar(style: UIStatusBarStyle) -> some View {
preference(key: StatusBarStyleKey.self, value: style)
}
}
Run Code Online (Sandbox Code Playgroud)
首先,在您SceneDelegate需要替换UIHostingController为您的子类:
//Previously: window.rootViewController = UIHostingController(rootView: rootView)
window.rootViewController = HostingController(wrappedView: rootView)
Run Code Online (Sandbox Code Playgroud)
任何视图现在都可以使用您的扩展来指定其首选项:
VStack {
Text("Something")
}.statusBar(style: .lightContent)
Run Code Online (Sandbox Code Playgroud)
在this answer to another question中建议了使用 HostingController 子类来观察首选项键更改的解决方案- 我以前使用过 @EnvironmentObject ,它有很多缺点,首选项键似乎更适合这个问题。
这是解决这个问题的正确方法吗?我不知道。可能存在无法处理的边缘情况,例如,如果层次结构中的多个视图指定了一个首选项键,我还没有彻底测试以查看哪个视图获得优先级。在我自己的用法中,我有两个相互排斥的视图,它们指定了它们首选的状态栏样式,所以我不必处理这个问题。因此,您可能需要修改它以满足您的需要(例如,可能使用元组指定样式和优先级,然后HostingController在覆盖之前检查它的先前优先级)。
Ned*_*Ned 14
@Dan Sandland 的回答对我有用,但就我而言,需要将界面保持在.light模式下
ZStack {
Rectangle()...
VStack(spacing: 0) {
...
}.colorScheme(.light)
}
.preferredColorScheme(.dark)
Run Code Online (Sandbox Code Playgroud)
小智 14
只需将此添加到 info.plist
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleLightContent</string>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
Run Code Online (Sandbox Code Playgroud)
在 IOS 14、xcode 12 上测试
krj*_*rjw 10
但是要回答这个问题并帮助人们直接找到答案:
Swift 5和SwiftUI
对于SwiftUI,创建一个名为HostingController.swift的新swift文件。
import Foundation
import UIKit
import SwiftUI
class HostingController: UIHostingController<ContentView> {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
Run Code Online (Sandbox Code Playgroud)
然后在SceneDelegate.swift中更改以下代码行
window.rootViewController = UIHostingController(rootView: ContentView())
Run Code Online (Sandbox Code Playgroud)
至
window.rootViewController = HostingController(rootView: ContentView())
Run Code Online (Sandbox Code Playgroud)
小智 9
此解决方案适用于使用新 SwiftUI Lifecycle 的应用程序:
我需要动态更改状态栏文本并且无法访问,window.rootViewController因为SceneDelegateSwiftUI 生命周期不存在。
我终于找到了 Xavier Donnellon 这个简单的解决方案:https : //github.com/xavierdonnellon/swiftui-statusbarstyle
将StatusBarController.swift文件复制到您的项目中并将您的主视图包装到一个RootView:
@main
struct ProjectApp: App {
var body: some Scene {
WindowGroup {
//wrap main view in RootView
RootView {
//Put the view you want your app to present here
ContentView()
//add necessary environment objects here
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
然后您可以通过使用.statusBarStyle(.darkContent)或.statusBarStyle(.lightContent)视图修饰符或通过UIApplication.setStatusBarStyle(.lightContent)直接调用例如来更改状态栏文本颜色。
不要忘记在 Info.plist 中将“基于控制器的状态栏外观”设置为“是”。
创建一个名为 的新类HostingController:
import SwiftUI
final class HostingController<T: View>: UIHostingController<T> {
override var preferredStatusBarStyle: UIStatusBarStyle {
.lightContent
}
}
Run Code Online (Sandbox Code Playgroud)
在你的SceneDelegate.swift,代替所有出现的UIHostingController用HostingController。
小智 6
更新:看起来上面 Hannes Sverrisson 的答案最接近,但我们的答案略有不同。
上面写的 UIHostingController 子类的答案在 XCode 11.3.1 中不起作用。
对于子类(也处理 ContentView 环境设置),以下确实对我有用:
import SwiftUI
class HostingController<Content>: UIHostingController<Content> where Content : View {
override var preferredStatusBarStyle: UIStatusBarStyle {
return .lightContent
}
}
Run Code Online (Sandbox Code Playgroud)
然后在 SceneDelegate.swift 中,更改window.rootViewController设置确实有效:
window.rootViewController = HostingController(rootView: contentView)
Run Code Online (Sandbox Code Playgroud)
创建一个主机控制器,DarkHostingController并在其preferredStatusBarStyle上进行设置:
class DarkHostingController<Content> : UIHostingController<Content> where Content : View {
@objc override dynamic open var preferredStatusBarStyle: UIStatusBarStyle {
.lightContent
}
}
Run Code Online (Sandbox Code Playgroud)
并包装SceneDelegate:
window.rootViewController = DarkHostingController(rootView: ContentView())
Run Code Online (Sandbox Code Playgroud)
这对我有用。将这些行添加到您的 info.plist 文件中。您需要切换顶部设置 ( View controller-based status bar appearance) 来确定您要查找的内容。
| 归档时间: |
|
| 查看次数: |
2355 次 |
| 最近记录: |