struct PanoramaView: View {
let image: UIImage
private struct Item: Identifiable, Equatable {
let id = UUID()
var pos: CGFloat!
}
@State private var items = [Item(), Item()]
// ...
var body: some View {
GeometryReader { gp in
let centerY = gp.size.height / 2
ForEach($items) { $item in
Image(uiImage: image)
.resizable().aspectRatio(contentMode: .fill)
.position(x: item.pos ?? 0, y: centerY)
.offset(x: dragOffset)
}
}
.background(GeometryReader {
Color.clear.preference(key: ViewSizeKey.self,
value: $0.frame(in: .local).size)
})
.onPreferenceChange(ViewSizeKey.self) {
setupLayout($0)
}
.contentShape(Rectangle())
.gesture(scrollGesture)
}
和使用
let panorama = UIImage(contentsOfFile: Bundle.main.path(forResource: "panorama", ofType: "jpeg")!)!
var body: some View {
PanoramaView(image: panorama)
.frame(height: 300) // to demo of dynamic internal layout
}
2条答案
按热度按时间ubof19bj1#
实际上,对于这样准备的图像,只需加载一次就足够了,我们只需要为它提供图像演示者(注意:它们不复制存储器,而是使用相同的加载图像)。其他的一切都只是关于布局的飞行移动当前的屏幕项目取决于拖动方向的左边或右边的当前之一。
已测试Xcode 13.4 / iOS 15.5
代码的主要部分:
和使用
Complete test code is here
kr98yfug2#
您可以将3个相同的全景图像彼此相邻(以便能够滚动边缘),并添加自定义DragGesture,基本上跳回到中间图像的相对位置。
这个图像是一个不好的例子,显然它会更好地与一个真实的的360°图像;)
编辑:
现在具有预测的结束位置+动画和5个图像。