Fix Compose toolbar not displaying on Catalyst and visionOS

This commit is contained in:
Shadowfacts 2025-02-26 15:32:56 -05:00
parent ae226508b0
commit 618dc78fe9
7 changed files with 25 additions and 4 deletions

View File

@ -77,14 +77,21 @@ struct FocusedInputModifier: ViewModifier {
// This property wrapper abstracts over them both. // This property wrapper abstracts over them both.
@propertyWrapper @propertyWrapper
struct FocusedInput: DynamicProperty { struct FocusedInput: DynamicProperty {
@Environment(\.toolbarInjectedFocusedInputBox) private var box
@FocusedValue(\.composeInput) private var input @FocusedValue(\.composeInput) private var input
#if !targetEnvironment(macCatalyst) && !os(visionOS)
@Environment(\.toolbarInjectedFocusedInputBox) private var box
@StateObject private var updater = Updater() @StateObject private var updater = Updater()
#endif
var wrappedValue: (any ComposeInput)? { var wrappedValue: (any ComposeInput)? {
#if !targetEnvironment(macCatalyst) && !os(visionOS)
box?.wrappedValue ?? input ?? nil box?.wrappedValue ?? input ?? nil
#else
input ?? nil
#endif
} }
#if !targetEnvironment(macCatalyst) && !os(visionOS)
func update() { func update() {
updater.update(box: box) updater.update(box: box)
} }
@ -98,4 +105,5 @@ struct FocusedInput: DynamicProperty {
} }
} }
} }
#endif
} }

View File

@ -55,7 +55,9 @@ public struct ComposeView: View {
) )
.environment(\.composeUIConfig, config) .environment(\.composeUIConfig, config)
.environment(\.currentAccount, currentAccount) .environment(\.currentAccount, currentAccount)
#if !targetEnvironment(macCatalyst) && !os(visionOS)
.injectInputAccessoryHost(state: state, mastodonController: mastodonController, focusedField: $focusedField) .injectInputAccessoryHost(state: state, mastodonController: mastodonController, focusedField: $focusedField)
#endif
.onReceive(NotificationCenter.default.publisher(for: .NSManagedObjectContextObjectsDidChange, object: DraftsPersistentContainer.shared.viewContext), perform: self.managedObjectsDidChange) .onReceive(NotificationCenter.default.publisher(for: .NSManagedObjectContextObjectsDidChange, object: DraftsPersistentContainer.shared.viewContext), perform: self.managedObjectsDidChange)
} }
@ -160,17 +162,23 @@ private struct ComposeViewBody: View {
// When we're using the input accessory toolbar, hide the overlay toolbar so that, // When we're using the input accessory toolbar, hide the overlay toolbar so that,
// on iPad, we don't get two toolbars showing. // on iPad, we don't get two toolbars showing.
#if targetEnvironment(macCatalyst) || os(visionOS)
let showOverlayToolbar = true
#else
let showOverlayToolbar = if #available(iOS 16.0, *) { let showOverlayToolbar = if #available(iOS 16.0, *) {
focusedField == nil focusedField == nil
} else { } else {
true true
} }
#endif
if config.showToolbar, if config.showToolbar,
showOverlayToolbar { showOverlayToolbar {
toolbarView toolbarView
.frame(maxHeight: .infinity, alignment: .bottom) .frame(maxHeight: .infinity, alignment: .bottom)
#if !targetEnvironment(macCatalyst) && !os(visionOS)
.modifier(IgnoreKeyboardSafeAreaIfUsingInputAccessory()) .modifier(IgnoreKeyboardSafeAreaIfUsingInputAccessory())
#endif
.transition(.move(edge: .bottom)) .transition(.move(edge: .bottom))
.animation(.snappy, value: config.showToolbar) .animation(.snappy, value: config.showToolbar)
} }
@ -307,6 +315,7 @@ private struct ToolbarSafeAreaInsetModifier: ViewModifier {
} }
#endif #endif
#if !targetEnvironment(macCatalyst) && !os(visionOS)
private struct IgnoreKeyboardSafeAreaIfUsingInputAccessory: ViewModifier { private struct IgnoreKeyboardSafeAreaIfUsingInputAccessory: ViewModifier {
func body(content: Content) -> some View { func body(content: Content) -> some View {
if #available(iOS 16.0, *) { if #available(iOS 16.0, *) {
@ -419,6 +428,7 @@ private struct InputAccessoryToolbarView: View {
.tint(accentColor.color.map(Color.init(uiColor:))) .tint(accentColor.color.map(Color.init(uiColor:)))
} }
} }
#endif
//#Preview { //#Preview {
// ComposeView() // ComposeView()

View File

@ -92,7 +92,6 @@ private struct LanguageButtonStyle: ButtonStyle {
} }
} }
@available(iOS, obsoleted: 16.0)
private struct LanguageButtonStyleAnimationModifier: ViewModifier { private struct LanguageButtonStyleAnimationModifier: ViewModifier {
let isPressed: Bool let isPressed: Bool

View File

@ -64,11 +64,11 @@ struct EmojiTextField: UIViewRepresentable {
#if !os(visionOS) #if !os(visionOS)
uiView.backgroundColor = colorScheme == .dark ? UIColor(fillColor) : .secondarySystemBackground uiView.backgroundColor = colorScheme == .dark ? UIColor(fillColor) : .secondarySystemBackground
#endif
if uiView.inputAccessoryView !== inputAccessoryToolbarHost { if uiView.inputAccessoryView !== inputAccessoryToolbarHost {
uiView.inputAccessoryView = inputAccessoryToolbarHost uiView.inputAccessoryView = inputAccessoryToolbarHost
} }
#endif
} }
func makeCoordinator() -> Coordinator { func makeCoordinator() -> Coordinator {

View File

@ -95,9 +95,11 @@ private struct NewMainTextViewRepresentable: UIViewRepresentable {
// uiView.backgroundColor = colorScheme == .dark ? UIColor(fillColor) : .secondarySystemBackground // uiView.backgroundColor = colorScheme == .dark ? UIColor(fillColor) : .secondarySystemBackground
// #endif // #endif
#if !os(visionOS)
if uiView.inputAccessoryView !== inputAccessoryToolbarHost { if uiView.inputAccessoryView !== inputAccessoryToolbarHost {
uiView.inputAccessoryView = inputAccessoryToolbarHost uiView.inputAccessoryView = inputAccessoryToolbarHost
} }
#endif
// Trying to set this with the @FocusState binding in onAppear results in the // Trying to set this with the @FocusState binding in onAppear results in the
// keyboard not appearing until after the sheet presentation animation completes :/ // keyboard not appearing until after the sheet presentation animation completes :/

View File

@ -59,7 +59,9 @@ public struct MenuPicker<Value: Hashable>: UIViewRepresentable {
#if targetEnvironment(macCatalyst) #if targetEnvironment(macCatalyst)
config.macIdiomStyle = .bordered config.macIdiomStyle = .bordered
#endif #endif
#if !os(visionOS)
config.contentInsets = .zero config.contentInsets = .zero
#endif
return config return config
} }