web-dev-qa-db-ja.com

ARKit:UIViewをARKitシーンに追加するにはどうすればよいですか?

私はARKitを使ったARプロジェクトに取り組んでいます。

UIViewをARKitシーンに追加したい。オブジェクトをタップすると、オブジェクトの横にある「ポップアップ」として情報を取得したいと思います。この情報は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)

飛行機の白い画面しか表示されず、ビューは表示されません。

9
Informatics

これを実現する最も簡単な(ただし文書化されていない)方法は、ViewControllerによってサポートされるUIViewSCNPlane(または実際には他のジオメトリ)上のマテリアルの拡散コンテンツとして設定することですが、これが最も効果的です。明らかな理由で飛行機を使用)。

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

ビューコントローラをどこかに永続化する必要があります。そうしないと、ビューコントローラが解放され、平面が表示されなくなります。 UIViewなしでUIViewControllerだけを使用すると、エラーがスローされます。

それについての最もよいことは、それがすべてのジェスチャーを保持し、実際には単純なビューと同じように機能することです。たとえば、UITableViewControllerのビューを使用すると、シーン内で右にスクロールできます。

IOS 10以下ではテストしていませんが、これまでのところiOS11で動作しています。プレーンなSceneKitシーンとARKitの両方で機能します。

16

現在コードを提供することはできませんが、これがその方法です。

  1. SCNPlaneを作成します。
  2. 必要なすべての要素を使用してUIViewを作成します。
  3. UIViewから画像コンテキストを作成します。
  4. この画像をSCNPlaneの素材として使用してください。

または、ラベルを使用してSKSceneを作成し、それをSCNPlaneのマテリアルとして追加する方が簡単です。

2
Alok Subedi

ワールド内のラベルにテキストを配置するには、テキストを画像に描画してから、その画像を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:stringSizeおよびrectへの参照を追加

1
Jordan