SwiftUI + UITextView: жесткое обрезка сверху/снизу рядом с панелями инструментов во время прокрутки (нужен плавный перехIOS

Программируем под IOS
Ответить
Anonymous
 SwiftUI + UITextView: жесткое обрезка сверху/снизу рядом с панелями инструментов во время прокрутки (нужен плавный перех

Сообщение Anonymous »

Я создаю экран заметок в SwiftUI (iOS 26).

Я использую UITextView через UIViewRepresentable, потому что TextEditor не обеспечивает надежную автоматическую прокрутку при перетаскивании маркеров выделения текста вверх или вниз по длинному тексту.
Проблема заключается в визуальном обрезке рядом с полосами: текст сильно обрезается сверху и снизу при прокрутке.

Мне нужно такое же плавное/мягкое поведение краев, как у Apple Примечания.
Ожидаемое поведение:
  • плавный переход между верхней и нижней полосами (без жесткого вырезания)
  • горизонтальные вставки текста около 20 пт.
  • полоса прокрутки по умолчанию остается в почти правом положении по умолчанию.
  • автопрокрутка при перетаскивании продолжает работать
Что я пробовал:
  • contentInsetAdjustmentBehavior = .automatic
  • удален вручную contentInset
  • только textContainerInset для горизонтальных заполнение текста
  • Настройки панели инструментов SwiftUI:

    .toolbarBackgroundVisibility(.automatic, for: .navigationBar, .bottomBar)
  • .scrollEdgeEffectStyle(.soft, for: [.top, .bottom])

Я подозреваю, что это связано со смешиванием UIViewRepresentable(UITextView) с эффектами прокрутки края панели инструментов SwiftUI.
Минимальный пример:

Код: Выделить всё

import SwiftUI
import UIKit

struct NoteEditorView: View {
@State private var text = "Long text..."
@FocusState private var isFocused: Bool

var body: some View {
NativeTextView(text: $text, isFocused: $isFocused, textInset: 20)
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItemGroup(placement: .topBarTrailing) {
Button {} label: { Image(systemName: "square.and.arrow.up") }
Button {} label: { Image(systemName: "ellipsis") }
}

ToolbarItem(placement: .bottomBar) {
HStack {
Button {} label: { Image(systemName: "checklist") }
Button {} label: { Image(systemName: "paperclip") }
Button {} label: { Image(systemName: "pencil.tip.crop.circle") }
}
}
}
.toolbarBackgroundVisibility(.automatic, for: .navigationBar, .bottomBar)
.scrollEdgeEffectStyle(.soft, for: [.top, .bottom])
}
}

struct NativeTextView: UIViewRepresentable {
@Binding var text: String
var isFocused: FocusState.Binding
let textInset: CGFloat

func makeUIView(context: Context) -> UITextView {
let tv = UITextView()
tv.delegate = context.coordinator
tv.backgroundColor = .clear
tv.isScrollEnabled = true
tv.alwaysBounceVertical = true
tv.keyboardDismissMode = .interactive
tv.contentInsetAdjustmentBehavior = .automatic
tv.font = .preferredFont(forTextStyle: .body)
tv.textContainer.lineFragmentPadding = 0
tv.textContainerInset = UIEdgeInsets(top: 8, left: textInset, bottom: 16, right: textInset)
tv.text = text
return tv
}

func updateUIView(_ uiView: UITextView, context: Context) {
if uiView.text != text { uiView.text = text }

if isFocused.wrappedValue, !uiView.isFirstResponder {
uiView.becomeFirstResponder()
} else if !isFocused.wrappedValue, uiView.isFirstResponder {
uiView.resignFirstResponder()
}
}

func makeCoordinator() -> Coordinator { Coordinator(self) }

final class Coordinator: NSObject, UITextViewDelegate {
var parent: NativeTextView
init(_ parent: NativeTextView) { self.parent = parent }
func textViewDidChange(_ textView: UITextView) {
parent.text = textView.text
}
}
}
Как правильно настроить это, чтобы обрезка не была сложной и переход соответствовал поведению Apple Notes?

Подробнее здесь: https://stackoverflow.com/questions/798 ... rolling-wa
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «IOS»