私は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)
飛行機の白い画面しか表示されず、ビューは表示されません。
これを実現する最も簡単な(ただし文書化されていない)方法は、ViewControllerによってサポートされるUIView
をSCNPlane
(または実際には他のジオメトリ)上のマテリアルの拡散コンテンツとして設定することですが、これが最も効果的です。明らかな理由で飛行機を使用)。
let plane = SCNPlane()
plane.firstMaterial?.diffuse.contents = someViewController.view
let planeNode = SCNNode(geometry: plane)
ビューコントローラをどこかに永続化する必要があります。そうしないと、ビューコントローラが解放され、平面が表示されなくなります。 UIView
なしでUIViewController
だけを使用すると、エラーがスローされます。
それについての最もよいことは、それがすべてのジェスチャーを保持し、実際には単純なビューと同じように機能することです。たとえば、UITableViewController
のビューを使用すると、シーン内で右にスクロールできます。
IOS 10以下ではテストしていませんが、これまでのところiOS11で動作しています。プレーンなSceneKitシーンとARKitの両方で機能します。
現在コードを提供することはできませんが、これがその方法です。
SCNPlane
を作成します。UIView
を作成します。UIView
から画像コンテキストを作成します。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:stringSize
およびrect
への参照を追加