UITextField not showing when added as subview

Hi. I'm pretty new to Swift and I'm having some trouble displaying UITextField in SpriteKit. Init() in SceneMenu will not display the UITextField, while using function showTextField() with touchesBegan() works. How can I display UITextField without the user clicking the button Show TextField?

GameViewController.swift:


class GameViewController: UIViewController {
   
  override func viewDidLoad() {
     
    let scene = SceneMenu(size: view.frame.size)
    scene.scaleMode = .aspectFill
    scene.backgroundColor = .white
     
    let view = view as! SKView
    view.presentScene(scene)
     
  }
   
}

SceneMenu.swift:


class SceneMenu: SKScene {
   
  override init(size: CGSize) {
     
    super.init(size: size)
     
    let btnAlert = SKLabelNode(text: "Show TextField")
    btnAlert.name = "btn_text"
    btnAlert.fontSize = 20
    btnAlert.fontColor = SKColor.blue
    btnAlert.fontName = "Avenir"
    btnAlert.position = CGPoint(x: size.width / 2, y: size.height / 2)
    addChild(btnAlert)

let textFieldFrame = CGRect(origin: CGPoint(x: 100, y: 300), size: CGSize(width: 200, height: 30))
    let textField = UITextField(frame: textFieldFrame)
    textField.backgroundColor = SKColor.blue
    textField.placeholder = "Type name"
   
    view?.addSubview(textField)
     
  }
   
  required init?(coder aDecoder: NSCoder) {
     
    fatalError("init(coder:) has not been implemented")
     
  }
   
  func showTextField() {
     
    let textFieldFrame = CGRect(origin: CGPoint(x: 100, y: 100), size: CGSize(width: 200, height: 30))
    let textField = UITextField(frame: textFieldFrame)
    textField.backgroundColor = SKColor.blue
    textField.placeholder = "Type name"
   
    view?.addSubview(textField)
     
  }
   
  override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
     
    if let touch = touches.first {
       
      let location = touch.location(in: self)
      let action = atPoint(location)
       
      if action.name == "btn_text" {
         
        showTextField()
         
      }
       
    }
     
  }
   
}

The size of view during viewDidLoad is not necessarily correct for final layout, in general we recommend you either use auto-layout or override UIView.layoutSubviews() or an analog like UIViewController.viewDidLayoutSubviews() or UIViewController.viewWillLayoutSubviews() to ensure that the subviews you create are laid out properly (this also applies to views you subclass – the size passed to initializers is not expected to be final, especially for larger more complex views like a SKScene subclass. Finally you should keep aware of coordinate system differences – UIView.frame is a view's extent in its parent's coordinate system and may not be correct for layout of subviews (setting a non-identity transform on a view will change its frame for example). You should always use bounds when referring to a view's internal coordinate space, such as when positioning and sizing subviews.

Finally your showTextField method always creates a new UITextField and adds it, which may be causing other issues (minimally, causing you to pile up UITextFields). Depending on specifically what is going on, you may either be positioning the UITextField you are creating offscreen, or you may be conflicting with positioning that SKScene itself is doing – I'm not familiar with that class enough to know how adding subviews affects its behavior.

I repost, as Forum seems to deletes some post randomly…

You should not do it in init((size:), but in another func later.

This works (but creates 2 textFields, which you probably don't need: so remove showTextField()

class SceneMenu: SKScene {
    
    var textField: UITextField!
    
    override func didMove(to view: SKView) {

        let textFieldFrame = CGRect(origin: CGPoint(x: 50, y: 50), size: CGSize(width: 200, height: 30))
        textField = UITextField(frame: textFieldFrame)
        textField.backgroundColor = SKColor.systemYellow
        textField.placeholder = "Type name"
        view.addSubview(textField)
    }
    
    override init(size: CGSize) {
        
        super.init(size: size)
        
        let btnAlert = SKLabelNode(text: "Show TextField")
        btnAlert.name = "btn_text"
        btnAlert.fontSize = 20
        btnAlert.fontColor = SKColor.systemGreen
        btnAlert.fontName = "Avenir"
        btnAlert.position = CGPoint(x: size.width / 2, y: size.height / 2)
        addChild(btnAlert)
        
//        let textFieldFrame = CGRect(origin: CGPoint(x: 50, y: 50), size: CGSize(width: 200, height: 30))
//        textField = UITextField(frame: textFieldFrame)
//        textField.backgroundColor = SKColor.systemYellow
//        textField.placeholder = "Type name"
//
//        view?.addSubview(textField)
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
        
    }
    
    func showTextField() {
        
        let textFieldFrame = CGRect(origin: CGPoint(x: 50, y: 100), size: CGSize(width: 200, height: 30))
        let textField = UITextField(frame: textFieldFrame)
        textField.backgroundColor = SKColor.systemRed
        textField.placeholder = "Type name"
        
        view?.addSubview(textField)
        
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        
        if let touch = touches.first {
            let location = touch.location(in: self)
            let action = atPoint(location)
            
            if action.name == "btn_text" {
                showTextField()
            }
        }
    }
    
}
UITextField not showing when added as subview
 
 
Q