Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI setting status bar style

I have been attempting to set the statusbar in my SwiftUI app to light text as it has a dark background.

I found this solution on several sites but cannot get it to work.

HostingController.swift

import Foundation
import UIKit
import SwiftUI

class HostingController : UIHostingController {
    override var preferredStatusBarStyle: UIStatusBarStyle {
    return .lightContent
    }
}

This returns an error on the class declaration line Reference to generic type 'UIHostingController' requires arguments in <...> with a suggested fix of Insert '<<#Content: View#>>'. Applying said fix results in the error Use of undeclared type '<#Content: View#>'

You are then meant to change the window.rootViewController in the SceneDelegate.swift file.

SceneDelegate.swift

...

// Create the SwiftUI view that provides the window contents.
        let contentView = Login()

        // Use a UIHostingController as window root view controller.
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = HostingController(rootView: contentView)
            self.window = window
            window.makeKeyAndVisible()
        }

...

This throws an error on the window.rootViewController line Argument passed to call that takes no arguments

Anyone got any ideas? Seems like a lot of bother just to set the status bar colour which I imagine would be a fairly common requirement.

like image 251
iShaymus Avatar asked Sep 29 '19 09:09

iShaymus


2 Answers

Your HostingController needs a concrete type of the rootView:

class HostingViewController: UIHostingController<AnyView> {

    @objc override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
}

Then use it in func scene(_ scene: UIScene, willConnectTo... as the rootViewController:

let contentView = ContentView()
    if let windowScene = scene as? UIWindowScene {
        let window = UIWindow(windowScene: windowScene)

        window.rootViewController = HostingViewController(rootView: AnyView(contentView.environmentObject(SessionStore())))
        self.window = window
        window.makeKeyAndVisible()
    }

You won't see any difference in canvas unfortunately, but try it on a simulator.

like image 165
LuLuGaGa Avatar answered Oct 06 '22 07:10

LuLuGaGa


Another way to extend UIHostingController is to keep the generic Content type, then you don't have to pass the session store:

class HostingController<Content>: UIHostingController<Content> where Content: View {
    @objc override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }
}

then in your scene delegate:

window.rootViewController = HostingController(rootView: contentView)
like image 44
ldiqual Avatar answered Oct 06 '22 07:10

ldiqual