Ich arbeite an einer iPad-App mit AutoLayout. Wenn der Benutzer einen bestimmten Modus aktiviert ("Heads-up" -Modus), möchte ich nur die Ausrichtung im Hochformat (oder im Hochformat auf dem Kopf stehend) unterstützen und außerdem, wenn sich das Gerät befindet Querformat möchte ich automatisch in den Hochformatmodus wechseln.
In der Draufsicht-Steuerung habe ich Folgendes:
- (NSUInteger) supportedInterfaceOrientations {
if (self.modeHeadsUp) {
return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown;
} else {
return UIInterfaceOrientationMaskAll;
}
}
- (BOOL) shouldAutorotate {
return TRUE;
}
Basierend auf den Antworten, die ich hier an anderer Stelle gesehen habe, scheint die Antwort zu sein, dass ich "application setStatusBarOrientation" verwenden sollte. Daher habe ich in die Methode, bei der der Benutzer den "Heads-up" -Modus ausgewählt hat, Folgendes aufgenommen:
UIApplication *application = [UIApplication sharedApplication];
[application setStatusBarOrientation:UIInterfaceOrientationPortrait
animated:YES];
Dies scheint jedoch einfach nichts zu bewirken. Ich kann das Gerät zwar physisch bewegen, um es in ein Hochformat zu verwandeln, dies geschieht jedoch nicht automatisch.
Wenn ich im Querformatmodus bin, nachdem ich den obigen Code ausgeführt habe, um zu versuchen, die Ausrichtung programmgesteuert festzulegen, bleibt die Anwendung "statusBarOrientation" mit dem folgenden Code bei "4" für Querformat:
UIApplication *application = [UIApplication sharedApplication];
int orientation = [application statusBarOrientation];
self.movesTextView.text = [NSString stringWithFormat:@"ORIENTATION %d", orientation];
Es schien, als würde mit der setStatusBarOrientation kein Autolayout ausgelöst, also habe ich versucht, diesen Code nachher ohne Erfolg hinzuzufügen:
[super updateViewConstraints];
[self.view updateConstraints];
Mir ist klar, dass Apple die Geräteorientierung in den Händen des Benutzers lassen möchte. Ich möchte jedoch den Querformatmodus unterstützen können, wenn ich mich nicht im "Heads-up" -Modus befinde.
Vermisse ich etwas, um eine Orientierungsänderung erzwingen zu können?
quelle
Benutze das. Perfekte Lösung für Orientierungsprobleme..ios7 und früher
[[UIDevice currentDevice] setValue: [NSNumber numberWithInteger: UIInterfaceOrientationPortrait] forKey:@"orientation"];
quelle
Sie müssen anrufen
attemptRotationToDeviceOrientation (UIViewController)
, damit das System Sie anruft,supportedInterfaceOrientations
wenn sich die Bedingung geändert hat.quelle
UIViewController
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft]; [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
funktioniert, aber Sie müssen zurückkehrenAutorotate mit YES in Ihrem View Controller
- (BOOL)shouldAutorotate { return self.shouldAutoRotate; }
Aber wenn Sie das tun, wird Ihr VC automatisch drehen, wenn der Benutzer das Gerät dreht ... also habe ich es geändert in:
@property (nonatomic, assign) BOOL shouldAutoRotate; - (BOOL)shouldAutorotate { return self.shouldAutoRotate; }
und ich rufe an
- (void)swithInterfaceOrientation:(UIInterfaceOrientation)orientation { self.rootVC.shouldAutoRotate = YES; NSNumber *value = [NSNumber numberWithInt: orientation]; [[UIDevice currentDevice] setValue:value forKey:@"orientation"]; }
um eine neue Ausrichtung mit einem Knopfdruck zu erzwingen. Um shouldAutoRotate auf NO zurückzusetzen, habe ich meine rootVC hinzugefügt
- (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { self.shouldAutoRotate = NO; }
PS: Diese Problemumgehung funktioniert auch in allen Simulatoren.
quelle
Das funktioniert bei mir am
Xcode
6 & 5.- (BOOL)shouldAutorotate { return YES; } - (NSUInteger)supportedInterfaceOrientations { return (UIInterfaceOrientationMaskPortrait); }
quelle
Die einzige Möglichkeit, die für mich funktioniert hat, ist die Präsentation des Dummy-Modal-View-Controllers.
UIViewController* dummyVC = [[UIViewController alloc] init]; dummyVC.view = [[UIView alloc] init]; [self presentModalViewController:dummyVC animated:NO]; [self dismissModalViewControllerAnimated:NO];
Ihr VC wird nach aktualisierten Schnittstellenausrichtungen gefragt, wenn der Modal View Controller deaktiviert wird.
Merkwürdig ist, dass UINavigationController genau dies tut, wenn untergeordnete View-Controller mit unterschiedlichen unterstützten Schnittstellenausrichtungen (getestet unter iOS 6.1, 7.0) verschoben / geöffnet werden.
quelle
Wenn Sie einen UIViewController haben, der im Hochformat bleiben soll, fügen Sie einfach diese Überschreibung hinzu und schon sind Sie fertig.
override func supportedInterfaceOrientations() -> UIInterfaceOrientationMask { return UIInterfaceOrientationMask.Portrait }
Das Beste daran ist, dass es keine Animation gibt, wenn diese Ansicht angezeigt wird. Sie befindet sich nur bereits in der richtigen Ausrichtung.
quelle
Mit dieser Lösung können Sie eine bestimmte Schnittstellenausrichtung erzwingen, indem Sie den Wert von vorübergehend überschreiben
UIDevice.current.orientation
und das System dann auffordern, die Schnittstelle entsprechend der Drehung des Geräts zu drehen:Wichtig: Dies ist ein Hack und kann jederzeit aufhören zu arbeiten
Fügen Sie dem Root View Controller Ihrer App Folgendes hinzu:
class RootViewController : UIViewController { private var _interfaceOrientation: UIInterfaceOrientation = .portrait override var supportedInterfaceOrientations: UIInterfaceOrientationMask { return UIInterfaceOrientationMask(from: _interfaceOrientation) } override var preferredInterfaceOrientationForPresentation: UIInterfaceOrientation { return _interfaceOrientation } override func viewDidLoad() { super.viewDidLoad() // Register for notifications NotificationCenter.default.addObserver(self, selector: #selector(RootViewController.handleInterfaceOrientationChangeRequestedNotification(_:)), name: .interfaceOrientationChangeRequested, object: nil) } deinit { NotificationCenter.default.removeObserver(self) } func handleInterfaceOrientationChangeRequestedNotification(_ notification: Notification) { guard let interfaceOrientation = notification.object as? UIInterfaceOrientation else { return } _interfaceOrientation = interfaceOrientation // Set device orientation // Important: // • Passing a UIDeviceOrientation here doesn't work, but passing a UIInterfaceOrientation does // • This is a hack, and could stop working at any moment UIDevice.current.setValue(interfaceOrientation.rawValue, forKey: "orientation") // Rotate the interface to the device orientation we just set UIViewController.attemptRotationToDeviceOrientation() } } private extension UIInterfaceOrientationMask { init(from interfaceOrientation: UIInterfaceOrientation) { switch interfaceOrientation { case .portrait: self = .portrait case .landscapeLeft: self = .landscapeLeft case .landscapeRight: self = .landscapeRight case .portraitUpsideDown: self = .portraitUpsideDown case .unknown: self = .portrait } } } extension Notification.Name { static let interfaceOrientationChangeRequested = Notification.Name(rawValue: "interfaceOrientationChangeRequested") }
Stellen Sie sicher, dass alle Schnittstellenausrichtungen unter "Bereitstellungsinformationen" überprüft sind:
Fordern Sie Änderungen an der Ausrichtung der Benutzeroberfläche an, wo Sie sie benötigen:
NotificationCenter.default.post(name: .interfaceOrientationChangeRequested, object: UIInterfaceOrientation.landscapeRight)
quelle
Wenn Sie die Hauptansicht Ihrer App für Hochformat sperren möchten, aber Popup-Ansichten im Querformat öffnen möchten und tabBarController wie ich als rootViewController verwenden, können Sie diesen Code in Ihrem AppDelegate verwenden.
AppDelegate.h
@interface AppDelegate : UIResponder <UIApplicationDelegate, UITabBarControllerDelegate> @property (strong, nonatomic) UIWindow *window; @property (strong, nonatomic) UITabBarController *tabBarController; @end
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; // Create a tab bar and set it as root view for the application self.tabBarController = [[UITabBarController alloc] init]; self.tabBarController.delegate = self; self.window.rootViewController = self.tabBarController; ... } - (NSUInteger)tabBarControllerSupportedInterfaceOrientations:(UITabBarController *)tabBarController { return UIInterfaceOrientationMaskPortrait; } - (UIInterfaceOrientation)tabBarControllerPreferredInterfaceOrientationForPresentation:(UITabBarController *)tabBarController { return UIInterfaceOrientationPortrait; }
Es funktioniert sehr gut.
In Ihrem viewController, der im Querformat dargestellt werden soll, verwenden Sie einfach Folgendes:
- (NSUInteger)supportedInterfaceOrientations { return UIInterfaceOrientationMaskLandscape; } - (BOOL)shouldAutorotate { return YES; }
quelle
UINavigationController
oderUITabBarController
integrierte, also ist es vielleicht ein kleiner Unterschied.Fügen Sie diese Anweisung hinzu
AppDelegate.h
//whether to allow cross screen marker @property (nonatomic, assign) allowRotation BOOL;
Schreiben Sie diesen Codeabschnitt in
AppDelegate.m
- (UIInterfaceOrientationMask) application: (UIApplication *) supportedInterfaceOrientationsForWindow: application (UIWindow *) window { If (self.allowRotation) { UIInterfaceOrientationMaskAll return; } UIInterfaceOrientationMaskPortrait return; }
Ändern Sie die
allowRotation
Eigenschaft der Delegaten-Appquelle
Der Basis-UINavigationController sollte den folgenden Rückruf haben, damit die untergeordneten Elemente entscheiden können, welche Ausrichtung sie wünschen.
-(NSUInteger)supportedInterfaceOrientations { UIViewController *topVC = self.topViewController; return topVC.supportedInterfaceOrientations; } -(BOOL)shouldAutorotate { UIViewController *topVC = self.topViewController; return [topVC shouldAutorotate]; }
quelle
Wenn Sie nur den Porträtmodus möchten, können Sie in iOS 9 (Xcode 7):
quelle
Ich hatte ein ähnliches Problem wie Sie. Ich muss die Geräteorientierung für einige Bildschirme (wie Login) sperren und die Drehung in anderen zulassen.
Nach ein paar Änderungen und den folgenden Antworten habe ich es gemacht durch:
shouldAutorotate
Methode in dieser VC überschreiben :-(BOOL)shouldAutorotate{ return NO; }
Hoffe das wird für dich funktionieren.
quelle
Hier ist es ein VOLLSTÄNDIGES ARBEITSbeispiel für iOS 7, 8, 9, 10, wie die App-Ausrichtung auf das aktuelle Gegenteil geändert wird
Ziel c
- (void)flipOrientation { NSNumber *value; UIInterfaceOrientation currentOrientation = [[UIApplication sharedApplication] statusBarOrientation]; if(UIInterfaceOrientationIsPortrait(currentOrientation)) { if(currentOrientation == UIInterfaceOrientationPortrait) { value = [NSNumber numberWithInt:UIInterfaceOrientationPortraitUpsideDown]; } else //if(currentOrientation == UIInterfaceOrientationPortraitUpsideDown) { value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait]; } } else { if(currentOrientation == UIInterfaceOrientationLandscapeRight) { value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeLeft]; } else //if(currentOrientation == UIInterfaceOrientationLandscapeLeft) { value = [NSNumber numberWithInt:UIInterfaceOrientationLandscapeRight]; } } [[UIDevice currentDevice] setValue:value forKey:@"orientation"]; [UIViewController attemptRotationToDeviceOrientation]; }
Swift 3
func flipOrientation() -> Void { let currentOrientation : UIInterfaceOrientation = UIApplication.shared.statusBarOrientation var value : Int = 0; if(UIInterfaceOrientationIsPortrait(currentOrientation)) { if(currentOrientation == UIInterfaceOrientation.portrait) { value = UIInterfaceOrientation.portraitUpsideDown.rawValue } else //if(currentOrientation == UIInterfaceOrientation.portraitUpsideDown) { value = UIInterfaceOrientation.portrait.rawValue } } else { if(currentOrientation == UIInterfaceOrientation.landscapeRight) { value = UIInterfaceOrientation.landscapeLeft.rawValue } else //if(currentOrientation == UIInterfaceOrientation.landscapeLeft) { value = UIInterfaceOrientation.landscapeRight.rawValue } } UIDevice.current.setValue(value, forKey: "orientation") UIViewController.attemptRotationToDeviceOrientation() }
quelle
UIDevice
'sorientation
Eigentum ist nur fertig. Wurde die App für diesen Code jemals abgelehnt?Für diejenigen wie mich, die Schwierigkeiten hatten, @Sunny Shah zu bekommen, akzeptierte sie die Antwort, um an iPads zu arbeiten. Sie müssen das Kontrollkästchen "Vollbild erforderlich" in den Projekteinstellungen aktivieren. Beachten Sie, dass dies verhindert, dass Ihre App im Multitasking-Modus arbeitet, der möglicherweise akzeptabel ist oder nicht.
quelle
Versuchen Sie dies zusammen mit Ihrem Code.
-(BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation -(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
Sobald der Benutzer eine Option ausgewählt hat, rufen Sie diese Methode auf, da sich der Benutzer im Querformat befinden kann und er dann nur den Hochformatmodus in derselben Ansichtssteuerung einstellen kann. Daher sollte die Ansicht automatisch in den Hochformatmodus verschoben werden, damit diese Schaltfläche dies aufruft
-(void)willRotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
quelle
[self willRotateToInterfaceOrientation:UIInterfaceOrientationPortrait duration:ROTATE_VIEW_DELAY];
habe die Methode hinzugefügt , bei der der Heads-up-Modus ausgewählt ist, und die objc_msgSend-Antwort von Sunny Shah oben ersetzt. Leider immer noch keine Auswirkung auf das Display. Nach meinem Verständnis wird "willrotate" aufgerufen, wenn sich das Display als Reaktion auf das sich physisch bewegende Gerät des Benutzers dreht.@property (nonatomic) bool modePortraitOnly;
Das hat mir perfekt geklappt ....
NSNumber *value = [NSNumber numberWithInt:UIDeviceOrientationPortrait]; [[UIDevice currentDevice] setValue:value forKey:@"orientation"];
quelle
2020 Swift 5:
override var supportedInterfaceOrientations:UIInterfaceOrientationMask { return .portrait }
quelle