通过按钮更改 uikit 视图中的文本(swift 4)
change text in arkitview via button(swift4)
我的代码使用arkit。我想做的就是更改标签的文本。更改反映在 arkit 文本中。目前不是。无论 arkit 标签保留和默认,无论视图控制器上的标签上有什么,都不会改变。
import UIKit;import ARKit
class ViewController: UIViewController {
@IBOutlet var arkitView:ARSCNView!
@IBOutlet var outputImageView:UIImageView!
@IBOutlet var ffox: UILabel!
@IBOutlet var enterText: UITextField!
var textGeometry: SCNText!
//4. Create Our ARWorld Tracking Configuration
let configuration = ARWorldTrackingConfiguration()
//5. Create Our Session
let augmentedRealitySession = ARSession()
override func viewDidAppear(_ animated: Bool) {
arkitView.session.run(configuration)
//1. Create The Text
textGeometry = SCNText(string: ffox.text!, extrusionDepth: 1)
//2. Set It From The UILabel
textGeometry.string = ffox.text!
//3. Create A Material For The Text
let material = SCNMaterial()
material.diffuse.contents = UIColor.green
textGeometry.materials = [material]
//4. Create A Holder Node To Hold The Text
let node = SCNNode()
node.position = SCNVector3(x: 0, y: 0.02, z: -0.01)
node.scale = SCNVector3(x: 0.01, y: 0.01, z: 0.01)
node.geometry = textGeometry
arkitView.scene.rootNode.addChildNode(node)
arkitView.automaticallyUpdatesLighting = true
DispatchQueue.main.async {
self.textGeometry.string = self.ffox.text!
}
}
@IBAction func takeScreenshotAction() {
if let d = enterText.text
{
ffox.text = d
}}}
查看您的代码,您可能需要设置字体和字体大小,例如:
textGeometry.font = UIFont(name: "Helvatica", size: 3)
更改文本:
要更改 SCNText
的文本,您需要访问它的 string
属性。
将您 SCNText
声明为 var
高于您的 Class 定义,例如
let textGeometry: SCNText!
我个人会在 ViewDidLoad
中初始化它。
然后要更改它,您只需调用:
textGeometry.string = "I Have Changed The String"
所以在你的例子中假设你的 SCNText 被称为 textGeometry
你可以这样做:
textGeometry.string = ffox.text
创建 SCNText 几何图形的示例:
class Text: SCNNode{
var textGeometry: SCNText!
/// Creates An SCNText Geometry
///
/// - Parameters:
/// - text: String (The Text To Be Displayed)
/// - depth: Optional CGFloat (Defaults To 1)
/// - font: UIFont
/// - textSize: Optional CGFloat (Defaults To 3)
/// - colour: UIColor
init(text: String, depth: CGFloat = 1, font: String = "Helvatica", textSize: CGFloat = 3, colour: UIColor) {
super.init()
//1. Create The Text Geometry With String & Depth Parameters
textGeometry = SCNText(string: text , extrusionDepth: depth)
//2. Set The Font With Our Set Font & Size
textGeometry.font = UIFont(name: font, size: textSize)
//3. Set The Flatness To Zero (This Makes The Text Look Smoother)
textGeometry.flatness = 0
//4. Set The Colour Of The Text
textGeometry.firstMaterial?.diffuse.contents = colour
//5. Set The Text's Material
self.geometry = textGeometry
//6. Scale The Text So We Can Actually See It!
self.scale = SCNVector3(0.01, 0.01 , 0.01)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
在您的场景中使用此 Class:
//1. Create An SCNText With A White Colour
let nodeToAdd = Text(text: "Hello AR", colour: .white)
//2. Add The Text To The Scene
augmentedRealityView.scene.rootNode.addChildNode(nodeToAdd)
//3. Set The Text's Position Center On The Screen & 1.5m In Front Of The Camera
nodeToAdd.position = SCNVector3(0, 0, -1.5)
希望这对您有所帮助...
更新:
上面的代码工作得很好,但是因为你在实现它时遇到了问题,下面是你的代码应该看起来的样子:
class Example: UIViewController {
//1. Create A Reference To Our ARSCNView In Our Storyboard Which Displays The Camera Feed
@IBOutlet weak var augmentedRealityView: ARSCNView!
//2. Create A Label To Display Text
@IBOutlet weak var ffox: UILabel!
//3. Create The Text Gemoetry
var textGeometry: SCNText!
//4. Create Our ARWorld Tracking Configuration
let configuration = ARWorldTrackingConfiguration()
//5. Create Our Session
let augmentedRealitySession = ARSession()
//--------------------
//MARK: View LifeCycle
//--------------------
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
augmentedRealityView.session.run(configuration)
//1. Create The Text
textGeometry = SCNText(string: ffox.text!, extrusionDepth: 1)
//2. Set It From The UILabel
textGeometry.string = ffox.text!
//3. Create A Material For The Text
let material = SCNMaterial()
material.diffuse.contents = UIColor.green
textGeometry.materials = [material]
//4. Create A Holder Node To Hold The Text
let node = SCNNode()
node.position = SCNVector3(x: 0, y: 0.02, z: -0.01)
node.scale = SCNVector3(x: 0.01, y: 0.01, z: 0.01)
node.geometry = textGeometry
augmentedRealityView.scene.rootNode.addChildNode(node)
augmentedRealityView.automaticallyUpdatesLighting = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
我想您的应用程序崩溃的原因可能是您没有在 Interface Builder 中设置 ffox text
并如下图所示进行连接:
还要记住UILabel
必须包含文字!
最终更新:
由于 Sam 仍然无法让它工作,我正在编写一个更 in-depth 的示例,它执行以下操作:
(1) UILabel
中的文本将在加载时显示在 SCNTextGeometry
中。
(2) 您可以通过按三个按钮之一来更改 SCNTextGeometry
的字符串,
(3) 您可以使用 UITextField
输入更改 SCNTextGeometry
的字符串。
所有这些都已经过全面测试,并且与我的其他示例一样有效。
您可以在此处下载完整示例:Sample Project
当然还有`ViewController' Class:
import UIKit
import ARKit
//--------------------
//MARK: TextNode Class
//--------------------
class TextNode: SCNNode{
var textGeometry: SCNText!
/// Creates An SCNText Geometry
///
/// - Parameters:
/// - text: String (The Text To Be Displayed)
/// - depth: Optional CGFloat (Defaults To 1)
/// - font: UIFont
/// - textSize: Optional CGFloat (Defaults To 3)
/// - colour: UIColor
init(text: String, depth: CGFloat = 1, font: String = "Helvatica", textSize: CGFloat = 3, colour: UIColor) {
super.init()
//1. Create The Text Geometry With String & Depth Parameters
textGeometry = SCNText(string: text , extrusionDepth: depth)
//2. Set The Font With Our Set Font & Size
textGeometry.font = UIFont(name: font, size: textSize)
//3. Set The Flatness To Zero (This Makes The Text Look Smoother)
textGeometry.flatness = 0
//4. Set The Colour Of The Text
textGeometry.firstMaterial?.diffuse.contents = colour
//5. Set The Text's Material
self.geometry = textGeometry
//6. Scale The Text So We Can Actually See It!
self.scale = SCNVector3(0.01, 0.01 , 0.01)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
//--------------------------
//MARK: UITextFieldDelegate
//--------------------------
extension ViewController: UITextFieldDelegate{
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
print("Current Text = \(textField.text!)")
DispatchQueue.main.async {
self.textNode.textGeometry.string = textField.text!
}
return true
}
}
class ViewController: UIViewController {
//1. Create A Reference To Our ARSCNView In Our Storyboard Which Displays The Camera Feed
@IBOutlet weak var augmentedRealityView: ARSCNView!
//2. Create A Reference To Our SCNNode
var textNode: TextNode!
//2. Create A Label To Display Text
@IBOutlet weak var ffox: UILabel!
//3. Create UITextField So Text Can Be Changed Dynamically
@IBOutlet weak var textChangerField: UITextField!
//3. Create Our ARWorld Tracking Configuration
let configuration = ARWorldTrackingConfiguration()
//3. Create Our Session
let augmentedRealitySession = ARSession()
//--------------------
//MARK: View LifeCycle
//--------------------
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
augmentedRealityView.session.run(configuration)
//1. Create An SCNText With A White Colour & With The Label's Text
textNode = TextNode(text: ffox.text!, colour: .white)
//2. Add The Text To The Scene
augmentedRealityView.scene.rootNode.addChildNode(textNode)
//3. Set The Text's Position Center On The Screen & 1.5m In Front Of The Camera
textNode.position = SCNVector3(0, 0, -1.5)
//4. Set The Lighting
augmentedRealityView.automaticallyUpdatesLighting = true
//5. Assign The Delegate To The TextChangerField
textChangerField.delegate = self
}
/// Changes The Text In The Button At The Bottom Of The Screen
///
/// - Parameter sender: UIButton
@IBAction func changeText(_ sender: UIButton){
guard let textToDisplay = sender.titleLabel?.text else { return }
DispatchQueue.main.async {
self.textNode.textGeometry.string = textToDisplay
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
在 Interface Builder 中,您将拥有以下内容:
我的代码使用arkit。我想做的就是更改标签的文本。更改反映在 arkit 文本中。目前不是。无论 arkit 标签保留和默认,无论视图控制器上的标签上有什么,都不会改变。
import UIKit;import ARKit
class ViewController: UIViewController {
@IBOutlet var arkitView:ARSCNView!
@IBOutlet var outputImageView:UIImageView!
@IBOutlet var ffox: UILabel!
@IBOutlet var enterText: UITextField!
var textGeometry: SCNText!
//4. Create Our ARWorld Tracking Configuration
let configuration = ARWorldTrackingConfiguration()
//5. Create Our Session
let augmentedRealitySession = ARSession()
override func viewDidAppear(_ animated: Bool) {
arkitView.session.run(configuration)
//1. Create The Text
textGeometry = SCNText(string: ffox.text!, extrusionDepth: 1)
//2. Set It From The UILabel
textGeometry.string = ffox.text!
//3. Create A Material For The Text
let material = SCNMaterial()
material.diffuse.contents = UIColor.green
textGeometry.materials = [material]
//4. Create A Holder Node To Hold The Text
let node = SCNNode()
node.position = SCNVector3(x: 0, y: 0.02, z: -0.01)
node.scale = SCNVector3(x: 0.01, y: 0.01, z: 0.01)
node.geometry = textGeometry
arkitView.scene.rootNode.addChildNode(node)
arkitView.automaticallyUpdatesLighting = true
DispatchQueue.main.async {
self.textGeometry.string = self.ffox.text!
}
}
@IBAction func takeScreenshotAction() {
if let d = enterText.text
{
ffox.text = d
}}}
查看您的代码,您可能需要设置字体和字体大小,例如:
textGeometry.font = UIFont(name: "Helvatica", size: 3)
更改文本:
要更改 SCNText
的文本,您需要访问它的 string
属性。
将您 SCNText
声明为 var
高于您的 Class 定义,例如
let textGeometry: SCNText!
我个人会在 ViewDidLoad
中初始化它。
然后要更改它,您只需调用:
textGeometry.string = "I Have Changed The String"
所以在你的例子中假设你的 SCNText 被称为 textGeometry
你可以这样做:
textGeometry.string = ffox.text
创建 SCNText 几何图形的示例:
class Text: SCNNode{
var textGeometry: SCNText!
/// Creates An SCNText Geometry
///
/// - Parameters:
/// - text: String (The Text To Be Displayed)
/// - depth: Optional CGFloat (Defaults To 1)
/// - font: UIFont
/// - textSize: Optional CGFloat (Defaults To 3)
/// - colour: UIColor
init(text: String, depth: CGFloat = 1, font: String = "Helvatica", textSize: CGFloat = 3, colour: UIColor) {
super.init()
//1. Create The Text Geometry With String & Depth Parameters
textGeometry = SCNText(string: text , extrusionDepth: depth)
//2. Set The Font With Our Set Font & Size
textGeometry.font = UIFont(name: font, size: textSize)
//3. Set The Flatness To Zero (This Makes The Text Look Smoother)
textGeometry.flatness = 0
//4. Set The Colour Of The Text
textGeometry.firstMaterial?.diffuse.contents = colour
//5. Set The Text's Material
self.geometry = textGeometry
//6. Scale The Text So We Can Actually See It!
self.scale = SCNVector3(0.01, 0.01 , 0.01)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
在您的场景中使用此 Class:
//1. Create An SCNText With A White Colour
let nodeToAdd = Text(text: "Hello AR", colour: .white)
//2. Add The Text To The Scene
augmentedRealityView.scene.rootNode.addChildNode(nodeToAdd)
//3. Set The Text's Position Center On The Screen & 1.5m In Front Of The Camera
nodeToAdd.position = SCNVector3(0, 0, -1.5)
希望这对您有所帮助...
更新:
上面的代码工作得很好,但是因为你在实现它时遇到了问题,下面是你的代码应该看起来的样子:
class Example: UIViewController {
//1. Create A Reference To Our ARSCNView In Our Storyboard Which Displays The Camera Feed
@IBOutlet weak var augmentedRealityView: ARSCNView!
//2. Create A Label To Display Text
@IBOutlet weak var ffox: UILabel!
//3. Create The Text Gemoetry
var textGeometry: SCNText!
//4. Create Our ARWorld Tracking Configuration
let configuration = ARWorldTrackingConfiguration()
//5. Create Our Session
let augmentedRealitySession = ARSession()
//--------------------
//MARK: View LifeCycle
//--------------------
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
augmentedRealityView.session.run(configuration)
//1. Create The Text
textGeometry = SCNText(string: ffox.text!, extrusionDepth: 1)
//2. Set It From The UILabel
textGeometry.string = ffox.text!
//3. Create A Material For The Text
let material = SCNMaterial()
material.diffuse.contents = UIColor.green
textGeometry.materials = [material]
//4. Create A Holder Node To Hold The Text
let node = SCNNode()
node.position = SCNVector3(x: 0, y: 0.02, z: -0.01)
node.scale = SCNVector3(x: 0.01, y: 0.01, z: 0.01)
node.geometry = textGeometry
augmentedRealityView.scene.rootNode.addChildNode(node)
augmentedRealityView.automaticallyUpdatesLighting = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
我想您的应用程序崩溃的原因可能是您没有在 Interface Builder 中设置 ffox text
并如下图所示进行连接:
还要记住UILabel
必须包含文字!
最终更新:
由于 Sam 仍然无法让它工作,我正在编写一个更 in-depth 的示例,它执行以下操作:
(1) UILabel
中的文本将在加载时显示在 SCNTextGeometry
中。
(2) 您可以通过按三个按钮之一来更改 SCNTextGeometry
的字符串,
(3) 您可以使用 UITextField
输入更改 SCNTextGeometry
的字符串。
所有这些都已经过全面测试,并且与我的其他示例一样有效。
您可以在此处下载完整示例:Sample Project
当然还有`ViewController' Class:
import UIKit
import ARKit
//--------------------
//MARK: TextNode Class
//--------------------
class TextNode: SCNNode{
var textGeometry: SCNText!
/// Creates An SCNText Geometry
///
/// - Parameters:
/// - text: String (The Text To Be Displayed)
/// - depth: Optional CGFloat (Defaults To 1)
/// - font: UIFont
/// - textSize: Optional CGFloat (Defaults To 3)
/// - colour: UIColor
init(text: String, depth: CGFloat = 1, font: String = "Helvatica", textSize: CGFloat = 3, colour: UIColor) {
super.init()
//1. Create The Text Geometry With String & Depth Parameters
textGeometry = SCNText(string: text , extrusionDepth: depth)
//2. Set The Font With Our Set Font & Size
textGeometry.font = UIFont(name: font, size: textSize)
//3. Set The Flatness To Zero (This Makes The Text Look Smoother)
textGeometry.flatness = 0
//4. Set The Colour Of The Text
textGeometry.firstMaterial?.diffuse.contents = colour
//5. Set The Text's Material
self.geometry = textGeometry
//6. Scale The Text So We Can Actually See It!
self.scale = SCNVector3(0.01, 0.01 , 0.01)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
//--------------------------
//MARK: UITextFieldDelegate
//--------------------------
extension ViewController: UITextFieldDelegate{
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
print("Current Text = \(textField.text!)")
DispatchQueue.main.async {
self.textNode.textGeometry.string = textField.text!
}
return true
}
}
class ViewController: UIViewController {
//1. Create A Reference To Our ARSCNView In Our Storyboard Which Displays The Camera Feed
@IBOutlet weak var augmentedRealityView: ARSCNView!
//2. Create A Reference To Our SCNNode
var textNode: TextNode!
//2. Create A Label To Display Text
@IBOutlet weak var ffox: UILabel!
//3. Create UITextField So Text Can Be Changed Dynamically
@IBOutlet weak var textChangerField: UITextField!
//3. Create Our ARWorld Tracking Configuration
let configuration = ARWorldTrackingConfiguration()
//3. Create Our Session
let augmentedRealitySession = ARSession()
//--------------------
//MARK: View LifeCycle
//--------------------
override func viewDidLoad() {
super.viewDidLoad()
}
override func viewDidAppear(_ animated: Bool) {
augmentedRealityView.session.run(configuration)
//1. Create An SCNText With A White Colour & With The Label's Text
textNode = TextNode(text: ffox.text!, colour: .white)
//2. Add The Text To The Scene
augmentedRealityView.scene.rootNode.addChildNode(textNode)
//3. Set The Text's Position Center On The Screen & 1.5m In Front Of The Camera
textNode.position = SCNVector3(0, 0, -1.5)
//4. Set The Lighting
augmentedRealityView.automaticallyUpdatesLighting = true
//5. Assign The Delegate To The TextChangerField
textChangerField.delegate = self
}
/// Changes The Text In The Button At The Bottom Of The Screen
///
/// - Parameter sender: UIButton
@IBAction func changeText(_ sender: UIButton){
guard let textToDisplay = sender.titleLabel?.text else { return }
DispatchQueue.main.async {
self.textNode.textGeometry.string = textToDisplay
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
在 Interface Builder 中,您将拥有以下内容: