Remove input accessory toolbar
This commit is contained in:
parent
84ed9e92ee
commit
1135094c21
@ -72,53 +72,17 @@ struct FocusedInputModifier: ViewModifier {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// In the input accessory view toolbar, we get the focused input through the box injected from the ComposeView.
|
|
||||||
// Otherwise we get it from @FocusedValue (which doesn't seem to work via the hacks we use for the input accessory).
|
|
||||||
// This property wrapper abstracts over them both.
|
|
||||||
@propertyWrapper
|
|
||||||
struct FocusedInput: DynamicProperty {
|
|
||||||
@FocusedValue(\.composeInput) private var input
|
|
||||||
#if !targetEnvironment(macCatalyst) && !os(visionOS)
|
|
||||||
@Environment(\.toolbarInjectedFocusedInputBox) private var box
|
|
||||||
@StateObject private var updater = Updater()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
var wrappedValue: (any ComposeInput)? {
|
|
||||||
#if !targetEnvironment(macCatalyst) && !os(visionOS)
|
|
||||||
box?.wrappedValue ?? input ?? nil
|
|
||||||
#else
|
|
||||||
input ?? nil
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#if !targetEnvironment(macCatalyst) && !os(visionOS)
|
|
||||||
func update() {
|
|
||||||
updater.update(box: box)
|
|
||||||
}
|
|
||||||
|
|
||||||
private class Updater: ObservableObject {
|
|
||||||
private var cancellable: AnyCancellable?
|
|
||||||
|
|
||||||
func update(box: MutableObservableBox<(any ComposeInput)?>?) {
|
|
||||||
cancellable = box?.objectWillChange.sink { [unowned self] _ in
|
|
||||||
self.objectWillChange.send()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
@propertyWrapper
|
@propertyWrapper
|
||||||
struct FocusedInputAutocompleteState: DynamicProperty {
|
struct FocusedInputAutocompleteState: DynamicProperty {
|
||||||
@FocusedInput private var input
|
@FocusedValue(\.composeInput) private var input
|
||||||
@StateObject private var updater = Updater()
|
@StateObject private var updater = Updater()
|
||||||
|
|
||||||
var wrappedValue: AutocompleteState? {
|
var wrappedValue: AutocompleteState? {
|
||||||
input?.autocompleteState
|
input??.autocompleteState
|
||||||
}
|
}
|
||||||
|
|
||||||
func update() {
|
func update() {
|
||||||
updater.update(input: input)
|
updater.update(input: input ?? nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
@ -133,8 +97,8 @@ struct FocusedInputAutocompleteState: DynamicProperty {
|
|||||||
lastInput = input
|
lastInput = input
|
||||||
cancellable = input?.autocompleteStatePublisher.sink { [unowned self] _ in
|
cancellable = input?.autocompleteStatePublisher.sink { [unowned self] _ in
|
||||||
// the autocomplete state sometimes changes during a view update, so defer this
|
// the autocomplete state sometimes changes during a view update, so defer this
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async { [weak self] in
|
||||||
self.objectWillChange.send()
|
self?.objectWillChange.send()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,40 +0,0 @@
|
|||||||
//
|
|
||||||
// KeyboardReader.swift
|
|
||||||
// ComposeUI
|
|
||||||
//
|
|
||||||
// Created by Shadowfacts on 3/7/23.
|
|
||||||
//
|
|
||||||
|
|
||||||
#if !os(visionOS)
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
import Combine
|
|
||||||
|
|
||||||
@available(iOS, obsoleted: 16.0)
|
|
||||||
class KeyboardReader: ObservableObject {
|
|
||||||
@Published var keyboardHeight: CGFloat = 0
|
|
||||||
|
|
||||||
var isVisible: Bool {
|
|
||||||
// when a hardware keyboard is connected, the height is very short, so we don't consider that being "visible"
|
|
||||||
keyboardHeight > 72
|
|
||||||
}
|
|
||||||
|
|
||||||
init() {
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(willShow), name: UIResponder.keyboardWillShowNotification, object: nil)
|
|
||||||
NotificationCenter.default.addObserver(self, selector: #selector(willHide), name: UIResponder.keyboardWillHideNotification, object: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc func willShow(_ notification: Foundation.Notification) {
|
|
||||||
let endFrame = notification.userInfo![UIResponder.keyboardFrameEndUserInfoKey] as! CGRect
|
|
||||||
keyboardHeight = endFrame.height
|
|
||||||
}
|
|
||||||
|
|
||||||
@objc func willHide() {
|
|
||||||
// sometimes willHide is called during a SwiftUI view update
|
|
||||||
DispatchQueue.main.async {
|
|
||||||
self.keyboardHeight = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
@ -144,12 +144,12 @@ private struct ExpandedEmojiSection: View {
|
|||||||
|
|
||||||
private struct AutocompleteEmojiButton: View {
|
private struct AutocompleteEmojiButton: View {
|
||||||
let emoji: Emoji
|
let emoji: Emoji
|
||||||
@FocusedInput private var input
|
@FocusedValue(\.composeInput) private var input
|
||||||
@Environment(\.composeUIDelegate) private var delegate
|
@Environment(\.composeUIDelegate) private var delegate
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
Button {
|
Button {
|
||||||
input?.autocomplete(with: ":\(emoji.shortcode):")
|
input??.autocomplete(with: ":\(emoji.shortcode):")
|
||||||
} label: {
|
} label: {
|
||||||
Label {
|
Label {
|
||||||
Text(verbatim: ":\(emoji.shortcode):")
|
Text(verbatim: ":\(emoji.shortcode):")
|
||||||
|
@ -14,7 +14,7 @@ struct AutocompleteHashtagView: View {
|
|||||||
let mastodonController: any ComposeMastodonContext
|
let mastodonController: any ComposeMastodonContext
|
||||||
@State private var loading = false
|
@State private var loading = false
|
||||||
@State private var hashtags: [Hashtag] = []
|
@State private var hashtags: [Hashtag] = []
|
||||||
@FocusedInput private var input
|
@FocusedValue(\.composeInput) private var input
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ScrollView(.horizontal) {
|
ScrollView(.horizontal) {
|
||||||
@ -90,6 +90,6 @@ struct AutocompleteHashtagView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func autocomplete(hashtag: Hashtag) {
|
private func autocomplete(hashtag: Hashtag) {
|
||||||
input?.autocomplete(with: "#\(hashtag.name)")
|
input??.autocomplete(with: "#\(hashtag.name)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ struct AutocompleteMentionView: View {
|
|||||||
let mastodonController: any ComposeMastodonContext
|
let mastodonController: any ComposeMastodonContext
|
||||||
@State private var loading = false
|
@State private var loading = false
|
||||||
@State private var accounts: [AnyAccount] = []
|
@State private var accounts: [AnyAccount] = []
|
||||||
@FocusedInput private var input
|
@FocusedValue(\.composeInput) private var input
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
ScrollView(.horizontal) {
|
ScrollView(.horizontal) {
|
||||||
@ -48,7 +48,7 @@ struct AutocompleteMentionView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func autocomplete(account: AnyAccount) {
|
private func autocomplete(account: AnyAccount) {
|
||||||
input?.autocomplete(with: "@\(account.value.acct)")
|
input??.autocomplete(with: "@\(account.value.acct)")
|
||||||
}
|
}
|
||||||
|
|
||||||
private func queryChanged() async {
|
private func queryChanged() async {
|
||||||
|
@ -207,11 +207,11 @@ private struct LocalOnlyButton: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private struct InsertEmojiButton: View {
|
private struct InsertEmojiButton: View {
|
||||||
@FocusedInput private var input
|
@FocusedValue(\.composeInput) private var input
|
||||||
@ScaledMetric(relativeTo: .body) private var imageSize: CGFloat = 22
|
@ScaledMetric(relativeTo: .body) private var imageSize: CGFloat = 22
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
if input?.toolbarElements.contains(.emojiPicker) == true {
|
if input??.toolbarElements.contains(.emojiPicker) == true {
|
||||||
Button(action: beginAutocompletingEmoji) {
|
Button(action: beginAutocompletingEmoji) {
|
||||||
Label("Insert custom emoji", systemImage: "face.smiling")
|
Label("Insert custom emoji", systemImage: "face.smiling")
|
||||||
}
|
}
|
||||||
@ -225,6 +225,7 @@ private struct InsertEmojiButton: View {
|
|||||||
|
|
||||||
private func beginAutocompletingEmoji() {
|
private func beginAutocompletingEmoji() {
|
||||||
if let input,
|
if let input,
|
||||||
|
let input,
|
||||||
input.autocompleteState == nil {
|
input.autocompleteState == nil {
|
||||||
input.beginAutocompletingEmoji()
|
input.beginAutocompletingEmoji()
|
||||||
}
|
}
|
||||||
@ -232,11 +233,12 @@ private struct InsertEmojiButton: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private struct FormatButtons: View {
|
private struct FormatButtons: View {
|
||||||
@FocusedInput private var input
|
@FocusedValue(\.composeInput) private var input
|
||||||
@PreferenceObserving(\.$statusContentType) private var contentType
|
@PreferenceObserving(\.$statusContentType) private var contentType
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
if let input,
|
if let input,
|
||||||
|
let input,
|
||||||
input.toolbarElements.contains(.formattingButtons),
|
input.toolbarElements.contains(.formattingButtons),
|
||||||
contentType != .plain {
|
contentType != .plain {
|
||||||
|
|
||||||
@ -269,16 +271,6 @@ private struct FormatButton: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private struct InputAccessoryToolbarHost: EnvironmentKey {
|
|
||||||
static var defaultValue: UIView? { nil }
|
|
||||||
}
|
|
||||||
extension EnvironmentValues {
|
|
||||||
var inputAccessoryToolbarHost: UIView? {
|
|
||||||
get { self[InputAccessoryToolbarHost.self] }
|
|
||||||
set { self[InputAccessoryToolbarHost.self] = newValue }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//#Preview {
|
//#Preview {
|
||||||
// ComposeToolbarView()
|
// ComposeToolbarView()
|
||||||
//}
|
//}
|
||||||
|
@ -59,14 +59,6 @@ public struct ComposeView: View {
|
|||||||
.environment(\.composeUIConfig, config)
|
.environment(\.composeUIConfig, config)
|
||||||
.environment(\.composeUIDelegate, delegate)
|
.environment(\.composeUIDelegate, delegate)
|
||||||
.environment(\.currentAccount, currentAccount)
|
.environment(\.currentAccount, currentAccount)
|
||||||
#if !targetEnvironment(macCatalyst) && !os(visionOS)
|
|
||||||
.injectInputAccessoryHost(
|
|
||||||
state: state,
|
|
||||||
mastodonController: mastodonController,
|
|
||||||
focusedField: $focusedField,
|
|
||||||
delegate: delegate
|
|
||||||
)
|
|
||||||
#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)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,9 +146,6 @@ private struct ComposeViewBody: View {
|
|||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.scrollDismissesKeyboardInteractivelyIfAvailable()
|
.scrollDismissesKeyboardInteractivelyIfAvailable()
|
||||||
#endif
|
#endif
|
||||||
#if !os(visionOS) && !targetEnvironment(macCatalyst)
|
|
||||||
.modifier(ToolbarSafeAreaInsetModifier())
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
.overlay(alignment: .top) {
|
.overlay(alignment: .top) {
|
||||||
if let poster = state.poster {
|
if let poster = state.poster {
|
||||||
@ -165,33 +154,13 @@ private struct ComposeViewBody: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
.overlay(alignment: .bottom, content: {
|
.safeAreaInset(edge: .bottom) {
|
||||||
// This needs to be in an overlay, ignoring the keyboard safe area
|
if config.showToolbar {
|
||||||
// doesn't work with the safeAreaInset modifier.
|
|
||||||
|
|
||||||
// When we're using the input accessory toolbar, hide the overlay toolbar so that,
|
|
||||||
// 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, *) {
|
|
||||||
focusedField == nil
|
|
||||||
} else {
|
|
||||||
true
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if config.showToolbar,
|
|
||||||
showOverlayToolbar {
|
|
||||||
toolbarView
|
toolbarView
|
||||||
.frame(maxHeight: .infinity, alignment: .bottom)
|
|
||||||
#if !targetEnvironment(macCatalyst) && !os(visionOS)
|
|
||||||
.modifier(IgnoreKeyboardSafeAreaIfUsingInputAccessory())
|
|
||||||
#endif
|
|
||||||
.transition(.move(edge: .bottom))
|
.transition(.move(edge: .bottom))
|
||||||
.animation(.snappy, value: config.showToolbar)
|
.animation(.snappy, value: config.showToolbar)
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
#endif
|
#endif
|
||||||
// Have these after the overlays so they barely work instead of not working at all. FB11790805
|
// Have these after the overlays so they barely work instead of not working at all. FB11790805
|
||||||
.modifier(DropAttachmentModifier(draft: draft))
|
.modifier(DropAttachmentModifier(draft: draft))
|
||||||
@ -304,180 +273,6 @@ enum FocusableField: Hashable {
|
|||||||
case pollOption(NSManagedObjectID)
|
case pollOption(NSManagedObjectID)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !os(visionOS) && !targetEnvironment(macCatalyst)
|
|
||||||
private struct ToolbarSafeAreaInsetModifier: ViewModifier {
|
|
||||||
@StateObject private var keyboardReader = KeyboardReader()
|
|
||||||
@FocusedInputAutocompleteState private var autocompleteState
|
|
||||||
|
|
||||||
private var inset: CGFloat {
|
|
||||||
var height: CGFloat = 0
|
|
||||||
if keyboardReader.isVisible {
|
|
||||||
height += ComposeToolbarView.toolbarHeight
|
|
||||||
}
|
|
||||||
if autocompleteState != nil {
|
|
||||||
height += ComposeToolbarView.autocompleteHeight
|
|
||||||
}
|
|
||||||
return height
|
|
||||||
}
|
|
||||||
|
|
||||||
func body(content: Content) -> some View {
|
|
||||||
if #available(iOS 17.0, *) {
|
|
||||||
content
|
|
||||||
.safeAreaPadding(.bottom, inset)
|
|
||||||
} else {
|
|
||||||
content
|
|
||||||
.safeAreaInset(edge: .bottom) {
|
|
||||||
if !keyboardReader.isVisible {
|
|
||||||
Color.clear.frame(height: inset)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if !targetEnvironment(macCatalyst) && !os(visionOS)
|
|
||||||
private struct IgnoreKeyboardSafeAreaIfUsingInputAccessory: ViewModifier {
|
|
||||||
func body(content: Content) -> some View {
|
|
||||||
if #available(iOS 16.0, *) {
|
|
||||||
content
|
|
||||||
.ignoresSafeArea(.keyboard)
|
|
||||||
} else {
|
|
||||||
content
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private extension View {
|
|
||||||
@ViewBuilder
|
|
||||||
func injectInputAccessoryHost(
|
|
||||||
state: ComposeViewState,
|
|
||||||
mastodonController: any ComposeMastodonContext,
|
|
||||||
focusedField: FocusState<FocusableField?>.Binding,
|
|
||||||
delegate: (any ComposeUIDelegate)?
|
|
||||||
) -> some View {
|
|
||||||
if #available(iOS 16.0, *) {
|
|
||||||
self.modifier(
|
|
||||||
InputAccessoryHostInjector(
|
|
||||||
state: state,
|
|
||||||
mastodonController: mastodonController,
|
|
||||||
focusedField: focusedField,
|
|
||||||
delegate: delegate
|
|
||||||
)
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
self
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@available(iOS 16.0, *)
|
|
||||||
private struct InputAccessoryHostInjector: ViewModifier {
|
|
||||||
// This is in a StateObject so we can use the autoclosure StateObject initializer.
|
|
||||||
@StateObject private var factory: ViewFactory
|
|
||||||
@FocusedValue(\.composeInput) private var composeInput
|
|
||||||
|
|
||||||
init(
|
|
||||||
state: ComposeViewState,
|
|
||||||
mastodonController: any ComposeMastodonContext,
|
|
||||||
focusedField: FocusState<FocusableField?>.Binding,
|
|
||||||
delegate: (any ComposeUIDelegate)?
|
|
||||||
) {
|
|
||||||
self._factory = StateObject(
|
|
||||||
wrappedValue: ViewFactory(
|
|
||||||
state: state,
|
|
||||||
mastodonController: mastodonController,
|
|
||||||
focusedField: focusedField,
|
|
||||||
delegate: delegate
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
func body(content: Content) -> some View {
|
|
||||||
content
|
|
||||||
.environment(\.inputAccessoryToolbarHost, factory.controller.view)
|
|
||||||
.onChange(of: ComposeInputEquatableBox(input: composeInput ?? nil)) { newValue in
|
|
||||||
factory.focusedInput = newValue.input ?? nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@MainActor
|
|
||||||
private class ViewFactory: ObservableObject {
|
|
||||||
let controller: UIViewController
|
|
||||||
@MutableObservableBox var focusedInput: (any ComposeInput)?
|
|
||||||
|
|
||||||
init(
|
|
||||||
state: ComposeViewState,
|
|
||||||
mastodonController: any ComposeMastodonContext,
|
|
||||||
focusedField: FocusState<FocusableField?>.Binding,
|
|
||||||
delegate: (any ComposeUIDelegate)?
|
|
||||||
) {
|
|
||||||
self._focusedInput = MutableObservableBox(wrappedValue: nil)
|
|
||||||
let view = InputAccessoryToolbarView(
|
|
||||||
state: state,
|
|
||||||
mastodonController: mastodonController,
|
|
||||||
focusedField: focusedField,
|
|
||||||
focusedInputBox: _focusedInput,
|
|
||||||
delegate: delegate
|
|
||||||
)
|
|
||||||
let controller = UIHostingController(rootView: view)
|
|
||||||
controller.sizingOptions = .intrinsicContentSize
|
|
||||||
controller.view.autoresizingMask = .flexibleHeight
|
|
||||||
self.controller = controller
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct ComposeInputEquatableBox: Equatable {
|
|
||||||
let input: (any ComposeInput)?
|
|
||||||
|
|
||||||
static func ==(lhs: Self, rhs: Self) -> Bool {
|
|
||||||
lhs.input === rhs.input
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// FocusedValue doesn't seem to work through the hacks we're doing for the input accessory.
|
|
||||||
private struct FocusedInputBoxEnvironmentKey: EnvironmentKey {
|
|
||||||
static var defaultValue: MutableObservableBox<(any ComposeInput)?>? { nil }
|
|
||||||
}
|
|
||||||
extension EnvironmentValues {
|
|
||||||
var toolbarInjectedFocusedInputBox: MutableObservableBox<(any ComposeInput)?>? {
|
|
||||||
get { self[FocusedInputBoxEnvironmentKey.self] }
|
|
||||||
set { self[FocusedInputBoxEnvironmentKey.self] = newValue }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct InputAccessoryToolbarView: View {
|
|
||||||
@ObservedObject var state: ComposeViewState
|
|
||||||
let mastodonController: any ComposeMastodonContext
|
|
||||||
@FocusState.Binding var focusedField: FocusableField?
|
|
||||||
let focusedInputBox: MutableObservableBox<(any ComposeInput)?>
|
|
||||||
let delegate: (any ComposeUIDelegate)?
|
|
||||||
@PreferenceObserving(\.$accentColor) private var accentColor
|
|
||||||
|
|
||||||
init(
|
|
||||||
state: ComposeViewState,
|
|
||||||
mastodonController: any ComposeMastodonContext,
|
|
||||||
focusedField: FocusState<FocusableField?>.Binding,
|
|
||||||
focusedInputBox: MutableObservableBox<(any ComposeInput)?>,
|
|
||||||
delegate: (any ComposeUIDelegate)?
|
|
||||||
) {
|
|
||||||
self.state = state
|
|
||||||
self.mastodonController = mastodonController
|
|
||||||
self._focusedField = focusedField
|
|
||||||
self.focusedInputBox = focusedInputBox
|
|
||||||
self.delegate = delegate
|
|
||||||
}
|
|
||||||
|
|
||||||
var body: some View {
|
|
||||||
ComposeToolbarView(draft: state.draft, mastodonController: mastodonController, focusedField: $focusedField)
|
|
||||||
.environment(\.toolbarInjectedFocusedInputBox, focusedInputBox)
|
|
||||||
.environment(\.composeUIDelegate, delegate)
|
|
||||||
.tint(accentColor.color.map(Color.init(uiColor:)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//#Preview {
|
//#Preview {
|
||||||
// ComposeView()
|
// ComposeView()
|
||||||
//}
|
//}
|
||||||
|
@ -13,7 +13,6 @@ struct EmojiTextField: UIViewRepresentable {
|
|||||||
@Environment(\.composeUIConfig.fillColor) private var fillColor
|
@Environment(\.composeUIConfig.fillColor) private var fillColor
|
||||||
@Environment(\.colorScheme) private var colorScheme
|
@Environment(\.colorScheme) private var colorScheme
|
||||||
@Environment(\.composeInputBox) private var inputBox
|
@Environment(\.composeInputBox) private var inputBox
|
||||||
@Environment(\.inputAccessoryToolbarHost) private var inputAccessoryToolbarHost
|
|
||||||
|
|
||||||
@Binding var text: String
|
@Binding var text: String
|
||||||
let placeholder: String
|
let placeholder: String
|
||||||
@ -64,10 +63,6 @@ struct EmojiTextField: UIViewRepresentable {
|
|||||||
|
|
||||||
#if !os(visionOS)
|
#if !os(visionOS)
|
||||||
uiView.backgroundColor = colorScheme == .dark ? UIColor(fillColor) : .secondarySystemBackground
|
uiView.backgroundColor = colorScheme == .dark ? UIColor(fillColor) : .secondarySystemBackground
|
||||||
|
|
||||||
if uiView.inputAccessoryView !== inputAccessoryToolbarHost {
|
|
||||||
uiView.inputAccessoryView = inputAccessoryToolbarHost
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,7 +41,6 @@ private struct NewMainTextViewRepresentable: UIViewRepresentable {
|
|||||||
@PreferenceObserving(\.$useTwitterKeyboard) private var useTwitterKeyboard
|
@PreferenceObserving(\.$useTwitterKeyboard) private var useTwitterKeyboard
|
||||||
@Environment(\.composeUIConfig.textSelectionStartsAtBeginning) private var textSelectionStartsAtBeginning
|
@Environment(\.composeUIConfig.textSelectionStartsAtBeginning) private var textSelectionStartsAtBeginning
|
||||||
@PreferenceObserving(\.$statusContentType) private var statusContentType
|
@PreferenceObserving(\.$statusContentType) private var statusContentType
|
||||||
@Environment(\.inputAccessoryToolbarHost) private var inputAccessoryToolbarHost
|
|
||||||
|
|
||||||
func makeUIView(context: Context) -> WrappedTextView {
|
func makeUIView(context: Context) -> WrappedTextView {
|
||||||
// TODO: if we're not doing the pill background, reevaluate whether this version fork is necessary
|
// TODO: if we're not doing the pill background, reevaluate whether this version fork is necessary
|
||||||
@ -95,12 +94,6 @@ 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 {
|
|
||||||
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 :/
|
||||||
if becomeFirstResponder {
|
if becomeFirstResponder {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user