SwiftUI ScrollView không được cập nhật?


10

Mục tiêu

Nhận dữ liệu để hiển thị trong một scrollView

Kết quả mong đợi

dữ liệu hiển thị trong scrollview

Kết quả thực tế

một cái nhìn trống

Thay thế

sử dụng List, nhưng nó không linh hoạt (không thể xóa dấu phân cách, không thể có nhiều cột)

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")]
        })
    }
}

Tôi đã thử nghiệm điều này trên Xcode 11.1, iOS 13.1, Swift 5 và đang nhận được kết quả mong đợi (mặc dù chế độ xem cuộn ở trên đầu thay vì ở giữa).
sfung3

Bạn cũng không cần từ khóareturn
sfung3

thật thú vị, tôi đang sử dụng Xcode 11.2, iOS 13.2, Swift 5
youjin

vâng tôi đã có một printtuyên bố trước đó, do đóreturn
youjin

Tôi sẽ cập nhật lên Xcode 11.2 và xem liệu tôi có thể sao chép này không. Có thể mất một lúc nhưng tôi sẽ cập nhật cho bạn về những phát hiện của tôi.
sfung3

Câu trả lời:


10

Một cách không quá rắc rối để khắc phục vấn đề này là bao quanh ScrollView trong câu lệnh IF để kiểm tra xem mảng có trống không

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

Cách giải quyết này là hoàn hảo, cảm ơn bạn!
Hendrik

1

Hành vi dự kiến ​​xảy ra Xcode 11.1nhưng khôngXcode 11.2.1

Tôi đã thêm một framesửa đổi để ScrollViewlàm cho ScrollViewxuất hiện

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")]
        })
    }
}

Thật không may, không thể làm cho nó hoạt động trên iOS 13.2 trên Trình mô phỏng
youjin

1

Tôi đã thấy rằng nó hoạt động (Xcode 11.2) như mong đợi nếu trạng thái được khởi tạo với một số giá trị, không phải là mảng trống. Trong trường hợp này cập nhật hoạt động chính xác và trạng thái ban đầu không có hiệu lực.

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")]
        })
    }
}

hoạt động cho trường hợp đơn giản, trong trường hợp của tôi, tôi có một cuộc gọi mạng onAppear, vì vậy việc khởi tạo scrollView với dữ liệu giả có thể có vấn đề
youjin

đúng, nhưng tình huống này có thể được xử lý một cách hợp lý trong mã, bởi vì đối tượng ban đầu có thể là một số sơ khai dễ phát hiện để hiển thị một cách có điều kiện như 'tải', v.v. đối với tôi điều này là đủ ... rất đáng để chia sẻ.
Asperi

1

Một cách giải quyết khó khăn mà tôi đã tìm thấy là thêm một "vô hình" Rectanglebên trong scrollView, với widthgiá trị được đặt thành giá trị lớn hơn chiều rộng của dữ liệu trongscrollView

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")]
        })
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.