簡體   English   中英

ARKit:如何將 UIView 添加到 ARKit 場景?

[英]ARKit: How can I add a UIView to ARKit Scene?

我正在使用 ARKit 進行 AR 項目。

我想向 ARKit 場景添加一個 UIView。 當我點擊一個對象時,我想以該對象旁邊的“彈出窗口”形式獲取信息。 此信息位於 UIView 中。

是否可以將此 UIView 添加到 ARKit 場景中? 我將此 UIView 設置為場景,然后我該怎么辦? 我可以給它一個節點,然后將它添加到 ARKit 場景中嗎? 如果是這樣,它是如何工作的?

或者還有其他方法嗎?

謝謝!

編輯:我的 SecondViewController 的代碼

class InformationViewController: UIViewController {

    @IBOutlet weak var secondView: UIView!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.view = secondView
    }
}

編輯 2:firstViewController 中的代碼

guard let secondViewController = storyboard?.instantiateViewController(withIdentifier: "SecondViewController") as? SecondViewController else {
    print ("No secondController")
    return
}

let plane = SCNPlane(width: CGFloat(0.1), height: CGFloat(0.1))       
plane.firstMaterial?.diffuse.contents = secondViewController.view

let node = SCNNode(geometry: plane)

我只看到飛機的白色屏幕,而不是視圖。

實現這一目標的最簡單(盡管未記錄)方法是將視圖控制器支持的UIView設置為SCNPlane上材質的漫反射內容(或任何其他幾何體,但由於顯而易見的原因,它最適用於平面)。

let plane = SCNPlane()
plane.firstMaterial?.diffuse.contents = someViewController.view
let planeNode = SCNNode(geometry: plane)

您必須將視圖控制器保留在某處,否則它將被釋放並且平面將不可見。 僅使用沒有任何UIViewControllerUIView將引發錯誤。

關於它的最好的事情是它保留了所有手勢並且實際上就像一個簡單的視圖一樣工作。 例如,如果您使用UITableViewController的視圖,您將能夠在場景中直接滾動它。

我還沒有在 iOS 10 及更低版本上測試過它,但到目前為止它一直在 iOS 11 上運行。 適用於普通 SceneKit 場景和 ARKit。

我現在無法為您提供代碼,但這是如何做到的。

  1. 創建一個SCNPlane
  2. 使用您需要的所有元素創建您的UIView
  3. UIView創建圖像上下文。
  4. 將此圖像用作SCNPlane材料。

或者更容易使用標簽制作SKScene並將其添加為SCNPlane材料。

要在世界中的標簽中放置文本,請將其繪制到圖像中,然后將該圖像附加到SCNNode

例如:

let text = "Hello, Stack Overflow."
let font = UIFont(name: "Arial", size: CGFloat(size))
let width = 128
let height = 128

let fontAttrs: [NSAttributedStringKey: Any] = 
[NSAttributedStringKey.font: font as UIFont]

let stringSize = self.text.size(withAttributes: fontAttrs)
let rect = CGRect(x: CGFloat((width / 2.0) - (stringSize.width/2.0)),
                  y: CGFloat((height / 2.0) - (stringSize.height/2.0)),
                  width: CGFloat(stringSize.width),
                  height: CGFloat(stringSize.height))

let renderer = UIGraphicsImageRenderer(size: CGSize(width: CGFloat(width), height: CGFloat(height)))
let image = renderer.image { context in

    let color = UIColor.blue.withAlphaComponent(CGFloat(0.5))

    color.setFill()
    context.fill(rect)

    text.draw(with: rect, options: .usesLineFragmentOrigin, attributes: fontAttrs, context: nil)
}

let plane = SCNPlane(width: CGFloat(0.1), height: CGFloat(0.1))
plane.firstMaterial?.diffuse.contents = image

let node = SCNNode(geometry: plane)

編輯:我添加了這些行:

let color = UIColor.blue.withAlphaComponent(CGFloat(0.5))

color.setFill()
context.fill(rect)

這使您可以設置背景顏色和不透明度。 還有其他方法可以做到這一點 - 也可以讓您繪制復雜的形狀 - 但這是基本顏色最簡單的方法。

編輯 2:添加了對stringSizerect引用

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM