SwiftUIPanoramaViewer

SwiftUIPanoramaViewer 是一个高性能库,它使用 SceneKit 来显示完整的球形或圆柱形全景图,并支持触摸、游戏手柄或基于运动的控制,可在 SwiftUI 项目中使用。

起源

SwiftUIPanoramaViewer 基于 scihant'sCTPanoramaView 开源库的源代码,我对其进行了大量修改,以支持现代 OSesSwiftUI、读取 Pitch & Yaw、支持 游戏手柄 以及更多功能。

为什么要创建一个新的库? 我发布 SwiftUIPanoramaViewer 作为一个新的库/包,而不是在 CTPanoramaView 上提交 pull request,原因有几个,但主要原因是以下两个:首先,看起来 CTPanoramaView 不再被支持。 其次,我所做的 SwiftUI 更改使得 CTPanoramaView 偏离了其支持 UIKit 和 Objective-C 的原始设计。

因此,您将在软件包中找到我的 MIT 许可证,以及 scihant's 的原始 MIT 许可证,该许可证来自 CTPanoramaView 开源库。

支持

如果您发现 SwiftUIPanoramaViewer 有用,并希望帮助支持其持续开发和维护,请考虑进行少量捐赠,尤其是在您将其用于商业产品时

Buy Me A Coffee

正是通过像您这样的贡献者的支持,我才能继续构建、发布和维护高质量、文档完善的 Swift 包,例如免费的 SwiftUIPanoramaViewer

安装

使用 Xcode 的 Swift Package Manager

  1. 在 Xcode 中,选择 File > Add Package Dependency… 菜单项。
  2. https://github.com/Appracatappra/SwiftUIPanoramaViewer.git 粘贴到对话框中。
  3. 按照 Xcode 的说明完成安装。

为什么不选择 CocoaPods、Carthage 等?

支持多个依赖项管理器会使维护库的复杂性和耗时呈指数级增长。

由于 Swift Package Manager 与 Xcode 集成,因此它是最容易支持的进一步选择。

概述

SwiftUIPanoramaViewer 提供了一种简单的方法,可以将交互式球形或圆柱形全景查看器添加到任何 SwiftUI View。 让我们看下面的例子

@State var rotationIndicator:Float = 0.0
...

ZStack {
	// Display the panorama
	PanoramaViewer(image: SwiftUIPanoramaViewer.bindImage("PanoramaImageName")) {key in }
	cameraMoved: { pitch, yaw, roll in
	    rotationIndicator = yaw
	}

	VStack {
		Spacer()
	
		CompassView()
	   .frame(width: 50.0, height: 50.0)
	   .rotationEffect(Angle(degrees: Double(rotationIndicator)))
	}
}
// If using `SwiftUIGamepad` package, allow the gamepad to rotate the view.
.onGamepadLeftThumbstick(viewID: viewID) { xAxis, yAxis in
    PanoramaManager.moveCamera(xAxis: xAxis, yAxis: yAxis)
}

让我们分解一下关键点

如果想将全景图像存储在 按需资源 中,请参阅我们的 ODRManager Package,以帮助您更轻松地使用 ODR。

在其当前实现中,一次只能在您的应用程序中激活一个 PanoramaViewer。 您可以使用 PanoramaManager 单例类与当前活动的查看器通信。

添加游戏手柄支持

通过在您的 SwiftUI 应用程序中包含我们的 SwiftUIGamepad Package,可以轻松地将游戏手柄支持添加到 PanoramaViewer。 以下代码行允许连接的游戏手柄的左拇指杆移动全景视图

// If using `SwiftUIGamepad` package, allow the gamepad to rotate the view.
.onGamepadLeftThumbstick(viewID: viewID) { xAxis, yAxis in
    PanoramaManager.moveCamera(xAxis: xAxis, yAxis: yAxis)
}

使用 PanoramaManager.moveCamera 传达全景视图中 xAxis(或 yaw)和 yAxis(或 pitch)的变化量。 cameraMoved 事件将在 PanoramaViewer 上响应此更改而引发。

在 SwiftUI View 中使用 SwiftUIGamepad 需要比此处显示的更多设置。 为了简洁起见,仅显示了 SwiftUIPanoramaViewer 的特定部分。 有关所需的完整设置,请参阅 SwiftUIGamepad DocC 文档。

显示视图标记和交互点

通过创建您自己的存储类并记录给定全景图像中的特定 pitchyaw 点,您可以创建 IndicatorsInteraction Points,这些点可以响应 cameraMoved 事件而显示。

如果返回到 cameraMoved 事件的 pitchyaw 点与结构中的特定点匹配,只需使用 ZStack 显示覆盖在 PanoramaViewer 上的 IconButton

PanoramaManager 单例类提供了几个辅助函数来协助完成此任务

由于可以在 SwiftUI 应用程序中使用 PanoramaViewer 的所有不同方式,因此提供所有数据结构以支持交互和节点导航超出了此库的范围。 任何“默认”实现对于任何给定应用程序的需求来说都可能过于局限或过于复杂。

因此,我决定提供易于实现此功能的工具,同时将具体细节留给消费应用程序的代码。

在用户交互时更改全景图像

如果您需要由于用户交互(或任何其他应用程序内事件)而更改 PanoramaViewer 中显示的全景图像,则需要执行一些额外的步骤。 请参阅以下代码片段

@State var panoImage:String = "MyImage"
...

PanoramaViewer(image: SwiftUIPanoramaViewer.bindImage(panoImage))
...

// Change the displayed image
PanoramaManager.shouldUpdateImage = true
PanoramaManager.shouldResetCameraAngle = false
panoImage = "newPanoImage"

在此代码中,我们使用 State 变量 panoImage 来保存当前显示的全景图像。 以下是关键点

更改 PanoramaViewer 中显示的全景图像的请求应在主线程上执行以获得最佳效果。

文档

Package 包括其所有功能的完整 DocC Documentation