如何在SpriteKit内调用UITextField?

时间:2018-11-27 22:06:00

标签: ios swift sprite-kit

正如问题所述,我试图在SpriteKit内调用UITextField接受用户输入的名称。我看过这里的许多帖子,但似乎都不适用于我所面临的问题。我要做的第一件事是将UITextField声明为类变量,因此稍后可以通过执行以下操作将其从单独的函数中从视图中删除:

let nameEntry = UITextField(frame: CGRect(origin: CGPoint(x: 800, y: 875), size: CGSize(width: 600, height: 200)))

然后我通过声明添加UITextField:

self.view?.addSubview(nameEntry)

但是,文本框未显示在我的场景中。我已经在层次结构视图中对其进行了研究,但它根本不存在。我对使用SceneKit缺乏经验,所以很好奇我做错了什么。预先感谢任何尝试提供帮助的人!

以更好地了解我的工作方式:

class Tutorial : SKScene{
let nameEntry = UITextField(frame: CGRect(origin: CGPoint(x: 800, y: 875), size: CGSize(width: 600, height: 200)))

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
//insert many lines of code here
self.view?.addSubview(nameEntry)
  }
}

编辑:这是到目前为止的所有代码。

class Tutorial : SKScene{
var chatBoxInt : Int = 0
let chatBoxLabel : SKLabelNode = SKLabelNode(text: "")
let arrow = SKSpriteNode(imageNamed: "Arrow")
let HappinessIcon = SKSpriteNode(imageNamed: "Happiness Icon")
let IntelligenceIcon = SKSpriteNode(imageNamed: "IntelligenceIcon")
let HealthIcon = SKSpriteNode(imageNamed: "HealthIcon")
let chatBox = SKSpriteNode(imageNamed: "ChatBox")
let maleButtonBackground = SKSpriteNode(imageNamed: "ButtonBackground")
let femaleButtonBackground = SKSpriteNode(imageNamed: "ButtonBackground")
let selectedGenderButtonBackground = SKSpriteNode(imageNamed: "ButtonBackgroundSelected")
let femaleLabel = SKLabelNode(text: "Female")
let maleLabel = SKLabelNode(text: "Male")
let genderLabel = SKLabelNode(text: "Gender:")
let nameLabel = SKLabelNode(text: "Name:")
let nameEntry = UITextField(frame: CGRect(origin: CGPoint(x: 800, y: 875), size: CGSize(width: 600, height: 200)))
enum genders {
    case Male
    case Female
}
var genderSelected : genders = .Male


override func didMove(to view: SKView) {
    let background = SKSpriteNode(imageNamed: "Background")
    background.size = CGSize(width: self.size.width, height: self.size.height)
    background.position = CGPoint(x: self.size.width/2, y: self.size.height/2)
    background.zPosition = 0
    scene?.addChild(background)
    Timer.scheduledTimer(timeInterval: 1.5, target: self, selector: #selector(beginTutorial), userInfo: nil, repeats: false)
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch : AnyObject in touches{
        let pointOfTouch = touch.location(in: self)
        if(maleButtonBackground.contains(pointOfTouch) || femaleButtonBackground.contains(pointOfTouch)){
            if(maleButtonBackground.contains(pointOfTouch)){
                swapGenderButton(ImageToSwap: maleButtonBackground)
                genderSelected = .Male
            }
            if(femaleButtonBackground.contains(pointOfTouch)){
                swapGenderButton(ImageToSwap: femaleButtonBackground)
                genderSelected = .Female
            }
        }else{
            chatBoxInt += 1
            let fadeInAnimation = SKAction.fadeIn(withDuration: 1)
            let fadeOutAnimation = SKAction.fadeOut(withDuration: 1)
            let removeAction = SKAction.removeFromParent()
            let fadeOutSequence = SKAction.sequence([fadeOutAnimation, removeAction])
            switch chatBoxInt {
            case 1:
                ChangeText(LabelText: "Best Life is the place for you to make the life you've always dreamed of!")
            case 2:
                ChangeText(LabelText: "In Best Life you can be who you want to be, do what you want to do... as long as you don't die.")
            case 3:
                ChangeText(LabelText: "The goal of Best Life is simple, make the best life possible for yourself before your time runs out.")
            case 4:
                ChangeText(LabelText: "Let's go over some of the basics of best life:")
            case 5:
                ChangeText(LabelText: "When you get into your new life, you'll have a HUD at the bottom of your screen at all times. This HUD will act as your guide as you go throughout Best Life. Let's get familiar with the icons and what they mean.")
            case 6:
                ChangeText(LabelText: "This is your happiness indicator, it will show you how much you are enjoying your life, try and keep this high at all times... too little happiness can result in your alter ego committing suicide.")
                HappinessIcon.position = CGPoint(x: self.size.width/2, y: (self.size.height/2) - 100)
                HappinessIcon.size = CGSize(width: 200, height: 200)
                HappinessIcon.zPosition = 2
                HappinessIcon.alpha = 0
                self.addChild(HappinessIcon)
                HappinessIcon.run(fadeInAnimation)
            case 7:
                HappinessIcon.run(fadeOutSequence)
                ChangeText(LabelText: "This is your intelligence indicator... it shows... well.... intelligence... what else would it do...? Too little of this and you may not get good jobs; leading to lower income.")
                IntelligenceIcon.position = CGPoint(x: self.size.width/2, y: (self.size.height/2) - 100)
                IntelligenceIcon.size = CGSize(width: 200, height: 200)
                IntelligenceIcon.zPosition = 2
                IntelligenceIcon.alpha = 0
                self.addChild(IntelligenceIcon)
                IntelligenceIcon.run(fadeInAnimation)
            case 8:
                IntelligenceIcon.run(fadeOutSequence)
                ChangeText(LabelText: "This is your health icon. It shows your current overall health level. If this gets too low it can contribute to life threatning illnesses which can ultimately lead to your demise.")
                HealthIcon.position = CGPoint(x: self.size.width/2, y: (self.size.height/2) - 100)
                HealthIcon.size = CGSize(width: 200, height: 200)
                HealthIcon.zPosition = 2
                HealthIcon.alpha = 0
                self.addChild(HealthIcon)
                HealthIcon.run(fadeInAnimation)
            case 9:
                HealthIcon.run(fadeOutSequence)
                ChangeText(LabelText: "The last thing that you need to know is that one day in your world will pass one year in your alter ego's life. Make sure you are making the most out of every day to make the best life possible for your alter ego!")
            case 10:
                ChangeText(LabelText: "Alright, that pretty much sums it up. The world is yours for the taking, go seize it! Have fun in your new Best Life!")
            case 11:
                ChangeText(LabelText: "First, we'll need to we'll need to set up your new alter ego. Some of these options can only be accessed by purchasing them, but since this is your first go around I'll cover this one for you.")
                chatBoxLabel.run(SKAction.moveTo(y: 1750, duration: 1))
                let changeSize = SKAction.scale(to: CGSize(width: 800, height: 1600), duration: 1)
                chatBox.run(changeSize)
                arrow.run(fadeOutSequence)
                genderLabel.position = CGPoint(x: 500, y: 1300)
                genderLabel.fontColor = .black
                genderLabel.zPosition = 2
                genderLabel.fontSize = 45
                genderLabel.alpha = 0
                self.addChild(genderLabel)
                genderLabel.run(fadeInAnimation)
                maleButtonBackground.position = CGPoint(x: 575, y: 1175)
                maleButtonBackground.zPosition = 2
                maleButtonBackground.setScale(0.3)
                maleButtonBackground.alpha = 0
                self.addChild(maleButtonBackground)
                maleButtonBackground.run(fadeInAnimation)
                femaleButtonBackground.position = CGPoint(x: 955, y: 1175)
                femaleButtonBackground.zPosition = 2
                femaleButtonBackground.setScale(0.3)
                femaleButtonBackground.alpha = 0
                self.addChild(femaleButtonBackground)
                femaleButtonBackground.run(fadeInAnimation)
                maleLabel.fontSize = 45
                maleLabel.fontColor = .white
                maleLabel.zPosition = 4
                maleLabel.alpha = 0
                maleLabel.position = CGPoint(x: 575, y: 1162)
                self.addChild(maleLabel)
                maleLabel.run(fadeInAnimation)
                femaleLabel.fontSize = 45
                femaleLabel.fontColor = .white
                femaleLabel.zPosition = 4
                femaleLabel.alpha = 0
                femaleLabel.position = CGPoint(x: 955, y: 1162)
                self.addChild(femaleLabel)
                femaleLabel.run(fadeInAnimation)
                nameLabel.position = CGPoint(x: 500, y: 1000)
                nameLabel.fontSize = 45
                nameLabel.fontColor = .black
                nameLabel.alpha = 0
                nameLabel.zPosition = 3
                self.addChild(nameLabel)
                nameLabel.run(fadeInAnimation)
                nameEntry.backgroundColor = .white
                self.view?.addSubview(nameEntry)

                default:
                return
            }
        }
    }

}

1 个答案:

答案 0 :(得分:1)

SpriteKit的SKSKScene存在于UIKit的SKView内部。也就是说,整个Spritekit场景基本上是应用程序中单个视图的支持层。如果要在UIKit层中执行操作,则更有意义的是在视图控制器级别执行这些操作并将职责委派回去。因此,例如,如果您想要一个textField,则可以在界面构建器中对其进行设置并将其隐藏,然后仅在场景请求时显示它。

如果您不想这样做,您仍然可以在执行操作时进入视图并从SKScene添加子视图(它糟糕的OOP可以扩展并更改您的父级,但是UIKit中没有任何功能)阻止您执行此操作)。您遇到的最可能的问题是SpriteKit和UIKit中的坐标系不同,并且实际上是颠倒的。因此,您不能仅将SKScene坐标用于UIViews。您需要转换。 SKView有一系列可以为您进行数学计算的方法:SKView.convert(:to:) SkView.convert( :from:)。请注意,这只会使您到达SKView。然后,您需要使用UIKit的convert方法转换为viewController.view坐标。

我认为,如果您将UIKit内容留在UIKit层中,而只是让viewController和scene来回传递相关信息,那么它就不会那么混乱了。

编辑:这是一个示例

import PlaygroundSupport
import SpriteKit

class GameScene: SKScene {

    private lazy var textField: UITextField = {
        let textField = UITextField()
        textField.frame.size = CGSize(width: 100, height: 30)
        textField.backgroundColor = .cyan
        return textField
    }()

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        guard let view = view,
              let point = touches.first?.location(in: self) else {
            return
        }
        if textField.superview != nil {
            textField.removeFromSuperview()
        }
        textField.center = view.convert(point, from: self)
        view.addSubview(textField)
        textField.becomeFirstResponder()
    }  
}

let sceneView = SKView(frame: CGRect(x:0 , y:0, width: 640, height: 480))
if let scene = GameScene(fileNamed: "GameScene") {
    scene.scaleMode = .aspectFill
    sceneView.presentScene(scene)
}

PlaygroundSupport.PlaygroundPage.current.liveView = sceneView