0

我有一个水平滚动视图,它显示了来自动态图像数组的一堆图像。当总内容宽度大于屏幕宽度时,一切都很好。但是,如果说数组中只有一个图像,它将前导对齐,这是默认行为。

当总内容宽度小于屏幕宽度并且不确定如何实现时,我希望内容居中:

ScrollView(.horizontal) {
    HStack {
        ForEach(images.indices, id: \.self) { index in
            let image = images[index] {
                Image(uiImage(uiImage: image))
            }
        }
    }
    .frame(height: 200)
}

所以在这种情况下,如果只有一个图像它是对齐的,但我希望它居中,直到内容填满屏幕然后滚动。我不介意反弹或不反弹,直到它填满屏幕。

4

1 回答 1

0

您可以使用并GeometryReader设置 aminWidth内容ScrollView

示例(出于测试目的将图像换成颜色):

struct ContentView: View {
    @State private var width: CGFloat?
    private let total = 10//0

    var body: some View {
        ScrollView(.horizontal) {
            HStack {
                ForEach(0 ..< total) { index in
                    Color.red.opacity(Double(index) / Double(total) + 0.05)
                        .frame(width: 20)
                }
//                ForEach(images.indices, id: \.self) { index in
//                    let image = images[index] {
//                        Image(uiImage(uiImage: image))
//                    }
//                }
            }
            .frame(height: 200)
            .frame(minWidth: width)
        }
        .widthReader { width in
            self.width = width
        }
    }
}

自定义widthReader(_:)修饰符:

extension View {
    func widthReader(_ width: @escaping (CGFloat?) -> Void) -> some View {
        modifier(WidthReaderModifier(width: width))
    }
}

fileprivate struct WidthReaderModifier: ViewModifier {
    private struct WidthPreferenceKey: PreferenceKey {
        static func reduce(value: inout CGFloat?, nextValue: () -> CGFloat?) {
            value = nextValue()
        }
    }

    let width: (CGFloat?) -> Void

    func body(content: Content) -> some View {
        content
            .background(
                GeometryReader { geo in
                    Color.clear
                        .preference(key: WidthPreferenceKey.self, value: geo.size.width)
                        .onAppear {
                            width(geo.size.width)
                        }
                }
            )
            .onPreferenceChange(WidthPreferenceKey.self) { width in
                self.width(width)
            }
    }
}
于 2021-08-12T10:20:51.810 回答