如何更新ScrollView中的内容:SwiftUI

时间:2020-07-27 17:38:34

标签: swift xcode uiscrollview swiftui uiviewrepresentable

我正在尝试在滚动视图中更新内容,但是由于makeUIView在构建视图时仅调用了一次。当我单击1张图像然后单击2张图像时,它不会刷新。

但是,如果我单击“无图像”,然后单击“图像2”,它将按预期工作。

ScrollView Issue.

这是我的代码。

struct ContentView: View {
    @State var images:[String] = []
    var body: some View {
        VStack{
            HStack{
                Button(action: { self.images = [] }, label: {
                    Text("No Images")
                })
                Button(action: { self.images = ["sample_1"] }, label: {
                    Text("1 Images")
                })
                Button(action: { self.images = ["sample_1","sample_2"] }, label: {
                    Text("2 Images")
                })
            }
            if self.images.count > 0{
                GeometryReader { (reader) in
                    STHorizontalScrollView(images: self.images, size: reader.size)
                }
            }else{
                Text("No Images")
            } 
        }
    }
}

struct STHorizontalScrollView:UIViewRepresentable {
    var images:[String]
    var size:CGSize
    func makeUIView(context: Context) -> UIScrollView {
        let scrollView = UIScrollView()
    
        // Calculating the Width
        let widthForContent = CGFloat(self.images.count) * size.width
        scrollView.contentSize = CGSize.init(width: widthForContent, height: size.height)
        scrollView.isPagingEnabled = true
   
        // Hosting Controller
        let hostingController = UIHostingController(rootView: HorizontalList(images: images, size: size))
        hostingController.view.frame = CGRect.init(x: 0, y: 0, width: widthForContent, height: size.height)
    
        // Add View to scrollview
       scrollView.addSubview(hostingController.view)
    
        return scrollView
    }
    func updateUIView(_ uiView: UIScrollView, context: Context) {
    
    }
}

struct HorizontalList:View {
    var images:[String]
    var size:CGSize
    var body: some View{
        HStack(spacing: 0.0) {
            ForEach(self.images, id:\.self){ image in
                Image(image)
                    .resizable()
                    .aspectRatio(contentMode: ContentMode.fill)
                    .frame(width: self.size.width, height: self.size.height)
                    .clipped()
            }
        }
    }
}

由于实际内容位于HorizontalList结构中,因此不确定在update方法中在此处写些什么。

任何帮助将不胜感激。

谢谢

1 个答案:

答案 0 :(得分:2)

每当依赖数据的某些绑定更新时,Representable就会更新,因此,当图像更改时,您需要在更新updateUIView中重建内部结构。

这是一个解决方案。经过Xcode 11.4 / iOS 13.4的测试

enter image description here

可代表的用途

// images as binding
STHorizontalScrollView(images: self.$images, size: reader.size)

并具有可表示性

struct STHorizontalScrollView:UIViewRepresentable {
    @Binding var images:[String]
    var size:CGSize

    func makeUIView(context: Context) -> UIScrollView {
        UIScrollView()
    }

    func updateUIView(_ scrollView: UIScrollView, context: Context) {
        _ = scrollView.subviews.map { $0.removeFromSuperview() }
        guard images.count != 0 else { return }
        
        // Calculating the Width
        let widthForContent = CGFloat(self.images.count) * size.width
        scrollView.contentSize = CGSize.init(width: widthForContent, height: size.height)
        scrollView.isPagingEnabled = true

        // Hosting Controller
        let hostingController = UIHostingController(rootView: HorizontalList(images: images, size: size))
        hostingController.view.frame = CGRect.init(x: 0, y: 0, width: widthForContent, height: size.height)

        // Add View to scrollview
       scrollView.addSubview(hostingController.view)
    }
}