Как вызвать UITextField внутри SpriteKit? - PullRequest
0 голосов
/ 28 ноября 2018

Как говорится в вопросе, я пытаюсь вызвать UITextField внутри SpriteKit, чтобы принять пользовательский ввод для имени.Я просмотрел много постов здесь, но ни один из них, кажется, не относится к проблеме, с которой я сталкиваюсь.Первое, что я делаю, это объявляю 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 голосов
/ 28 ноября 2018

SKSKScene SpriteKit существует внутри SKView UIKit.т. е. вся ваша сцена Spritekit в основном является вспомогательным слоем для одного представления в вашем приложении.Если вы хотите сделать что-то на уровне UIKit, имеет больше смысла делать это на уровне вашего контроллера представления и возвращать ответственность обратно.Так, например, если вам нужен textField, вы можете настроить его в конструкторе интерфейсов и сделать его скрытым, а затем показывать его только тогда, когда ваша сцена запрашивает его.

Если вы не хотите делать это таким образом,вы по-прежнему можете получать доступ к своему представлению и добавлять подпредставления из своего SKScene (это плохой ООП, чтобы связываться с вашим родителем и изменять его, но ничто в UIKit не мешает вам сделать это).Скорее всего, проблема, с которой вы столкнулись, заключается в том, что системы координат в SpriteKit и UIKit различны и фактически перевернуты.Поэтому вы не можете просто использовать свои координаты SKScene для UIViews.Вам нужно конвертировать.SKView имеет семейство методов, которые будут выполнять математику за вас: SKView.convert (: to:) SkView.convert (: from:) .Обратите внимание, что это поможет вам достичь вашего SKView.Затем вам нужно конвертировать в ваши координаты viewController.view, используя методы конвертации UIKit.

Я думаю, что это гораздо менее запутанно, если вы оставите материал UIKit в слое UIKit и просто получите viewController и сцену, чтобы передать соответствующую информацию обратнои далее.

РЕДАКТИРОВАТЬ: вот пример

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
...