2009-07-28 13 views
6

UIViewControllerの4つのサブクラスを管理するプログラマティックを作成したUITabBarControllerがあります。何かが好きです:UITabBarControllerロードビューコントローラを遅延させるには?

//Create Controller 1 
    self.terminal = [[[TerminalController alloc] initWithNibName:@"TerminalView" bundle:nil] autorelease]; 
    UINavigationController* navTerminal = [[[UINavigationController alloc] initWithRootViewController:terminal] autorelease]; 
    navTerminal.title = __(@"Terminal"); 
    navTerminal.navigationBar.barStyle = UIBarStyleBlackOpaque; 
    navTerminal.tabBarItem.image = [UIImage imageNamed:@"tab_terminal.png"];   

    //Create Controller 2 
    self.history = [[[HistoryController alloc] initWithNibName:@"HistoryView" bundle:nil] autorelease]; 
    UINavigationController* navHistory = [[[UINavigationController alloc] initWithRootViewController:history] autorelease]; 
    navHistory.title = __(@"History"); 
    navHistory.navigationBar.barStyle = UIBarStyleBlackOpaque; 
    navHistory.tabBarItem.image = [UIImage imageNamed:@"tab_history.png"]; 

    //Create Controller 3 
    self.settings = [[[SettingsController alloc] initWithNibName:@"SettingsView" bundle:nil] autorelease]; 
    UINavigationController* navSettings = [[[UINavigationController alloc] initWithRootViewController:settings] autorelease]; 
    navSettings.title = __(@"Settings"); 
    navSettings.navigationBar.barStyle = UIBarStyleBlackOpaque; 
    navSettings.tabBarItem.image = [UIImage imageNamed:@"tab_settings.png"]; 

    //Create Controller 4 
    HelpController* help = [[[HelpController alloc] initWithNibName:@"HelpView" bundle:nil] autorelease]; 
    UINavigationController* navHelp = [[[UINavigationController alloc] initWithRootViewController:help] autorelease]; 
    navHelp.title = __(@"Help"); 
    navHelp.navigationBar.barStyle = UIBarStyleBlackOpaque; 
    navHelp.tabBarItem.image = [UIImage imageNamed:@"tab_help.png"]; 

    //Create Tab Bar an add it's view to window. 
    self.tabBar = [[[UITabBarController alloc] initWithNibName:nil bundle:nil] autorelease]; 
    tabBar.viewControllers = [[[NSArray alloc] initWithObjects:navTerminal, navHistory, navSettings, navHelp, nil] autorelease]; 
    tabBar.delegate = self;  

    [window addSubview:tabBar.view]; 

UITabBarControllerに表示コントローラを遅くロードするように指示する方法はありますか?ユーザーがタブバーアイテムの1つをクリックしたとき、またはtabBarController setSelectedIndexが呼び出されたときのej。

答えて

12

私はこのアプリを私のアプリでやっています。そのトリックは、あなたのビューコントローラをUITabBarControllerのサブクラスではなくUIViewControllerにし、UITabBarDelegateを実装することです。私はIBのビューを作成し、タブバー(適切なボタン、画像、タグなど)とスワップイン/アウトされたサブビューを適切に配置するためのプレースホルダUIViewをレイアウトしました。ビューの切り替えは、タブバー上で起こる:didSelectItem:それは見えます。このような何か:

// MyTabBarController.h 
@class MyFirstViewController; 
@class MySecondViewController; 
@class MyThirdViewController; 

@interface MyTabBarController : UIViewController <UITabBarDelegate> { 
    IBOutlet UIView *placeholderView; 
    IBOutlet UITabBar *tabBar; 
    MyFirstViewController *firstViewController; 
    MySecondViewController *secondViewController; 
    MyThirdViewController *thirdViewController; 
    UIViewController *currentViewController; 
} 
@property (nonatomic, retain) MyFirstViewController *firstViewController; 
@property (nonatomic, retain) MySecondViewController *secondViewController; 
@property (nonatomic, retain) MyThirdViewController *thirdViewController; 

- (void) switchToView:(UIViewController*)aViewController; 
@end 


// MyTabBarController.m 
#import "MyTabBarController.h" 
#import "MyFirstViewController.h" 
#import "MySecondViewController.h" 
#import "MyThirdViewController.h" 

enum { 
    kView_First = 1, 
    kView_Second, 
    kView_Third 
}; 

@implementation MyTabBarController 

@synthesize firstViewController, secondViewController, thirdViewController; 

- (void) viewDidLoad { 
    // Default to first view. 
    tabBar.selectedItem = [tabBar.items objectAtIndex:0]; 
    MyFirstViewController *viewController = [[MyFirstViewController alloc] initWithNibName:@"FirstView" bundle:nil]; 
    self.firstViewController = viewController; 
    [viewController release]; 
    [self switchToView:firstViewController]; 
} 

- (void)viewWillAppear:(BOOL)animated { 
    // Tell our subview. 
    if(currentViewController != nil) { 
     [currentViewController viewWillAppear:animated]; 
    } 
} 

- (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item { 
    switch (item.tag) { 
     case kView_First: { 
      if (firstViewController == nil) { 
       MyFirstViewController *viewController = [[MyFirstViewController alloc] 
        initWithNibName:@"FirstView" bundle:nil]; 
       self.firstViewController = viewController; 
       [viewController release]; 
      } 

      [self switchToView:firstViewController]; 
     } 
     break; 

     case kView_Second: 
      if (secondViewController == nil) { 
       MySecondViewController *viewController = [[MySecondViewController alloc] 
       initWithNibName:@"SecondView" bundle:nil]; 
       self.secondViewController = viewController; 
       [viewController release]; 
      } 

      [self switchToView:secondViewController]; 
      break; 

     case kView_Third: { 
      if (timesViewController == nil) { 
       MyThirdViewController *viewController = [[MyThirdViewController alloc] 
       initWithNibName:@"ThirdView" bundle:nil]; 
       self.thirdViewController = viewController; 
       [viewController release]; 
      } 

      [self switchToView:thirdViewController]; 
     } 
     break;    
    } 
} 

- (void) switchToView:(UIViewController*)aViewController { 
    if(aViewController == currentViewController) return; 

    UIView *aView= aViewController.view;     
    [aViewController viewWillAppear:NO]; 
    if(currentViewController != nil) { 
     [currentViewController viewWillDisappear:NO]; 
     [currentViewController.view removeFromSuperview];  
    } 
    aView.frame = placeholderView.frame; 
    [self.view insertSubview:aView aboveSubview:placeholderView]; 
    if(currentViewController != nil) { 
     [currentViewController viewDidDisappear:NO]; 
    } 
    [aViewController viewDidAppear:NO]; 
    currentViewController = aViewController; 
} 
@end 

コードは確実に、よりDRY作ることができるが、あなたのアイデアを得ます。

+0

私はOPと同じ問題を抱えていました。ありがとう!!私はアプリの起動時間を2秒遅くすることができました。 –

+0

実際、私はこれ以上の作業とテストをして問題に遭遇しました。モーダルビューコントローラを表示してそのモーダルを閉じると、タブコントローラに戻ったときにそのインターフェイスが壊れてしまいます。私のUITabBarは移動しました。カスタムタブバーコントローラのサブビューであるUIViewは、より多くの画面を埋めるように伸びています。このような問題に遭遇しましたか?もしそうなら、解決策を見つけましたか? –

+0

@ケニーワイランド、私はこれのようなトラブルはありませんでしたが、私はこれまでモーダルビューを表示しようとしたことはないと思います。しかし、私の頭の上から何らかの理由があるとは思えません。 – zpasternack

2

UITabBarControllerでは、実際のView ControllerをviewControllersプロパティに設定する必要があります.Appleのフレームワークから遅延ロードはありません。タブバーコントローラは、そのプロパティのためにロードするコントローラの特定の側面に依存しています。ただし、最初にタブが押されるまでは、viewDidLoadは呼び出されません。

代わりにできるのは、viewDidLoadまたはviewWillAppearのメソッドでは、実際のビューコントローラーでタブバーコントローラーに置き換わる独自の「プレースホルダー」ビューコントローラーを作成することです。こうすることで、特定のタブのビューコントローラを読み込んで、より多くのメモリとプロセッサを消費するコントローラに置き換えるまで、タブバーコントローラが保持するビューコントローラによって使用されるメモリを最小限に抑えることができます。

サイドノート:setViewControllers:animated:メソッドを使用するのではなく、タブバーコントローラのviewControllersプロパティを直接変更して、新しいコントローラをロードするたびにユーザーにアニメーションが表示されないようにします。

0

あなたはいつも誰かがタブを選択したときにuがviewcontrollersを押し、UITabBarControllerを使用してタブバーurselfを管理することはできませんが、あなたが怠惰ロードするために何をしようとしているdidSelectIndex方法で

4

の中か?

これはかなり標準的なUITabBarControllerの実装です。私は書いているアプリケーションでそれに非常によく似たものを持っています。私のコードでは、viewDidLoad(コントローラが関連付けられたビューをメモリにロードした後に呼び出されるメソッド)は、タブがタッチされるまで呼び出されません。

この種のUIを作成するには、(すべての自動リリースされたオブジェクトを除いて)コード化した方法が好ましい方法だと思います。

+0

は自動解放することが好ましい解放されていますか?何故ですか? –

+0

オブジェクトを解放するとメモリが即座に解放されますが、自動解放されたオブジェクトはプールが解放されるまで待機する必要があります。デスクトップコンピュータではこれは問題ではないかもしれませんが、iPhoneメモリの世界では限られた商品です。 WWDC '09のビデオのメモリ管理の1つは、コードの短縮形以外の理由がない場合に、このような状況で自動解放を使用することを特に推奨します。 – Lounges

+0

@Lounges iOS開発の初心者です...このタブコントローラが実際にどのように機能するか教えてください。どのようにいつビューをメモリにロードするのか、それがメモリに残る時間はどれくらいですか? –

0

カスタムUITabBarControllerのdidSelectItemメソッド内では、単純にこの呼び出しを行う必要があります

[self setSelectedViewController :[self.viewControllers objectAtIndex:0]]; 
関連する問題