Как я могу скрыть строку заголовка в новом протоколе приложений SwiftUI?
Поскольку протоколы AppDelegate.swift и SceneDelegate.swift ушли, я больше не могу следовать этой документации: https://developer.apple.com/documentation/uikit/mac_catalyst/removing_the_title_bar_in_your_mac_app_built_with_mac_catalyst
Я не могу реализовать этот код:
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
#if targetEnvironment(macCatalyst)
if let titlebar = windowScene.titlebar {
titlebar.titleVisibility = .hidden
titlebar.toolbar = nil
}
#endif
}
}
Надеюсь, это все еще возможно с новым AppProtocol.
заранее спасибо
@Asperi, спасибо за ваш ответ, благодаря вашему ответу я смог скрыть заголовок. Я опубликую ответ, но я все еще надеюсь, что Apple скоро добавит официальную поддержку.
Вот как скрыть заголовок:
struct ContentView: View {
var body: some View {
ZStack {
Text("Example UI")
}
.withHostingWindow { window in
#if targetEnvironment(macCatalyst)
if let titlebar = window?.windowScene?.titlebar {
titlebar.titleVisibility = .hidden
titlebar.toolbar = nil
}
#endif
}
}
}
extension View {
fileprivate func withHostingWindow(_ callback: @escaping (UIWindow?) -> Void) -> some View {
self.background(HostingWindowFinder(callback: callback))
}
}
fileprivate struct HostingWindowFinder: UIViewRepresentable {
var callback: (UIWindow?) -> ()
func makeUIView(context: Context) -> UIView {
let view = UIView()
DispatchQueue.main.async { [weak view] in
self.callback(view?.window)
}
return view
}
func updateUIView(_ uiView: UIView, context: Context) {
}
}
UIKit наше все! :D
@imike Да, я с нетерпением жду того времени, когда у SwiftUI будет все необходимое :)
Лучший подход — создать подкласс UIView и реализовать его willMove:toWindow:, вызвать там обратный вызов и пропустить async. Таким образом, мерцание отсутствует, а заголовок сразу же скрывается при появлении представления.
Я добавил условное выражение if let titlebar
из модификатора .withHostingWindow
прямо в свой AppDelegate, в didFinishLaunchingWithOptions
, и это сработало отлично!
В вашей сцене установите для .windowStyle(_:) значение HiddenTitleBarWindowStyle().
@main
struct MyApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
.windowStyle(HiddenTitleBarWindowStyle())
}
}
Обновлено: Ах, дерьмо. Хотя этот API предположительно доступен для Mac Catalyst в соответствии с онлайн-документацией, похоже, что на самом деле он не помечен как таковой в фреймворках, поэтому вы не можете его использовать.
И как я могу попасть на сцену?
Обычно вы создаете сцены в @main, например. Оконная группа. Поэтому установите windowStyle в WindowGroup.
Я пробовал это, но нет возможности для этого.
Извините, в онлайн-документации говорится, что windowStyle(_:) доступен для Mac Catalyst, но на самом деле это не так. Надеюсь, Apple добавит его!
Без проблем! Я надеюсь, что это так, потому что это делает ваше приложение намного лучше.
Отлично работает в macOS 11. Спасибо.
Вы можете использовать
withHostingWindow
(от stackoverflow.com/a/63276688/12299030), чтобы найти собственное окно, а затем сделать то, что нужно.