iOS 15 fixes
This commit is contained in:
parent
17c67a3d5d
commit
f001e8edcd
|
@ -116,6 +116,8 @@ public struct NavigationTitlePreferenceKey: PreferenceKey {
|
||||||
|
|
||||||
private struct ToolbarActions: ToolbarContent {
|
private struct ToolbarActions: ToolbarContent {
|
||||||
@ObservedObject var draft: Draft
|
@ObservedObject var draft: Draft
|
||||||
|
// Prior to iOS 16, the toolbar content doesn't seem to have access
|
||||||
|
// to the environment form the containing view.
|
||||||
let controller: ComposeController
|
let controller: ComposeController
|
||||||
|
|
||||||
var body: some ToolbarContent {
|
var body: some ToolbarContent {
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
struct NewMainTextView: View {
|
struct NewMainTextView: View {
|
||||||
|
static var minHeight: CGFloat { 150 }
|
||||||
|
|
||||||
@Binding var value: String
|
@Binding var value: String
|
||||||
@FocusState.Binding var focusedField: FocusableField?
|
@FocusState.Binding var focusedField: FocusableField?
|
||||||
@State private var becomeFirstResponder = true
|
@State private var becomeFirstResponder = true
|
||||||
|
@ -16,6 +18,7 @@ struct NewMainTextView: View {
|
||||||
NewMainTextViewRepresentable(value: $value, becomeFirstResponder: $becomeFirstResponder)
|
NewMainTextViewRepresentable(value: $value, becomeFirstResponder: $becomeFirstResponder)
|
||||||
.focused($focusedField, equals: .body)
|
.focused($focusedField, equals: .body)
|
||||||
.modifier(FocusedInputModifier())
|
.modifier(FocusedInputModifier())
|
||||||
|
.modifier(HeightExpandingModifier(minHeight: Self.minHeight))
|
||||||
.overlay(alignment: .topLeading) {
|
.overlay(alignment: .topLeading) {
|
||||||
if value.isEmpty {
|
if value.isEmpty {
|
||||||
PlaceholderView()
|
PlaceholderView()
|
||||||
|
@ -34,6 +37,9 @@ private struct NewMainTextViewRepresentable: UIViewRepresentable {
|
||||||
@Environment(\.composeUIConfig.useTwitterKeyboard) private var useTwitterKeyboard
|
@Environment(\.composeUIConfig.useTwitterKeyboard) private var useTwitterKeyboard
|
||||||
// TODO: test textSelectionStartsAtBeginning
|
// TODO: test textSelectionStartsAtBeginning
|
||||||
@Environment(\.composeUIConfig.textSelectionStartsAtBeginning) private var textSelectionStartsAtBeginning
|
@Environment(\.composeUIConfig.textSelectionStartsAtBeginning) private var textSelectionStartsAtBeginning
|
||||||
|
#if !os(visionOS)
|
||||||
|
@Environment(\.textViewContentHeight) @Binding private var textViewContentHeight
|
||||||
|
#endif
|
||||||
|
|
||||||
func makeUIView(context: Context) -> UITextView {
|
func makeUIView(context: Context) -> UITextView {
|
||||||
let view: UITextView
|
let view: UITextView
|
||||||
|
@ -86,6 +92,16 @@ private struct NewMainTextViewRepresentable: UIViewRepresentable {
|
||||||
becomeFirstResponder = false
|
becomeFirstResponder = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !os(visionOS)
|
||||||
|
if #unavailable(iOS 16.0) {
|
||||||
|
DispatchQueue.main.async {
|
||||||
|
let targetSize = CGSize(width: uiView.bounds.width, height: UIView.layoutFittingCompressedSize.height)
|
||||||
|
let fittingSize = uiView.systemLayoutSizeFitting(targetSize, withHorizontalFittingPriority: .required, verticalFittingPriority: .defaultHigh)
|
||||||
|
textViewContentHeight = fittingSize.height
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeCoordinator() -> WrappedTextViewCoordinator {
|
func makeCoordinator() -> WrappedTextViewCoordinator {
|
||||||
|
@ -96,12 +112,11 @@ private struct NewMainTextViewRepresentable: UIViewRepresentable {
|
||||||
return coordinator
|
return coordinator
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: fallback for this on iOS 15
|
|
||||||
@available(iOS 16.0, *)
|
@available(iOS 16.0, *)
|
||||||
func sizeThatFits(_ proposal: ProposedViewSize, uiView: UIViewType, context: Context) -> CGSize? {
|
func sizeThatFits(_ proposal: ProposedViewSize, uiView: UIViewType, context: Context) -> CGSize? {
|
||||||
let width = proposal.width ?? 10
|
let width = proposal.width ?? 10
|
||||||
let size = uiView.sizeThatFits(CGSize(width: width, height: 0))
|
let size = uiView.sizeThatFits(CGSize(width: width, height: 0))
|
||||||
return CGSize(width: width, height: max(150, size.height))
|
return CGSize(width: width, height: max(NewMainTextView.minHeight, size.height))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -261,3 +276,38 @@ private struct PlaceholderView: View {
|
||||||
.allowsHitTesting(false)
|
.allowsHitTesting(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if !os(visionOS)
|
||||||
|
@available(iOS, obsoleted: 16.0)
|
||||||
|
private struct HeightExpandingModifier: ViewModifier {
|
||||||
|
let minHeight: CGFloat
|
||||||
|
|
||||||
|
@State private var height: CGFloat?
|
||||||
|
private var effectiveHeight: CGFloat {
|
||||||
|
height.map { max($0, minHeight) } ?? minHeight
|
||||||
|
}
|
||||||
|
|
||||||
|
func body(content: Content) -> some View {
|
||||||
|
if #available(iOS 16.0, *) {
|
||||||
|
content
|
||||||
|
} else {
|
||||||
|
content
|
||||||
|
.frame(height: effectiveHeight)
|
||||||
|
.environment(\.textViewContentHeight, $height)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOS, obsoleted: 16.0)
|
||||||
|
private struct TextViewContentHeightKey: EnvironmentKey {
|
||||||
|
static var defaultValue: Binding<CGFloat?> { .constant(nil) }
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOS, obsoleted: 16.0)
|
||||||
|
private extension EnvironmentValues {
|
||||||
|
var textViewContentHeight: Binding<CGFloat?> {
|
||||||
|
get { self[TextViewContentHeightKey.self] }
|
||||||
|
set { self[TextViewContentHeightKey.self] = newValue }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue