Я использую SpriteKit, чтобы представить несколько ящиков (SKShapeNodes) с текстами внутри, например:
Затем я поворачиваю свое устройство, ожидая, что Ящики будут сохранять свое исходное положение независимо от ориентации, но получите это вместо:
Может ли кто-нибудь помочь мне найти преступника?
Это мой код:
import SpriteKit
import GameplayKit
struct TextMessage: Equatable
{
var messageText : SKLabelNode?
var messageBox : SKShapeNode?
}
class GameScene: SKScene {
var background : SKSpriteNode!
private var label : SKLabelNode?
private var spinnyNode : SKShapeNode?
var listOfTextMessages = [TextMessage]()
var number = 1
override func didMove(to view: SKView)
{
background = SKSpriteNode()
background.color = .green
addChild(background)
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
createTextMessageBox(text:"\(number)\(number)\(number)")
number += 1
}
func createTextMessageBox(text:String)
{
var textboxWidth : CGFloat = 500
if UIDevice.current.orientation.isLandscape { textboxWidth = 800 }
else { textboxWidth = 500 }
// Create the text message label
let notificationText = SKLabelNode(fontNamed: "AppleSDGothicNeo-Regular")
notificationText.name = "message_text"
notificationText.text = text
notificationText.fontSize = 45
notificationText.fontColor = SKColor.white
notificationText.alpha = 0
notificationText.numberOfLines = 0
notificationText.horizontalAlignmentMode = .left
notificationText.verticalAlignmentMode = .center
notificationText.preferredMaxLayoutWidth = textboxWidth-50
// Height of the textbox depends on the size of the text
let textboxHeight = notificationText.frame.height + 50
// Notification textbox that contains the text
let rightEdgeX = self.convert(CGPoint(x: self.frame.maxX, y: 0), to: background).x
let bottomEdgeY = self.convert(CGPoint(x: 0, y: self.frame.minY), to: background).y
let boxPositionX = rightEdgeX-50-textboxWidth
let boxPositionY : CGFloat = bottomEdgeY+100
// Create the Notification Textbox
let notificationNode = SKShapeNode(rect: CGRect(x: boxPositionX, y: boxPositionY, width: textboxWidth, height: textboxHeight),cornerRadius: 20)
notificationNode.name = "message_box"
notificationNode.fillColor = UIColor(red: 120/255, green: 0/255, blue: 0/255, alpha: 0.8)
notificationNode.strokeColor = UIColor(red: 128/255, green: 0/255, blue: 0/255, alpha: 1)
notificationNode.lineWidth = 2
notificationNode.alpha = 0
notificationNode.zPosition = 1
// Position text in the middle of the texbox
notificationText.position = CGPoint(x: notificationNode.frame.minX+25, y: notificationNode.frame.maxY-textboxHeight/2)
// Add nodes to the scene
background.addChild(notificationNode)
notificationNode.addChild(notificationText)
// Add to the list of text messages
let currentMessage = TextMessage(messageText: notificationText, messageBox: notificationNode)
listOfTextMessages.insert(currentMessage, at: 0)
// The first message is shown at the bottom, whereas the older messages are moved on top of it.
for (index,textBox) in listOfTextMessages.enumerated()
{
// The latest message
if index == 0
{
let actionBoxFadeIn = SKAction.fadeAlpha(to: 0.8, duration: 0.2)
let actionTextFadeIn = SKAction.run { textBox.messageText!.run(SKAction.fadeIn(withDuration: 0.2)) }
let actionMoveGroup = SKAction.group([actionBoxFadeIn,actionTextFadeIn])
textBox.messageBox!.run(actionMoveGroup)
}
else
{
textBox.messageBox!.position.y += listOfTextMessages[0].messageBox!.frame.height
}
}
}
override func didChangeSize(_ oldSize: CGSize)
{
super.didChangeSize(oldSize)
if background != nil
{
background.size = CGSize(width: self.frame.width, height: self.frame.height)
background.position = CGPoint(x: self.frame.width/2, y: self.frame.height/2)
}
if self.view != nil && !listOfTextMessages.isEmpty
{
if UIDevice.current.orientation.isLandscape
{
let textboxWidth : CGFloat = 800
let textlabelWidth = textboxWidth-50
for (index,textBox) in listOfTextMessages.enumerated()
{
if index == 0
{
textBox.messageText!.fontSize = 45
textBox.messageText!.fontColor = SKColor.white
textBox.messageText!.numberOfLines = 0
textBox.messageText!.horizontalAlignmentMode = .left
textBox.messageText!.verticalAlignmentMode = .center
textBox.messageText!.preferredMaxLayoutWidth = textlabelWidth
let textboxHeight = textBox.messageText!.frame.height + 50
let rightEdgeX = self.convert(CGPoint(x: self.frame.maxX, y: 0), to: background).x
let bottomEdgeY = self.convert(CGPoint(x: 0, y: self.frame.minY), to: background).y
let boxPositionX = rightEdgeX-50-textboxWidth
let boxPositionY : CGFloat = bottomEdgeY+100
textBox.messageBox!.path = UIBezierPath(roundedRect: CGRect(x: boxPositionX, y: boxPositionY, width: textboxWidth, height: textboxHeight), cornerRadius: 20).cgPath
textBox.messageText!.position = CGPoint(x: textBox.messageBox!.frame.minX+25, y: textBox.messageBox!.frame.maxY-textboxHeight/2)
}
else
{
textBox.messageText!.fontSize = 45
textBox.messageText!.fontColor = SKColor.white
textBox.messageText!.numberOfLines = 0
textBox.messageText!.horizontalAlignmentMode = .left
textBox.messageText!.verticalAlignmentMode = .center
textBox.messageText!.preferredMaxLayoutWidth = textlabelWidth
let textboxHeight = textBox.messageText!.frame.height + 50
let rightEdgeX = self.convert(CGPoint(x: self.frame.maxX, y: 0), to: background).x
let boxPositionX = rightEdgeX-50-textboxWidth
let boxPositionY = listOfTextMessages[index-1].messageBox!.frame.minY //+ textboxHeight
textBox.messageBox!.path = UIBezierPath(roundedRect: CGRect(x: boxPositionX, y: boxPositionY, width: textboxWidth, height: textboxHeight), cornerRadius: 20).cgPath
textBox.messageText!.position = CGPoint(x: textBox.messageBox!.frame.minX+25, y: textBox.messageBox!.frame.minY-textboxHeight/2)
}
}
}
else
{
let textboxWidth : CGFloat = 500
let textlabelWidth = textboxWidth-50
for (index,textBox) in listOfTextMessages.enumerated()
{
if index == 0
{
textBox.messageText!.fontSize = 45
textBox.messageText!.fontColor = SKColor.white
textBox.messageText!.numberOfLines = 0
textBox.messageText!.horizontalAlignmentMode = .left
textBox.messageText!.verticalAlignmentMode = .center
textBox.messageText!.preferredMaxLayoutWidth = textlabelWidth
let textboxHeight = textBox.messageText!.frame.height + 50
let rightEdgeX = self.convert(CGPoint(x: self.frame.maxX, y: 0), to: background).x
let bottomEdgeY = self.convert(CGPoint(x: 0, y: self.frame.minY), to: background).y
let boxPositionX = rightEdgeX-50-textboxWidth
let boxPositionY : CGFloat = bottomEdgeY+100
textBox.messageBox!.path = UIBezierPath(roundedRect: CGRect(x: boxPositionX, y: boxPositionY, width: textboxWidth, height: textboxHeight), cornerRadius: 20).cgPath
textBox.messageText!.position = CGPoint(x: textBox.messageBox!.frame.minX+25, y: textBox.messageBox!.frame.maxY-textboxHeight/2)
}
else
{
textBox.messageText!.fontSize = 45
textBox.messageText!.fontColor = SKColor.white
textBox.messageText!.numberOfLines = 0
textBox.messageText!.horizontalAlignmentMode = .left
textBox.messageText!.verticalAlignmentMode = .center
textBox.messageText!.preferredMaxLayoutWidth = textlabelWidth
let textboxHeight = textBox.messageText!.frame.height + 50
let rightEdgeX = self.convert(CGPoint(x: self.frame.maxX, y: 0), to: background).x
let boxPositionX = rightEdgeX-50-textboxWidth
let boxPositionY = listOfTextMessages[index-1].messageBox!.frame.maxY - textboxHeight
textBox.messageBox!.path = UIBezierPath(roundedRect: CGRect(x: boxPositionX, y: boxPositionY, width: textboxWidth, height: textboxHeight), cornerRadius: 20).cgPath
textBox.messageText!.position = CGPoint(x: textBox.messageBox!.frame.minX+25, y: textBox.messageBox!.frame.minY-textboxHeight/2)
}
}
}
}
}
}
Спасибо!
РЕДАКТИРОВАТЬ:
Код для ViewController:
import UIKit
import SpriteKit
import GameplayKit
class GameViewController: UIViewController {
override func viewDidLoad()
{
super.viewDidLoad()
let scene = GameScene()
let skView = self.view as! SKView
if skView.bounds.size.height>skView.bounds.size.width
{
scene.size = CGSize(width: 1080, height: 1920)
}
else
{
scene.size = CGSize(width: 1920, height: 1080)
}
skView.showsFPS = true
skView.showsNodeCount = true
skView.ignoresSiblingOrder = false
scene.scaleMode = .aspectFit
skView.presentScene(scene)
}
override func viewWillLayoutSubviews()
{
super.viewDidLayoutSubviews()
let skView = self.view as! SKView
if let scene = skView.scene
{
if skView.bounds.size.height>skView.bounds.size.width
{
scene.size = CGSize(width: 1080, height: 1920)
}
else
{
scene.size = CGSize(width: 1920, height: 1080)
}
var size = scene.size
// Bound size of the SKView in Points
let boundWidth = skView.bounds.width
let boundHeight = skView.bounds.height
// New Height and Width ratio based on points
let newHeight = boundHeight*size.width/boundWidth
let newWidth = boundWidth*size.height/boundHeight
// Adjust the new height in the scene
if newHeight > size.height
{
//scene.anchorPoint = CGPoint(x: 0, y: (newHeight - scene.size.height) / 2.0 / newHeight)
size.height = newHeight
scene.size = size
}
// Adjust the new width in the scene
if newWidth > size.width
{
//scene.anchorPoint = CGPoint(x: 0, y: (newWidth - scene.size.width) / 2.0 / newWidth)
size.width = newWidth
scene.size = size
}
}
}
}