Je dois détecter lorsque l'appareil est en orientation portrait afin de pouvoir lancer une animation spéciale. Mais je ne veux pas que ma vue tourne automatiquement.
Comment remplacer une vue en rotation automatique lorsque l'appareil est tourné en mode portrait? Mon application n'a besoin que d'afficher sa vue en paysage, mais il semble que je doive également prendre en charge le portrait si je veux pouvoir détecter une rotation vers le portrait.
Essayez de faire ce qui suit lorsque l'application se charge ou lorsque votre vue se charge:
[[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
[[NSNotificationCenter defaultCenter]
addObserver:self selector:@selector(orientationChanged:)
name:UIDeviceOrientationDidChangeNotification
object:[UIDevice currentDevice]];
Ajoutez ensuite la méthode suivante:
- (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;
};
}
Ce qui précède vous permettra de vous inscrire aux changements d'orientation de l'appareil sans activer la rotation automatique de votre vue.
Dans tous les cas dans iOS, lorsque vous ajoutez un observateur, supprimez-le également aux moments appropriés (éventuellement, mais pas toujours, lorsque la vue apparaît/disparaît). Vous ne pouvez avoir que des "paires" de code d'observation/de désobservation. Si vous ne le faites pas, l'application se bloquera. Choisir où observer/désobserver dépasse le cadre de cet AQ. Cependant, vous devez avoir un "unobserve" pour correspondre au code "observe" ci-dessus.
Si vous êtes venu à cette question en cherchant comment détecter un changement d'orientation (sans nécessairement vouloir désactiver la rotation), vous devez également être conscient de viewWillTransitionToSize
, qui est disponible depuis iOS 8 .
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)
}
Et si vous n'avez pas à vous soucier de l'orientation réelle:
override func viewWillTransitionToSize(size: CGSize, withTransitionCoordinator coordinator: UIViewControllerTransitionCoordinator) {
// do something
super.viewWillTransitionToSize(size, withTransitionCoordinator: coordinator)
}
- (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];
}
Et si vous n'avez pas à vous soucier de l'orientation réelle (tirée de cette réponse ):
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
// Do view manipulation here.
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
}
1) Swift version de la réponse de David 2) Dans le cas où vous souhaitez toujours détecter l'orientation quand il n'y a pas de changement d'orientation (Swift vesion of Moe's answer to How I I detect the orientation of the appareil sur 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())
fonction orientationChanged
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
}
}
Si je vous comprends bien, votre application est uniquement en mode paysage. Vous pouvez simplement spécifier dans la configuration des applications qu'il s'agit uniquement de paysage et n'avez donc pas à vous soucier de la rotation. L'application démarrera en mode paysage et y restera quelle que soit la façon dont l'iPad est orienté.
Si vous ne souhaitez pas créer d'objet périphérique, vous pouvez également utiliser
-(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
}
}
.UIDeviceOrientationDidChange
la notification est appelée plusieurs fois sur l'iphone même lorsque l'appareil ne tourne pas. Je ne connais pas la raison, mais si vous en avez besoin uniquement lorsque l'appareil tourne vraiment, procédez comme suit.
NotificationCenter.default.addObserver(self, selector: #selector(orientationChanged), name: .UIDeviceOrientationDidChange, object: nil)
La méthode appelée depuis l'observateur devrait ressembler à ceci:
func orientationChanged() {
if traitCollection.isIphone {
defer {
self.previousTraitCollectionForIphone = traitCollection
}
guard let previousTraitCollectionForIphone = previousTraitCollectionForIphone else {
updateView()
return
}
if previousTraitCollectionForIphone != traitCollection {
updateView()
}
} else {
updateView()
}
}
Tout d'abord, désactivez tout sauf l'orientation souhaitée (pour qu'elle ne tourne pas)
Ensuite, comme David l'a dit, obtenez simplement l'orientation actuelle de l'appareil:
Alternativement, vous pouvez simplement utiliser l'accéléromètre vous-même (car c'est de cette façon qu'il est fait de toute façon) et vérifier où se trouve la gravité pour voir son orientation. Si vous adoptez cette approche, vous pouvez jouer avec les valeurs vous-même pour obtenir des résultats différents.