Проблема Swiftui LazyVStack на iOS 17, 18IOS

Программируем под IOS
Ответить
Anonymous
 Проблема Swiftui LazyVStack на iOS 17, 18

Сообщение Anonymous »

Я не могу понять, почему LazyVStack иногда не восстанавливается после отключения клавиатуры. Я понял одну вещь: когда размеры представлений внутри LazyVStack одинаковы, проблем не будет, но когда размер меняется, эта проблема возникает.
Lazy отображается желтым фоном, а представление прокрутки - зеленым. Просто сформулируйте это так, чтобы ясно показать мою проблему.
Изображение

struct MessagesView: View {
@State private var messages: [ChatMessage] = MockChatMessages().loadAllMessages()
@State private var inputText: String = ""
@Binding var showChat: Bool

@State private var scrollToID: Int? // Used for iOS 17 auto-scroll

var body: some View {
VStack(spacing: 0) {
HeaderView()
MessagesList(messages: messages, scrollToID: $scrollToID)
InputBar(inputText: $inputText, onSend: sendMessage)
}
.background(Color.blue.opacity(0.3))
.ignoresSafeArea(edges: .top)
.onAppear {
scrollToID = messages.last?.id
}
.onChange(of: messages.count) { _ in
scrollToID = messages.last?.id
}
}
}

// MARK: - Header
struct HeaderView: View {
var body: some View {
if #available(iOS 17.0, *) {
Text("Chat")
.frame(width: UIScreen.main.bounds.width, height: 70)
.padding(.top, 20)
.safeAreaPadding(.top)
.background(Color.red.opacity(0.5))
.clipShape(Rectangle())

} else {
Text("Chat")
.frame(height: 70)
.background(Color.red.opacity(0.5))
.clipShape(Rectangle())
.padding(.top, 20)
} }
}

// MARK: - Messages List
struct MessagesList: View {
var messages: [ChatMessage]
@Binding var scrollToID: Int?

var body: some View {
if #available(iOS 17.0, *) {
ScrollView {
LazyVStack(spacing: 14) {
ForEach(messages, id: \.id) { msg in
MessageBubble(message: msg)
}
}
.padding(.vertical)
.background(Color.yellow.opacity(0.5))
}
.background(Color.green.opacity(0.5))
.scrollIndicators(.hidden)
.scrollPosition(id: $scrollToID, anchor: .bottom)
} else {
ScrollViewReader { proxy in
ScrollView {
LazyVStack(spacing: 14) {
ForEach(messages, id: \.id) { msg in
MessageBubble(message: msg)
.id(msg.id)
}
}
.padding(.vertical)
}
.onChange(of: scrollToID) { id in
if let id = id {
withAnimation {
proxy.scrollTo(id, anchor: .bottom)
}
}
}
}
}
}
}

// MARK: - Input Bar
struct InputBar: View {
@Binding var inputText: String
var onSend: () -> Void

var body: some View {
HStack {
TextField("Type your message...", text: $inputText)
.padding(12)
.background(Color.white)
.clipShape(RoundedRectangle(cornerRadius: 10))

Button(action: onSend) {
Text("Send")
.foregroundColor(.white)
.padding(.vertical, 10)
.padding(.horizontal, 16)
.background(Color.blue)
.clipShape(RoundedRectangle(cornerRadius: 10))
}
}
.padding(.horizontal)
.padding(.bottom, 12)
.background(Color.gray.opacity(0.15))
}
}

// MARK: - Single Message Bubble
struct MessageBubble: View {
var message: ChatMessage

var isRight: Bool { message.direction == .right }

var body: some View {
HStack {
if isRight { Spacer() }

Text(message.message)
.foregroundColor(isRight ? .white : .black)
.padding(.vertical, 10)
.padding(.horizontal, 12)
.background(isRight ? Color.black : Color.white)
.clipShape(RoundedRectangle(cornerRadius: 14))
.frame(maxWidth: UIScreen.main.bounds.width * 0.7, alignment: isRight ? .trailing : .leading)

if !isRight { Spacer() }
}
.padding(.horizontal, 12)
}
}

// MARK: - Add Message Function
extension MessagesView {
func sendMessage() {
guard !inputText.isEmpty else { return }

let nextID = (messages.last?.id ?? 0) + 1

let msg = ChatMessage(
id: nextID,
direction: .right,
message: inputText
)

messages.append(msg)
inputText = ""
scrollToID = msg.id
}
}


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

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

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

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

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

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