xcode - 如何在iOS 6中強制將UIViewController設置為縱向





ios6 xamarin.ios (14)


我有一個非常好的方法混合https://stackoverflow.com/a/13982508/2516436和https://stackoverflow.com/a/17578272/2516436

-(NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
    NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown;


    if(self.window.rootViewController){
        UIViewController *presentedViewController = [self topViewControllerWithRootViewController:self.window.rootViewController];
        orientations = [presentedViewController supportedInterfaceOrientations];
    }

    return orientations;
}

- (UIViewController*)topViewControllerWithRootViewController:(UIViewController*)rootViewController {
    if ([rootViewController isKindOfClass:[UITabBarController class]]) {
        UITabBarController* tabBarController = (UITabBarController*)rootViewController;
        return [self topViewControllerWithRootViewController:tabBarController.selectedViewController];
    } else if ([rootViewController isKindOfClass:[UINavigationController class]]) {
        UINavigationController* navigationController = (UINavigationController*)rootViewController;
        return [self topViewControllerWithRootViewController:navigationController.visibleViewController];
    } else if (rootViewController.presentedViewController) {
        UIViewController* presentedViewController = rootViewController.presentedViewController;
        return [self topViewControllerWithRootViewController:presentedViewController];
    } else {
        return rootViewController;
    }
}

並返回您想要為每個UIViewController支持的任何方向

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;
}

由於ShouldAutorotateToInterfaceOrientation在iOS 6中已被棄用,並且我使用它強制將某個特定視圖強制為顯示縱向 ,所以在iOS 6中執行此操作的正確方法是什麼? 這只適用於我的應用程序的一個區域,所有其他視圖都可以旋轉。




把它放在你不想旋轉的每個ViewController的.m文件中:

- (NSUInteger)supportedInterfaceOrientations
{
    //return UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskLandscapeLeft;
    return UIInterfaceOrientationMaskPortrait;
}

請參閱developer.apple.com/library/ios/#featuredarticles/…了解更多信息。




我不同意@aprato的回答,因為UIViewController旋轉方法是在類別本身中聲明的,因此如果您在另一個類別中重寫,則會導致未定義的行為。 在UINavigationController(或UITabBarController)子類中重寫它們更安全

此外,這不包括您從橫向視圖中將/呈現/彈出到僅肖像VC或反之亦然的場景。 為了解決這個棘手的問題(Apple從未解決),您應該:

在iOS中<= 4和iOS> = 6:

UIViewController *vc = [[UIViewController alloc]init];
[self presentModalViewController:vc animated:NO];
[self dismissModalViewControllerAnimated:NO];
[vc release];

在iOS 5中:

UIWindow *window = [[UIApplication sharedApplication] keyWindow];
UIView *view = [window.subviews objectAtIndex:0];
[view removeFromSuperview];
[window addSubview:view];

這些將會強制UIKit重新評估您的所有shouldAutorotate,supportedInterfaceOrientations等。




只需進入project.plist,然後添加支持的界面方向,然後只添加肖像(底部主頁按鈕)和肖像(頂部主頁按鈕)。

您可以根據項目要求添加或刪除那裡的方向。

謝謝







對於iOS6來說,最好的方法是在Ray Wenderlich團隊的“iOS6 By Tutorials”中註明 - http://www.raywenderlich.com/並且比大多數情況下的UINavigationController的子類更好。

我使用的iOS6包含一個設置為初始視圖控制器的UINavigationController故事板。

//AppDelegate.m - 這種方法在iOS6之前是不可用的

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window{
NSUInteger orientations = UIInterfaceOrientationMaskAllButUpsideDown;

if(self.window.rootViewController){
    UIViewController *presentedViewController = [[(UINavigationController *)self.window.rootViewController viewControllers] lastObject];
    orientations = [presentedViewController supportedInterfaceOrientations];
}

return orientations;
}

//MyViewController.m - 返回每個UIViewController支持的方向

- (NSUInteger)supportedInterfaceOrientations{
    return UIInterfaceOrientationMaskPortrait;
}



這個答案與OP的帖子評論中提出的問題有關:

要強制視圖出現在給定的方向中,請將viewWillAppear放置在以下位置:

UIApplication* application = [UIApplication sharedApplication];
if (application.statusBarOrientation != UIInterfaceOrientationPortrait)
{
    UIViewController *c = [[UIViewController alloc]init];
    [self presentModalViewController:c animated:NO];
    [self dismissModalViewControllerAnimated:NO];
}

這有點破解,但是這迫使UIViewController以縱向呈現,即使前一個控制器是橫向的

更新iOS7

上面的方法現在已被棄用,所以對於iOS 7,使用以下方法:

UIApplication* application = [UIApplication sharedApplication];
if (application.statusBarOrientation != UIInterfaceOrientationPortrait)
{
     UIViewController *c = [[UIViewController alloc]init];
     [c.view setBackgroundColor:[UIColor redColor]];
     [self.navigationController presentViewController:c animated:NO completion:^{
            [self.navigationController dismissViewControllerAnimated:YES completion:^{
            }];
     }];
}

有趣的是,在撰寫本文時, 無論是現在還是解僱都必須是動畫形式。 如果兩者都不是,那麼你會得到一個白色的屏幕。 不知道為什麼這使它工作,但它確實! 視覺效果因動畫而異。




對於Monotouch,你可以這樣做:

public override UIInterfaceOrientationMask GetSupportedInterfaceOrientations()
    {
    return UIInterfaceOrientationMask.LandscapeRight;
}

public override UIInterfaceOrientation PreferredInterfaceOrientationForPresentation()
    {
    return UIInterfaceOrientation.LandscapeRight;
}



1)檢查你的項目設置和info.plist,並確保只選擇你想要的方向。

2)將以下方法添加到最頂層的視圖控制器(導航控制器/ tabbar控制器)

- (NSUInteger) supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;

}

3)將以下方法添加到您的應用程序委託

- (NSUInteger) supportedInterfaceOrientations
{
    return UIInterfaceOrientationMaskPortrait;

}

- (NSUInteger)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window
{
    return UIInterfaceOrientationMaskPortrait;

}



如果您希望我們所有的導航控制器都遵守頂級視圖控制器,您可以使用一個類別,這樣您就不必經歷並更改一堆類名稱。

@implementation UINavigationController (Rotation_IOS6)

-(BOOL)shouldAutorotate
{
    return [[self.viewControllers lastObject] shouldAutorotate];
}

-(NSUInteger)supportedInterfaceOrientations
{
    return [[self.viewControllers lastObject] supportedInterfaceOrientations];
}

- (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation
{
    return [[self.viewControllers lastObject] preferredInterfaceOrientationForPresentation];
}

@end

正如一些評論指出的那樣,這是對問題的快速解決。 更好的解決方案是UINavigationController的子類,並將這些方法放在那裡。 一個子類也有助於支持6和7。




IOS 5

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation{

    return (interfaceOrientation == UIInterfaceOrientationPortrait);

}

IOS 6

-(BOOL)shouldAutorotate{
    return YES;
}

-(NSInteger)supportedInterfaceOrientations{

    //    UIInterfaceOrientationMaskLandscape;
    //    24
    //
    //    UIInterfaceOrientationMaskLandscapeLeft;
    //    16
    //
    //    UIInterfaceOrientationMaskLandscapeRight;
    //    8
    //
    //    UIInterfaceOrientationMaskPortrait;
    //    2

    //    return UIInterfaceOrientationMaskPortrait; 
    //    or
          return 2;
}



在這裡不要沉悶,但你會如此善良地分享你的子類? 謝謝。

編輯:好吧,我終於做到了,這個子類很簡單。 我只需將AppDelegatenavigationController聲明為UINavigationControllerSubclass而不是默認的UINavigationController ,然後使用以下方法修改您的子類:

- (BOOL)shouldAutorotate {
    return _shouldRotate;
}

所以我可以通過調用viewDidLoad來設置我想旋轉的任何視圖

_navController = (UINavigationController *)self.navigationController;
[_navController setShouldRotate : YES / NO]

希望這個調整也能幫助其他人,謝謝你的提示!

提示:利用

- (NSUInteger)supportedInterfaceOrientations

在你的視圖控制器中,所以你最終不需要在橫向上顯示一幅肖像所需的視圖,反之亦然。




使用子類或類別的答案允許UINavigationController和UITabBarController類中的VC運行良好。 從橫向標籤欄控制器啟動僅肖像模式失敗。 如果你需要這樣做,那麼使用顯示和隱藏非動畫模式視圖的技巧,但在viewDidAppear方法中執行 。 它在viewDidLoad或viewWillAppear中並不適用於我。

除此之外,上述解決方案工作正常。




如果您希望它是合法的,那麼您有兩種選擇,基於雲的Mac解決方案或跨平台開發工具。 如果你不關心合法的東西,你可以考慮hackintosh方法或虛擬機。 如果你有一台體面的PC,運行虛擬機將是最簡單的方法。 你可能永遠都不知道哪一個硬件會在haintosh上出現驅動程序問題。

我嘗試了所有這些方法,他們都有優點和缺點,但對於第二組,我感到內疚。 我開發應用程序謀生,並且我不想為了它而撕掉其他人。

如果您正在製作一個小型項目,基於雲的Mac可能會很有用。 租一小段時間,開發你的項目,然後離開你。 不要去學習任何新東西。

但是,如果您的項目越來越大,跨平台框架似乎是唯一的選擇。 關鍵的是你需要明智地選擇。 有這麼多的混合框架,但他們做的事情可以用一句話來概括為“在應用程序包裝中浸入網頁”,而開發人員對混合框架的負面經歷也會影響本地框架。

我嘗試了三種(Titanium,Smartface和Xamarin),他們都聲稱會產生“真正的本地輸出”,並且我認為他們的說法是正確的。 你需要測試並看到它,你很難描述出本地的感覺。 在之前的評論中,有人指出,學習這些平台需要一些努力,但是一旦了解它們,就可以開發iOS應用程序,而不僅僅是Android應用程序,它們都具有通用的代碼庫。 當然,它們比雲端Mac便宜得多。 其中一些甚至是免費的。 您只需要一台Mac用於商店提交。

如果您了解JavaScript,請嘗試使用Titanium和Smartface,如果您了解C#,請嘗試Xamarin。 請注意,對於設備模擬器,Titanium依賴於Mac,但Smartface具有用於Windows開發的模擬器應用程序,它的工作效果比我預期的要好。 另一方面,Xamarin需要在您的網絡中使用Mac。





ios xcode ios6 xamarin.ios