如何在 DocumentGroup 应用程序的 Main 中使用 if #available()

问题描述 投票:0回答:4

在下面的代码中,我只想在 #available(macOS 13.0, *) == true 或 @ available(macOS 13.0, *) 时使用 .windowResizability,因为它在 macOS 13 下不可用。我找不到解决方案我自己。

//
//  Test_HowAviableApp.swift
//  Test HowAviable
//
//  Created by Sebastien REMY on 03/11/2022.
//

import SwiftUI
import UniformTypeIdentifiers

@main
struct Test_HowAviableApp: App {
    var body: some Scene {
        DocumentGroup(newDocument: MyDocument()) { file in
            MyView(document: file.$document)
        }
        // @available(macOS 13.0, *) // <- DOESN'T WORK!
        //.windowResizability(.contentSize) // Only for macOs 13+
    }
}

struct MyDocument: FileDocument, Codable {
    
    static var readableContentTypes = [UTType(exportedAs:"com.test.test")]
    var test = "test"
    init() {
        
    }
    
    init(configuration: ReadConfiguration) throws {
        if let data = configuration.file.regularFileContents {
            self = try JSONDecoder().decode(MyDocument.self, from: data)
        }
    }
    
    func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper {
        let data = try JSONEncoder().encode(self)
        return FileWrapper(regularFileWithContents: data)
    }
}

struct MyView: View {
    @Binding var document: MyDocument
    
    var body: some View {
        Text("Hello")
    }
}
swift xcode macos swiftui
4个回答
3
投票
  1. .windowResizability
    仅在 macOS 上可用,因此您需要根据平台有条件地应用此修饰符。
  2. .windowResizability
    仅支持 macOS 13.0+,因此在 macOS 实现中,需要进行 API 可用性检查。

基于此,我添加了此条件功能。

@main
struct YourApp: App {
    var body: some Scene {
#if os(macOS)
        // macOS
        conditionalWindowScene()
#else
        // Other Platform
        WindowGroup {
            ContentView()
        }
#endif
    }

#if os(macOS)
    /// Extract your conditional scene to avoid using `@SceneBuilder`
    /// In `body`, SwiftUI will always use `@SceneBuilder` to build multiple Scene.
    /// Because the result type is `some Scene`,
    /// you just need to return a type that conforms to `Scene` Protocol.
    func conditionalWindowScene() -> some Scene {
        if #available(macOS 13.0, *) {
            /// `Window` Scene is only available on macOS 13.0+
            return Window("App", id: "MAIN") {
                ContentView()
            }
        } else {
            /// Otherwise, using `WindowGroup`
            return WindowGroup {
                ContentView()
            }
        }
    }
#endif
}

Window
Scene 仅适用于 macOS 13.0+ ,这与您的问题非常相似。

希望这可以帮助你。


1
投票

对于单个表达式,您只能删除

return
:

试试这个:

struct MacDemoApp: App {
    var body: some Scene {
        
        if #available(macOS 13, *) {
            return DocumentGroup(newDocument: MyDocument()) { file in
                ContentView(document: file.$document)
            }.windowResizability(.contentSize)
        } else {
            return DocumentGroup(newDocument: MyDocument()) { file in
                ContentView(document: file.$document)
            }
        }
    }
}

0
投票

您可以通过

扩展场景协议
extension Scene {
    func addWindowResizabilityIfAvailable() -> some Scene {
        if #available(macOS 13, *) {
            return self.windowResizability(.contentSize)
        } else {
            return self
        }
    }
}

稍后致电

@main
struct Test_HowAviableApp: App {
    var body: some Scene {
        DocumentGroup(newDocument: MyDocument()) { file in
            MyView(document: file.$document)
        }
        .addWindowResizabilityIfAvailable()
    }
}

这将是我选择的方法,因为它


-1
投票

用 if 语句包裹起来即可

if #available(macOS 13, *) {
    .windowResizability(.contentSize)
}
© www.soinside.com 2019 - 2024. All rights reserved.