簡體   English   中英

iOS根據設備方向切換視圖控制器

[英]iOS switching view controllers depending on the device orientation

我正在開發一個增強現實應用程序,到目前為止一切正常,根據設備的方向,我需要兩種不同類型的可視化(AR和Map)。 特別是當設備處於橫向模式時,應用程序應使用landscapeViewController,而當設備的方向為“面朝上”時,應用程序應使用另一個控制器(名為faceUpViewController)。 我試着用兩個簡單的視圖控制器來做,並且工作正常。 當landscapeViewController使用AR控制器時,會發生問題。 視圖是完全白色的,我不明白為什么。 這兩個控制器均由“根視圖控制器”“包含”。 我通過編碼來完成所有工作,因此沒有nib文件。 這是代碼:

RootViewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(deviceOrientationDidChange:) name:UIDeviceOrientationDidChangeNotification object:nil];
    [[UIDevice currentDevice] beginGeneratingDeviceOrientationNotifications];
}

- (void)deviceOrientationDidChange:(NSNotification *)notification{

    UIDeviceOrientation orientation = [[UIDevice currentDevice] orientation];

    if (orientation == UIDeviceOrientationLandscapeLeft) {
        if (self.landscapeViewController.view.superview == nil) {
            if (self.landscapeViewController == nil) {
                LandscapeViewController *lvc = [[LandscapeViewController alloc] init];
                self.landscapeViewController = lvc;
                [lvc release];
            }
            [self.faceUpViewController.view removeFromSuperview];
            [self.view addSubview:self.landscapeViewController.view];
        }
    }

    if (orientation == UIDeviceOrientationFaceUp) {
        if (self.faceUpViewController.view.superview == nil) {
            if (self.faceUpViewController == nil) {
                FaceUpViewController *fvc = [[FaceUpViewController alloc] init];
                self.faceUpViewController = fvc;
                [fvc release];
            }
            [self.landscapeViewController.view removeFromSuperview];
            [self.view addSubview:self.faceUpViewController.view];
        }
    }

}

@end

LandscapeViewController.m

// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView
{
    UIView *landscapeView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1024, 768)];
    landscapeView.backgroundColor = [UIColor yellowColor];
    self.view = landscapeView;
    [landscapeView release];

    ARController *arC = [[ARController alloc] initWithViewController:self];
    arC.landscapeViewController = self;
    self.arController = arC;
    [arC release];
}

//When the view appear present the camera feed
- (void)viewDidAppear:(BOOL)animated { 
    [super viewDidAppear:animated]; 
    [_arController presentModalARControllerAnimated:NO];
}

FaceUpViewController.m

- (void)loadView
{
    UIView *faceUpView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 1024, 768)];
    faceUpView.backgroundColor = [UIColor blueColor];
    self.view = faceUpView;
    [faceUpView release];
}

ARController.m非常簡單的版本

- (id) initWithViewController:(UIViewController *)theView{

    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {

        self.rootController = theView; 

        //Retrieve screen bounds
        CGRect screenBounds = [[UIScreen mainScreen] bounds]; 

        UIView *overlaidView = [[UIView alloc] initWithFrame: screenBounds];
        self.overlayView =  overlaidView;
        [overlaidView release];
        self.rootController.view = overlayView;

        // Initialise the UIImagePickerController 
        UIImagePickerController *picker= [[UIImagePickerController alloc] init];
        self.pickerController = picker;
        [picker release];

        self.pickerController.sourceType = UIImagePickerControllerSourceTypeCamera; 
        self.pickerController.cameraViewTransform = CGAffineTransformScale(
                                                                           self.pickerController.cameraViewTransform, 1.0f, 1.12412f);

        self.pickerController.showsCameraControls = NO; 
        self.pickerController.navigationBarHidden = YES; 
        self.pickerController.cameraOverlayView = _overlayView;
    }

    return self;
}

- (void)presentModalARControllerAnimated:(BOOL)animated{
    [self.rootController presentModalViewController:[self pickerController] animated:animated]; 
    self.overlayView.frame = self.pickerController.view.bounds;
}

@end

我再說一次,我正在通過沒有nib文件的編碼來做所有事情。 我真的很感謝任何建議! 謝謝

像這里所做的那樣,添加和刪除“子”視圖控制器的視圖的主要問題是視圖控制器生命周期方法( viewWillAppear:viewDidAppear:等)永遠不會在子視圖控制器上調用。 諸如UINavigationControllerUITabBarController類的容器一直都知道如何將此類方法適當地委派給他們的孩子,但是UIViewController並沒有正式支持在iOS 5之前將視圖控制器嵌套在您自己的自定義容器中的功能。這是可能的,但是這花費了很多做正確的更多工作。

如果要堅持添加和刪除子視圖的方法,則有兩個選擇:

  1. 需要iOS 5以上版本,並按照UIViewController類參考的“ 實現容器視圖控制器”部分中的描述,調用addChildViewController:removeFromParentViewControllertransitionFromViewController:toViewController:duration:options:animations:completion:willMoveToParentViewController:didMoveToParentViewController:

  2. 為了支持較舊的iOS版本,您必須重寫UIViewController類的許多方法,並將這些調用手動委派給子視圖控制器,以使它們的行為符合預期。 我將特別注意UIViewController類參考中標題為“響應視圖事件”和“響應視圖旋轉事件”的部分。

支持iOS 5之前版本的另一種方法是使用presentModalViewController:animated:顯示子視圖控制器,而不是將其視圖作為子視圖添加到容器中。 Apple在《適用於iOS的View Controller編程指南》下的創建備用橫向界面一節中介紹了這種方法。 這種方法的優點是,您的子視圖控制器作為視圖控制器層次結構的一等成員而得到正式支持,因此UIKit將自動適當地管理其生命周期。 您不必手動覆蓋和委派所有這些方法。

您可能希望嘗試提高接受率-更多的人願意幫助您。

無論如何,大膽的猜測:在您的根控制器中,嘗試將

  deviceOrientationDidChange

進入

  deviceOrientationWillChange.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM