В настоящее время я разрабатываю игру с использованием Swift 3, SpriteKit и Xcode 8 beta. Я пытаюсь реализовать статические 3D Touch Quick Actions с главного экрана через info.plist. В настоящее время действия отображаются на главном экране, но не идут в нужное место SKScene - переход на начальную сцену или последнюю открытую сцену (если приложение все еще открыто), что означает, что сцена не изменяется. Я пробовал различные способы настройки сцены внутри оператора switch, но ни один из них не работает должным образом для представления SKScene, поскольку строка window!.rootViewController?.present(gameViewController, animated: true, completion: nil)
работает только с UIViewController.3D Touch Быстрые действия не работают должным образом с помощью SpriteKit
Различные части этого кода взяты из различных учебных пособий, но я уверен, что через мое исследование, что сломанная часть представляет собой сцену (если я ошибаюсь), потому что она не должна даже загружать сцену, если часть сломана.
Есть ли способы представить SKScene из AppDelegate или установить начальную сцену на основе инструкции switch?
AppDelegate
import UIKit
import SpriteKit
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
guard !handledShortcutItemPress(forLaunchOptions: launchOptions) else { return false } // ADD THIS LINE
return true
}
}
extension AppDelegate: ShortcutItem {
/// Perform action for shortcut item. This gets called when app is active
func application(_ application: UIApplication, performActionForShortcutItem shortcutItem: UIApplicationShortcutItem, completionHandler: (Bool) -> Void) {
completionHandler(handledShortcutItemPress(forItem: shortcutItem))
}
}
extension AppDelegate: ShortcutItemDelegate {
func shortcutItem1Pressed() {
Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(loadShopScene), userInfo: nil, repeats: false)
}
@objc private func loadShopScene() {
let scene = ShopScene(size: CGSize(width: 768, height: 1024))
loadScene(scene: scene, view: window?.rootViewController?.view)
}
func shortcutItem2Pressed() {
Timer.scheduledTimer(timeInterval: 0.5, target: self, selector: #selector(loadGameScene), userInfo: nil, repeats: false)
}
@objc private func loadGameScene() {
let scene = GameScene(size: CGSize(width: 768, height: 1024))
loadScene(scene: scene, view: window?.rootViewController?.view)
}
func shortcutItem3Pressed() {
// do something else
}
func shortcutItem4Pressed() {
// do something else
}
func loadScene(scene: SKScene?, view: UIView?, scaleMode: SKSceneScaleMode = .aspectFill) {
guard let scene = scene else { return }
guard let skView = view as? SKView else { return }
skView.ignoresSiblingOrder = true
#if os(iOS)
skView.isMultipleTouchEnabled = true
#endif
scene.scaleMode = scaleMode
skView.presentScene(scene)
}
}
3DTouchQuickActions.swift
import Foundation
import UIKit
/// Shortcut item delegate
protocol ShortcutItemDelegate: class {
func shortcutItem1Pressed()
func shortcutItem2Pressed()
func shortcutItem3Pressed()
func shortcutItem4Pressed()
}
/// Shortcut item identifier
enum ShortcutItemIdentifier: String {
case first // I use swift 3 small letters so you have to change your spelling in the info.plist
case second
case third
case fourth
init?(fullType: String) {
guard let last = fullType.components(separatedBy: ".").last else { return nil }
self.init(rawValue: last)
}
public var type: String {
return Bundle.main.bundleIdentifier! + ".\(self.rawValue)"
}
}
/// Shortcut item protocol
protocol ShortcutItem { }
extension ShortcutItem {
// MARK: - Properties
/// Delegate
private weak var delegate: ShortcutItemDelegate? {
return self as? ShortcutItemDelegate
}
// MARK: - Methods
/// Handled shortcut item press first app launch (needed to avoid double presses on first launch)
/// Call this in app Delegate did launch with options and exit early (return false) in app delegate if this method returns true
///
/// - parameter forLaunchOptions: The [NSObject: AnyObject]? launch options to pass in
/// - returns: Bool
func handledShortcutItemPress(forLaunchOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
guard let launchOptions = launchOptions, let shortcutItem = launchOptions[UIApplicationLaunchOptionsKey.shortcutItem] as? UIApplicationShortcutItem else { return false }
handledShortcutItemPress(forItem: shortcutItem)
return true
}
/// Handle shortcut item press
/// Call this in the completion handler in AppDelegate perform action for shortcut item method
///
/// - parameter forItem: The UIApplicationShortcutItem the press was handled for.
/// - returns: Bool
func handledShortcutItemPress(forItem shortcutItem: UIApplicationShortcutItem) -> Bool {
guard let _ = ShortcutItemIdentifier(fullType: shortcutItem.type) else { return false }
guard let shortcutType = shortcutItem.type as String? else { return false }
switch shortcutType {
case ShortcutItemIdentifier.first.type:
delegate?.shortcutItem1Pressed()
case ShortcutItemIdentifier.second.type:
delegate?.shortcutItem2Pressed()
case ShortcutItemIdentifier.third.type:
delegate?.shortcutItem3Pressed()
case ShortcutItemIdentifier.fourth.type:
delegate?.shortcutItem4Pressed()
default:
return false
}
return true
}
}
Awesome. Извините за беспокойство, это была всего лишь синтаксис 3. Пожалуйста, вы можете отметить мой ответ. Я не могу вспомнить, почему я использую таймер. Если вам не нравится задержка, попробуйте сократить время или вообще не использовать один. – crashoverride777
Я бы переделал ваши другие сцены, чтобы использовать AspectFill, даже если это означает, что вам придется переделать много работы. Поверьте мне, мои 2 игры, о которых я говорил, действительно использовали ResizeFill, прежде чем я его изменил. Это был кошмар, чтобы сделать его последовательным на всех устройствах. – crashoverride777
Добро пожаловать. Просто, чтобы вернуться к сценарию масштабирования, вы поблагодарите мою связку в будущем, если вы не используете ResizeFill. Вы можете проверить это очень просто. Создайте новый шаблон Xcode Game. Используя настройки по умолчанию, если вы запустите проект, ярлык HelloWorld отлично масштабируется на всех iPhone (5, 6, 6Plus). Теперь перейдите в GameViewController и измените режим масштабирования на ResizeFill и запустите на всех устройствах. Вы заметите, что на всех устройствах он не выглядит одинаково. Я использовал помощника, чтобы сделать это вручную, помните, что это также включает такие вещи, как физические импульсы. Это было безумие – crashoverride777