Обнаружение ориентации iOS UIDevice
Мне нужно определить, когда устройство находится в портретной ориентации, чтобы я мог отключить специальную анимацию. Но я не хочу, чтобы мой взгляд на авторотацию.
Как переопределить авторотирование вида, когда устройство повернуто к портрету? Моему приложению нужно только отображать его в ландшафте, но мне кажется, что мне нужно поддерживать портрет также, если я хочу, чтобы можно было обнаружить поворот к портрету.
Ответы
Ответ 1
Попробуйте выполнить следующее при загрузке приложения или при загрузке вашего представления:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:[UIDevice currentDevice]];
Затем добавьте следующий метод:
- (void) orientationChanged:(NSNotification *)note
{
UIDevice * device = note.object;
switch(device.orientation)
{
case UIDeviceOrientationPortrait:
/* start special animation */
break;
case UIDeviceOrientationPortraitUpsideDown:
/* start special animation */
break;
default:
break;
};
}
Вышеупомянутое позволит вам регистрировать изменения ориентации устройства без включения авторотации вашего представления.
Примечание
Во всех случаях в iOS при добавлении наблюдателя также удаляйте его в соответствующие моменты времени (возможно, но не всегда, когда представление появляется/исчезает). Вы можете иметь только "пары" кода наблюдения/ненаблюдения. Если вы этого не сделаете, приложение выйдет из строя. Выбор места для наблюдения/ненаблюдения выходит за рамки этого QA. Однако вы должны иметь "unobserve", чтобы соответствовать "наблюдаемому" коду выше.
Ответ 2
Если вы пришли к этому вопросу в поисках того, как определить изменение ориентации (не обязательно желая отключить поворот), вы также должны знать viewWillTransitionToSize
, который доступен в iOS 8.
Пример Swift из здесь
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
coordinator.animateAlongsideTransition({ (UIViewControllerTransitionCoordinatorContext) -> Void in
let orient = UIApplication.sharedApplication().statusBarOrientation
switch orient {
case .Portrait:
println("Portrait")
// Do something
default:
println("Anything But Portrait")
// Do something else
}
}, completion: { (UIViewControllerTransitionCoordinatorContext) -> Void in
println("rotation completed")
})
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
}
И если вам не нужно беспокоиться о фактической ориентации:
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
// do something
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
}
Objective-C пример из здесь
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
[coordinator animateAlongsideTransition:^(id<UIViewControllerTransitionCoordinatorContext> context)
{
UIInterfaceOrientation orientation = [[UIApplication sharedApplication] statusBarOrientation];
// do whatever
} completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
{
}];
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}
И если вам не нужно беспокоиться о фактической ориентации (взятой из этого ответа):
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
// Do view manipulation here.
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}
См. также
Ответ 3
1) Быстрая версия ответа Дэвида
2) Если вы все еще хотите определить ориентацию, когда нет изменения ориентации (Swift vesion of Moe отвечает Как определить ориентацию устройства на iOS?)
// Initial device orientation
let orientation: UIInterfaceOrientation = UIApplication.sharedApplication().statusBarOrientation
if(orientation == UIInterfaceOrientation.Unknown){
// code for Unknown
}
else if(orientation == UIInterfaceOrientation.Portrait){
// code for Portrait
}
else if(orientation == UIInterfaceOrientation.PortraitUpsideDown){
// code for Portrait
}
else if(orientation == UIInterfaceOrientation.LandscapeRight){
// code for Landscape
}
else if(orientation == UIInterfaceOrientation.LandscapeLeft){
// ode for Landscape
}
// To detect device orientation change
UIDevice.currentDevice().beginGeneratingDeviceOrientationNotifications()
NSNotificationCenter.defaultCenter().addObserver(
self,
selector: "orientationChanged:",
name: UIDeviceOrientationDidChangeNotification,
object: UIDevice.currentDevice())
orientationChanged function
func orientationChanged(note: NSNotification)
{
let device: UIDevice = note.object as! UIDevice
switch(device.orientation)
{
case UIDeviceOrientation.Portrait:
// code for Portrait
break
case UIDeviceOrientation.PortraitUpsideDown:
// code for Portrait
break
case UIDeviceOrientation.LandscapeLeft:
// code for Landscape
break
case UIDeviceOrientation.LandscapeRight:
// code for Landscape
break
case UIDeviceOrientation.Unknown:
// code for Unknown
break
default:
break
}
}
Ответ 4
Если вы правильно поняли, ваше приложение будет только ландшафтом. Вы можете просто указать в настройках приложений, что это только пейзаж, и поэтому не нужно беспокоиться о вращении. Приложение запустится в пейзаже и останется там независимо от того, как ориентируется iPad.
Ответ 5
Сначала отключите все, кроме нужной ориентации (чтобы она не вращалась)
Тогда, как сказал Дэвид, просто введите текущую ориентацию устройства:
https://developer.apple.com/library/ios/#documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/MotionEvents/MotionEvents.html
В качестве альтернативы вы можете просто использовать акселерометр самостоятельно (так как все равно это делается)
и проверьте, где находится сила тяжести, чтобы увидеть, какую ориентацию она имеет. Если вы примете такой подход, вы можете сами играть со значениями, чтобы получить разные результаты.
Ответ 6
Если вы не хотите создавать объект устройства, вы также можете использовать
-(void) seObserverForOrientationChanging
{
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:[UIDevice currentDevice]];
}
- (void) orientationChanged:(NSNotification *)note
{
if (UIDeviceOrientationIsLandscape([UIDevice currentDevice].orientation)){
//Do something in landscape
}
else {
//Do something in portrait
}
}
Ответ 7
.UIDeviceOrientationDidChange
уведомление вызывается много раз на iphone, даже если устройство не вращается. Не знаете причину, но если вам это нужно, только когда устройство действительно повернуто, сделайте следующее.
NotificationCenter.default.addObserver(self, selector: #selector(orientationChanged), name: .UIDeviceOrientationDidChange, object: nil)
Метод, вызываемый от наблюдателя, должен выглядеть так:
func orientationChanged() {
if traitCollection.isIphone {
defer {
self.previousTraitCollectionForIphone = traitCollection
}
guard let previousTraitCollectionForIphone = previousTraitCollectionForIphone else {
updateView()
return
}
if previousTraitCollectionForIphone != traitCollection {
updateView()
}
} else {
updateView()
}
}