SwiftUI ScrollView не оновлюється?


10

Мета

Отримати дані для відображення в scrollView

Очікуваний результат

дані, показані в перегляді прокрутки

Фактичний результат

порожній вид

Альтернатива

використання List, але він не є гнучким (не може видалити роздільники, не може мати кілька стовпців)

Код

struct Object: Identifiable {
    var id: String
}

struct Test: View {
    @State var array = [Object]()

    var body: some View {
//        return VStack { // uncomment this to see that it works perfectly fine
        return ScrollView(.vertical) {
            ForEach(array) { o in
                Text(o.id)
            }
        }
        .onAppear(perform: {
            self.array = [Object(id: "1"),Object(id: "2"),Object(id: "3"),Object(id: "4"),Object(id: "5")]
        })
    }
}

Я перевірив це на Xcode 11.1, iOS 13.1, Swift 5 і отримую очікуваний результат (хоча вид прокрутки знаходиться вгорі, а не в центрі).
sfung3

Вам також не потрібне ключове словоreturn
sfung3

цікаво, я на Xcode 11.2, iOS 13.2, Swift 5
youjin

так, я мав printзаяву раніше, звідсиreturn
youjin

Я оновлю до Xcode 11.2 і побачу, чи зможу це відтворити. Це може зайняти деякий час, але я поінформую вас про свої висновки.
sfung3

Відповіді:


10

Не настільки шалений спосіб подолати цю проблему - укласти ScrollView у IF-операторі, який перевіряє, чи масив порожній

if !self.array.isEmpty{
     ScrollView(.vertical) {
          ForEach(array) { o in
               Text(o.id)
          }
     }
}

Це рішення ідеально, дякую!
Гендрик

1

Очікувана поведінка трапляється на, Xcode 11.1але не наXcode 11.2.1

Я додав frameмодифікатор, ScrollViewякий зробить ScrollViewпояву

struct Object: Identifiable {
    var id: String
}

struct ContentView: View {
    @State var array = [Object]()

    var body: some View {
        ScrollView(.vertical) {
            ForEach(array) { o in
                Text(o.id)
            }
        }
        .frame(height: 40)
        .onAppear(perform: {
            self.array = [Object(id: "1"),Object(id: "2"),Object(id: "3"),Object(id: "4"),Object(id: "5")]
        })
    }
}

На жаль, не вдається змусити його працювати на iOS 13.2 на Simulator
youjin

1

Я виявив, що він працює (Xcode 11.2), як очікувалося, якщо стан ініціалізується з деяким значенням, а не порожнім масивом. У цьому випадку оновлення працює правильно і початковий стан не впливає.

struct TestScrollViewOnAppear: View {
    @State var array = [Object(id: "1")]

    var body: some View {
        ScrollView(.vertical) {
            ForEach(array) { o in
                Text(o.id)
            }
        }
        .onAppear(perform: {
            self.array = [Object(id: "1"),Object(id: "2"),Object(id: "3"),Object(id: "4"),Object(id: "5")]
        })
    }
}

це працює для простого випадку, у моєму випадку я зателефонував у мережу onAppear, тому ініціалізація scrollView з фіктивними даними може бути проблематичною
youjin

правильно, але ця ситуація може бути керована логічно в коді, тому що початковий об'єкт може бути легким виявленням-заглушкою, щоб умовно показати щось на кшталт "завантаження" тощо. Для мене цього було досить ... тому варто поділитися.
Аспері

1

Я знайшов один хиткий спосіб вирішення питання - додати "невидимий" Rectangleвсередині scrollView, при цьому widthвстановлено значення, яке перевищує ширину даних уscrollView

struct Object: Identifiable {
    var id: String
}

struct ContentView: View {
    @State var array = [Object]()

    var body: some View {
        GeometryReader { geometry in
            ScrollView(.vertical) {
                Rectangle()
                    .frame(width: geometry.size.width, height: 0.01)
                ForEach(array) { o in
                    Text(o.id)
                }
            }
        }
        .onAppear(perform: {
            self.array = [Object(id: "1"),Object(id: "2"),Object(id: "3"),Object(id: "4"),Object(id: "5")]
        })
    }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.