在SWIFTUI中添加新窗口并使其成为关键窗口

时间:2020-01-03 12:12:35

标签: swift swiftui swiftui-navigationlink

我想添加一个新窗口,因为我想创建一个全屏加载器。我试图在其中添加一个新窗口并将其设置为rootviewcontroller。但是它没有添加到Windows层次结构中。下面是我的代码。我正在学习swiftUI。任何帮助表示赞赏。

let window = UIWindow()
window.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
window.backgroundColor = .blue
window.isHidden = false
window.rootViewController = UIHostingController(rootView: Text("Loading...."))
window.makeKeyAndVisible()

2 个答案:

答案 0 :(得分:0)

您需要包装UIActivityIndi​​cator并将其设置为UIViewRepresentable。

struct ActivityIndicator: UIViewRepresentable {

@Binding var isAnimating: Bool
style: UIActivityIndicatorView.Style

func makeUIView(context: UIViewRepresentableContext<ActivityIndicator>) -> UIActivityIndicatorView {
    return UIActivityIndicatorView(style: style)
}

func updateUIView(_ uiView: UIActivityIndicatorView, context: UIViewRepresentableContext<ActivityIndicator>) {
    isAnimating ? uiView.startAnimating() : uiView.stopAnimating()
  }
}

然后您可以按以下方式使用它-这是加载叠加图的示例。

注意:我更喜欢使用ZStack,而不是overlay(:_),所以我确切地知道 在我的实施中 struct LoadingView:查看内容Content:查看{

@Binding var isShowing: Bool
var content: () -> Content

var body: some View {
    GeometryReader { geometry in
        ZStack(alignment: .center) {

            self.content()
                .disabled(self.isShowing)
                .blur(radius: self.isShowing ? 3 : 0)

            VStack {
                Text("Loading...")
                ActivityIndicator(isAnimating: .constant(true), style: .large)
            }
            .frame(width: geometry.size.width / 2,
                   height: geometry.size.height / 5)
            .background(Color.secondary.colorInvert())
            .foregroundColor(Color.primary)
            .cornerRadius(20)
            .opacity(self.isShowing ? 1 : 0)

         }
      }
   }

}

答案 1 :(得分:0)

如果要显示备用窗口,则必须将新的UIWindow连接到现有的窗口场景,因此,这是根据发布的通知在SceneDelegate中执行此操作的可能方法的演示。 / p>

// notification names declarations
let showFullScreenLoader = NSNotification.Name("showFullScreenLoader")
let hideFullScreenLoader = NSNotification.Name("hideFullScreenLoader")

// demo alternate window
struct FullScreenLoader: View {
    var body: some View {
        VStack {
            Spacer()
            Button("Close Loader") {
                NotificationCenter.default.post(name: hideFullScreenLoader, object: nil)
            }
        }
    }
}

// demo main window
struct MainView: View {
    var body: some View {
        VStack {
            Button("Show Loader") {
                NotificationCenter.default.post(name: showFullScreenLoader, object: nil)
            }
            Spacer()
        }
    }
}


class SceneDelegate: UIResponder, UIWindowSceneDelegate {

    var window: UIWindow? // << main window
    var loaderWindow: UIWindow?  // << alternate window

    private var subscribers = Set<AnyCancellable>()

    func makeAntherWindow() { // << alternate window creation
        if let windowScene = window?.windowScene {
            let newWindow = UIWindow(windowScene: windowScene)
            let contentView = FullScreenLoader()
            newWindow.rootViewController = UIHostingController(rootView: contentView)

            self.loaderWindow = newWindow
            newWindow.makeKeyAndVisible()
        }
    }

    override init() {
        super.init()
        NotificationCenter.default.publisher(for: hideFullScreenLoader)
            .sink(receiveValue: { _ in
                self.loaderWindow = nil // remove alternate window
            })
            .store(in: &self.subscribers)
        NotificationCenter.default.publisher(for: showFullScreenLoader)
            .sink(receiveValue: { _ in
                self.makeAntherWindow() // create alternate window
            })
            .store(in: &self.subscribers)
    }

    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {

        let contentView = MainView()
        if let windowScene = scene as? UIWindowScene {
            let window = UIWindow(windowScene: windowScene)
            window.rootViewController = UIHostingController(rootView: contentView)
            self.window = window
            window.makeKeyAndVisible()

        }
    }
    ...