SwiftUI TextField урезан пополам

Я новичок, когда дело доходит до программирования на Swift, и пытаюсь научиться создавать собственное приложение для чата с помощью некоторых руководств на Youtube. Я продвинулся довольно далеко, но попал в ловушку. Я не понимаю, почему, когда я пытаюсь прокрутить это представление в SwiftUI, сообщение обрывается на полпути. Я думал, что это как-то связано с отступами, но отступы должны быть установлены на все. Посмотрите на скриншот ниже:

Я не уверен, что я делаю неправильно в своем коде, поскольку все работает. Мой код прикреплен ниже. Любая помощь будет оценена по достоинству!

import SwiftUI

struct ChatUIView: View {
    
    @State var message = ""
    //StateObject is the owner of the object...
    @StateObject var allMessages = Messages()
    
    var body: some View {
        VStack{
            
            ZStack{
                
                /*
                HStack{
                    Spacer()
                }*/
                
                VStack(spacing:5){
                    Text("Chat")
                        .fontWeight(.bold)
                }
                .foregroundColor(.white)
            }
            .padding(.all)
            
            //Spacer()
            VStack{
                
                //Spacer()
                //Displaying Message...
                
                ScrollView(.vertical, showsIndicators: false, content: {
                    
                    ScrollViewReader{reader in
                        
                        VStack(spacing: 20){
                            
                            ForEach(allMessages.messages){msg in
                                
                                //Chat Bubbles...
                                
                                ChatBubble(msg: msg)
                            
                                
                            }
                            //whenever new data is inserted, scroll to bottom...
                            .onChange(of: allMessages.messages) {(value) in
                                
                                //scrolling only user message...
                                
                                if value.last!.myMsg{
                                    reader.scrollTo(value.last?.id)
                                }
                                
                            }
                        }
                        .padding([.horizontal, .bottom])
                        .padding(.top, 25)
                    }
                })
                
                HStack(spacing:15){
                    
                    HStack(spacing: 15){
                        TextField("Message", text: self.$message)
                    }
                    .padding(.vertical, 12)
                    .padding(.horizontal)
                    .background(Color.black.opacity(0.06))
                    .clipShape(Capsule())
                    
                    
                    //send button
                    //hiding view...
                    if message != ""{
                        Button(action: {
                            
                            //appending message...
                            
                            //adding animation...
                            withAnimation(.easeIn){
                                allMessages.messages.append(Message(id: Date(), message: message, myMsg: false))
                            }
                            message = ""
                            
                        }, label: {
                            
                            Image("send")
                                .resizable()
                                .frame(width: 25, height: 25)
                                .rotationEffect(.init(degrees: 45))
                                .padding()
                                //.aspectRatio(contentMode: .fit)
                                //.font(.system(size: 0.5))
                                //.padding(.all)
                                .background(Color.black.opacity(0.07))
                                .clipShape(Circle())
                        })
                    }
                }
                .padding(.horizontal)
                .animation(.easeOut)
            }
            .padding(.bottom, UIApplication.shared.windows.first?.safeAreaInsets.bottom)
            .background(Color.white)
            .clipShape(RoundedShape())
        }
        //.edgesIgnoringSafeArea(.bottom)
        .background(Color.blue.edgesIgnoringSafeArea(.top))
    }
}

//Chat Bubbles...

struct ChatBubble : View {
    
    var msg : Message
    var body: some View{
        
        //Automatics scroll to bottom...
        //First assigning id to each row
        
        HStack(alignment: .top, spacing: 10){
            
            if msg.myMsg{
                
                //pushing msg to the left...
                
                //minimum space ...
                Spacer(minLength: 25)
                
                Text(msg.message)
                    .padding(.all)
                    .background(Color.black.opacity(0.06))
                    //.cornerRadius(15)
                    .clipShape(BubbleArrow(myMsg: msg.myMsg))
            } else {
                
                //pushing msg to the right...
                
                Text(msg.message)
                    .lineLimit(nil)
                    .foregroundColor(.white)
                    .padding(.all)
                    //.background(Color.black.opacity(0.06))
                    .background(Color.blue)
                    .clipShape(BubbleArrow(myMsg: msg.myMsg))
                
                Spacer(minLength: 25)
            }
        }
        .id(msg.id)
        //.padding(msg.myMsg ? .leading : .trailing, 55)
        //.padding(.vertical,10)
    }
}

// Bubble Arrow...

struct BubbleArrow : Shape {
    
    var myMsg : Bool
    
    
    func path(in rect: CGRect) -> Path {
        let path = UIBezierPath(roundedRect: rect, byRoundingCorners: myMsg ? [.topLeft, .bottomLeft, .bottomRight] : [.topRight, .bottomLeft, .bottomRight], cornerRadii: CGSize(width: 10, height: 10))
        
        return Path(path.cgPath)
    }
}


// Custom Rounded Shape...

struct RoundedShape : Shape {
    
    func path(in rect: CGRect) -> Path {
        let path = UIBezierPath(roundedRect: rect, byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: 35, height: 35))
        
        return Path(path.cgPath)
    }
}

// Model Data For Message...

struct Message : Identifiable, Equatable {
    
    var id: Date
    var message: String
    var myMsg: Bool
    //var profilePic: String
    //var photo: Data?
    
}

class Messages: ObservableObject {
    
    @Published var messages : [Message] = []
    
    //sample data...
    init() {
        let strings = ["Hi!", "hello!", "How are you doing?!", "Fine, I just want to talk about life", "ok, I may be able to help with that", "This is awesome, thanks", "So what do you want to talk about?", "movies sound like a good topic. Let's start there!", "Ok, so tell me: What's you favorite movie?", "Definitely, interstellar for sure."]
        
        for i in 0..<strings.count{
            
            //simple logic for two sided message View...
            
            messages.append(Message(id: Date(), message: strings[i], myMsg: i % 2 == 0 ? false : true))
        }
    }
    
    func writeMessage(id: Date, msg: String, photo: Data?, myMsg: Bool){
        
        messages.append((Message(id: id, message: msg, myMsg: myMsg)))
        
        
    }
}

В качестве отправной точки взгляните на иерархию представлений, чтобы лучше понять, что на самом деле происходит.

Software2 19.12.2020 17:01

Это выглядит как ошибка ScrollView, по крайней мере, в iOS 14.1. Если ScrollView находится в полной области (т. е. без верхнего/нижнего колонтитула), то все в порядке.

Asperi 19.12.2020 17:58
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
2
524
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Вы можете попробовать использовать fixedSize:

Text(msg.message)
    .fixedSize(horizontal: false, vertical: true)

В моем Xcode 12.1/iOS 14.1 это не решает проблему. Вы проверили это? Какая среда?

Asperi 19.12.2020 17:57

@Asperi Я использую Xcode 12.3 / iOS 14.3, и он работает, как и ожидалось (даже без fixedSize). Это действительно похоже на ошибку.

pawello2222 19.12.2020 18:02

Наконец! Кое-что поправили в новой версии 12.х... до этого встречал только баги ))

Asperi 19.12.2020 18:28

@ pawello2222 pawello2222 Я уже пробовал это в своем коде, и это не сработало. решение, которое я принял, сработало для меня

jeff-ridgeway 19.12.2020 20:25
Ответ принят как подходящий

Проблема заключается в использовании .clipShape(RoundedShape()) в VStack, содержащем ScrollView, TextField и Button. Если вы заметили, дело не только в том, что сообщение разрезано пополам, но и в том, что никакие другие сообщения (есть еще одно) не отображаются. Пользовательская форма RoundedShape недостаточно велика, чтобы охватить все виды. Когда я переключаю его на прямоугольник, встроенную форму, все отображается. Я не понимаю, почему в иерархии представлений, но это проблема. Я оставлю это кому-то другому, чтобы определить, что с ним происходит.

Когда вы пытаетесь отладить иерархию представлений, начните с модификаторов. Комментируйте их, пока что-то не изменится, а затем изучите их. Кроме того, порядок модификаторов имеет значение, так как использование модификатора в представлении дает вам совершенно новое представление. Попробуйте что-нибудь простое, например, поставьте .padding перед .font на Text, и вы получите сообщение об ошибке. Это связано с тем, что в дополненном представлении нет шрифта-модификатора, хотя в модифицированном представлении шрифт есть.

Я принял это как ответ, потому что это сработало. Большое спасибо, и я буду иметь это в виду в будущем!

jeff-ridgeway 19.12.2020 20:24

вопрос: я изменил clipShape на Rectangle(), но теперь, когда я использую клавиатуру, он появляется, а затем быстро исчезает. У меня есть ошибка с .clipShape Rectangle()

jeff-ridgeway 19.12.2020 20:37

Это хороший вопрос, и другой вопрос. SwiftUI не имеет (пока, я надеюсь) родной блокировки клавиатуры, так что придется использовать свою. По сути, вы resignFirstResponder или переключаете фокус на другой элемент. Если это происходит в вашем коде, это объясняет клавиатуру. Я не проверял это, когда отлаживал ваш код, и удалил то, что у меня было.

Yrb 19.12.2020 20:45

Другие вопросы по теме