這次決定使用 SwiftUI 作為專案主框架,ARKit 的部分再用 UIViewRepresentable 作為 UIKit 的橋接層。
直白的專案名稱:
import SwiftUI
@main
struct MagicWandARApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
今天的目標是讓 App 打開就能開到滿版的 AR 畫面(包含自拍鏡頭兩旁),畫面中只要呈現相機見到的世界,不放任何物件。
先將負責呈現 AR 的 ARViewContainer
放到 ContentView
裡面,並且使用 .ignoresSafeArea(_:edges:)
修飾器達成全景畫面的效果:
import SwiftUI
struct ContentView: View {
var body: some View {
ARViewContainer()
.ignoresSafeArea()
}
}
ARViewContainer
作為呈現 AR 世界的容器,需要 import ARKit
框架。ARViewContainer
遵從 UIViewRepresentable
之後的第一件事情,就是實作 makeUIView(context:),這樣才能讓 UIKit 的 View 在 SwiftUI 框架中顯示出來。
struct ARViewContainer: UIViewRepresentable {
func makeUIView(context: Context) -> ARSCNView {
let view = ARSCNView()
view.scene = SCNScene()
view.automaticallyUpdatesLighting = true
let config = ARWorldTrackingConfiguration()
view.session.run(config)
return view
}
}
makeUIView(context: Context)
實作說明:
let view = ARSCNView()
我們需要一個 ARSCNView 來呈現 ARSession。ARSCNView 結合了 ARKit 的相機追蹤與世界理解,以及 SceneKit 的 3D 場景渲染,讓我們能在同一個畫面中同時看到真實世界與虛擬物件。
view.scene = SCNScene()
指定一個空的 3D SCNScene 場景讓 view 能呈現出相機畫面。之後有 3D 物件都是放到這裡。
view.automaticallyUpdatesLighting = true
開啟 automaticallyUpdatesLighting,能夠利用 ARKit 的光線估測,自動調整 SceneKit 物件的光照與陰影,讓畫面更貼近現場光線。(如果只是要讓畫面跑起來,可以不用開啟這個設定,開啟的話則可以注意到畫面有在調整光線)
let config = ARWorldTrackingConfiguration()
在此建立 AR 的追蹤設定物件,這是 ARKit 中最常用的設定。
view.session.run(config)
這裡的 session 就是 ARSession 了,讓他運作起來吧!
等等,在按下 Run 之前,我們還需要到 info.plist 填個設定(必要!),請求使用者允許我們使用相機:
好,真的來 Run 了,因為是 AR 要使用相機,因此在實機上運行:
可以看到手機上滿版的相機畫面,並且有根據周圍的黃光也變得黃黃的(一打開是沒那麼黃...),我們完成今天的目標啦!
今天就到這裡
...
...
...
...
...了嗎?
還沒結束!
當我在查官網的 ARSCNView 時,赫然發現 ARSCNView 將在未來被棄用啦!
要篡位的人是 RealityView。
因為 RealityView
有支援到 iOS 18,我猶豫了一會,要不要直接放棄 ARSCNView。
但為了之後若上架能有更多人能下載(想太多),今天也來試試看使用 RealityView
的方法吧!
先設定版本與相對的 view,記得多 import RealityKit 框架:
import SwiftUI
import RealityKit
struct ContentView: View {
var body: some View {
Group {
if #available(iOS 18.0, *) {
RealityCameraView()
} else {
ARViewContainer()
}
}.ignoresSafeArea()
}
}
因為都要滿版,因此用 Group 不管是使用哪個 view 都能套用到 .ignoresSafeArea()
修飾器。
新增一個 RealityCameraView
,並輸入 RealityKit 框架
import SwiftUI
import RealityKit
@available(iOS 18.0, *)
struct RealityCameraView: View {
var body: some View {
RealityView { content in
}
.ignoresSafeArea()
}
}
還以為這樣就可以了,但結果手機只出現黑畫面,說好的 AR 實景呢!?
原來少了這行:content.camera = .spatialTracking
.spatialTracking
是 RealityView 的預設 AR 模式,可顯示相機畫面與世界追蹤功能。
加到 RealityView 中就可以看到跟剛剛 ARSCNView 相同的滿版相機畫面了。
體感覺得 RealityView 啟動的比 ARSCNView 還要慢一些,但總之開啟 app 後都要等他們啟動,一開始是畫面卡住,再來是隨著手機移動畫面慢慢一幀一幀的出現,最後才變成我們熟悉的相機鏡頭。之後可以規劃在完全啟動到順暢之間,能做點什麼 UI 墊擋。
今天半路殺出程咬金,終於真的完成了,顯示 AR 初始畫面,明天再見!
P.S. 我使用的 Xcode 版本為 Xcode 26 Beta 7