#ios #swift #uikit
#iOS #swift #uikit
Вопрос:
Возможно ли получить доступ к dismission() в классе SKScene? Dismiss — это метод, доступный в Apple UIKit. Вот ссылка на официальную документацию Apple по dismiss.
class GameScene: SKScene {
}
Попытка запустить dismission из примера IBAction:
@IBAction func dismissTapped(_ sender: Any) {
//figure out how to dismiss
}
Dismiss обычно используется следующим образом —
dismiss(animated: true, completion: nil)
Ответ №1:
dismiss
это метод в UIViewController, а не в SKScene. Однако у вашей сцены действительно есть view
свойство, которое является содержащим ее представлением (которое является SKView
, которое является UIView
, которое является UIResponder
). Вы можете использовать next
метод представления, унаследованный от UIResponder
, чтобы пройти вверх по цепочке ответчиков, пока не нажмете на первый контроллер представления (потому что UIViewController
это также UIResponder
):
extension UIResponder {
func firstParent<T: UIResponder>(ofType type: T.Type ) -> T? {
return next as? T ?? next.flatMap { $0.firstParent(ofType: type) }
}
}
//Use in your SKScene like so
view?.firstParent(ofType: UIViewController.self)?.dismiss(animated: true, completion: nil)
Комментарии:
1. Не могли бы вы подробнее объяснить этот метод firstParent? После добавления расширения за пределами класса и добавления этой строки под функцией в мой IBAction выдается сообщение об ошибке : нераспознанный селектор, отправленный в экземпляр.
2. ОТРЕДАКТИРОВАНО ВЫШЕ. Извините, я пропустил . self после UIViewController. В любом случае firstParent рекурсивно проходит вверх по цепочке ответчиков, пока не найдет тип пользовательского интерфейса, который вы ищете (обычно UIView или UIViewController), или он попадает в окно. Это делает типобезопасный способ с использованием универсального. Вы можете передать UIViewController.self или yourviewcontroller class.self в зависимости от того, какой тип объекта вы хотите получить обратно. В этом случае UIViewController.self является достаточным, поскольку dismiss определен в UIViewController.
3. спасибо за обновление! отличный ответ, просто хотел немного больше понять это, что я сейчас так ценю. После обновления кода —
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[SKView dismissTapped:]: unrecognized selector sent to instance 0x7fcf0e814800'
4. у вас есть идея, почему
NSInvalidArgumentException
здесь будут уволены? Сейчас исследую, но пытаюсь дополнить этот вопрос исключительным ответом. Еще раз спасибо за помощь5. Похоже, что это не связанная ошибка. Возможно, у вас сломан выход в вашей раскадровке или вызываемом интерфейсе
dismissTapped
? Откройте раскадровку / перо и выберите ViewController. затем нажмите на инспектор подключений справа и посмотрите, не разорвано ли соединение дляdismissTapped