В 7.3/9/2 + Swift как отключить анимацию вращения, когда устройство вращается?
Этот вопрос строго касается iOS9 +
Скажем, у вас есть обычное современное приложение (автозапуск, раскадровка, универсальный), который позволяет все четыре положения вращения
![введите описание изображения здесь]()
вы хотите, чтобы он автоматически определялся авторотированием, поэтому он изменится на ваши новые макеты с ограничениями, когда пользователь поворачивает устройство от пейзажа к портрету
Но вы просто не хотите анимации NO во время вращения устройства. Вы хотите, чтобы это просто "click" к новому боковому или вертикальному расположению.
Единственный способ добиться этого - добавить:
override func viewWillTransitionToSize(size:CGSize,
withTransitionCoordinator coordinator:UIViewControllerTransitionCoordinator)
{
coordinator.animateAlongsideTransition(nil, completion:
{_ in
UIView.setAnimationsEnabled(true)
})
UIView.setAnimationsEnabled(false)
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator);
}
to один, самый высокий или почти самый высокий VC, который удерживает остальные виды контейнера или что-то еще в сцене.
Это в основном та же самая древняя идея использования
willRotateToInterfaceOrientation/didRotateFromInterfaceOrientation (оба теперь непригодны для использования в современных iOS), чтобы включить анимацию.
Однако есть много проблем
-
это не работает AppWide, это беспорядок, он основан на сценах
-
Кажется, очень плохо просто отключить все анимации
-
вы можете увидеть все виды гоночных треков
Этот вопрос строго касается iOS9 +
В эти дни, есть ли лучший способ отключить анимацию вращения в приложении, которое поддерживает пейзаж/портрет???
Этот вопрос строго касается iOS9 +
Ответы
Ответ 1
Вы можете использовать метод swizzling.
Это означает, что вы собираетесь менять вызовы на "viewWillTransitionToSize" на любом контроллере представления в своем приложении, чтобы вместо этого вызвать "genericViewWillTransitionToSize".
Таким образом, вам не нужно использовать подкласс или повторный код для вашего приложения.
С этим грустным, вы должны быть очень внимательны к swizzling, с большой силой приходит большая ответственность. Поместите класс в место, где вы или следующий программист после вас, узнаете, как его найти, когда он захочет вернуть анимацию вращения для просмотра контроллеров.
extension UIViewController {
public override static func initialize() {
struct Static {
static var token: dispatch_once_t = 0
}
dispatch_once(&Static.token) {
let originalSelector = #selector(UIViewController.viewWillTransitionToSize(_:withTransitionCoordinator:))
let swizzledSelector = #selector(UIViewController.genericViewWillTransitionToSize(_:withTransitionCoordinator:))
let originalMethod = class_getInstanceMethod(self, originalSelector)
let swizzledMethod = class_getInstanceMethod(self, swizzledSelector)
let didAddMethod = class_addMethod(self, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))
if didAddMethod {
class_replaceMethod(self, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod))
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
}
// MARK: - Method Swizzling
func genericViewWillTransitionToSize(size:CGSize,
withTransitionCoordinator coordinator:UIViewControllerTransitionCoordinator)
{
self.genericViewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
coordinator.animateAlongsideTransition(nil, completion:
{_ in
UIView.setAnimationsEnabled(true)
})
UIView.setAnimationsEnabled(false)
}
}
Ответ 2
Насколько я знаю, нет лучшего способа сделать это.
Хотя вы можете объявить отдельный класс с помощью этого метода и сделать все контроллеры представлений в своем приложении подклассами.
class NoRotateAnimationVC: UIViewController {
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
UIView.setAnimationsEnabled(false)
coordinator.notifyWhenInteractionEndsUsingBlock {_ in UIView.setAnimationsEnabled(true)}
}
}
При повороте устройства все контроллеры представлений, чьи представления должны изменять свои размеры, получают вызов метода viewWillTransitionToSize
.
Вам нужно объявить этот новый класс один раз в своем приложении, а затем изменить все объявления своего контроллера представления от класса MyViewController: UIViewController
до MyViewController: NoRotateAnimationVC
.
Приведенная реализация отключает все анимации и восстанавливает их после перехода. Поэтому, если вы переопределите этот метод только в одном контроллере просмотра, если его вид изменится по размеру в результате вращения, он повсеместно отключит анимацию вращения. Но если этот контроллер просмотра неактивен, анимация не будет отключена.