通过按钮更改 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 中,您将拥有以下内容: