2010-01-13 2 views
2

나는 다양한 UIViewController를 관리하는 UINavigationController를 관리하는 UITabBarController가있는 응용 프로그램을 가지고 있습니다.UITabBarController 뷰를 미리 렌더링 하시겠습니까?

3G 휴대 전화의 경우 TabBar 버튼을 통해 특정보기를 처음 볼 때 느려지지만 이후에는보기 흉합니다. 3GS 폰에서는 눈에 띄지 않습니다. 제 질문은 이러한 견해를 어떻게 미리 렌더링 할 수 있습니까? 시작시에 다른 스레드에서 loadView 함수를 호출하여 loadView 함수를 트리거하려고 시도했지만이 경우에는 아무 것도하지 않습니다.

명확성을 위해 다음 내용은 내 코드에서 간략히 요약 한 것입니다. 5 개의 뷰 컨트롤러가 있지만 2 개의 코드 만 표시합니다. poiVC는 표준 UITableViewController 하위 클래스에 불과합니다. 심지어 사용자 정의 init 또는 loadView 함수도 없습니다.

- (void)applicationDidFinishLaunching:(UIApplication *)application { 

    self.mapVC = [[MapViewController alloc] init]; 
    NavControlBar * mapNavBar = [[[NavControlBar alloc] initWithViewController:mapVC 
          withControlBar:[mapVC initBar]]autorelease]; 
    self.poiVC = [[POIViewController alloc] init]; 
    NavControlBar * poiNavBar = [[[NavControlBar alloc] initWithViewController:poiVC 
          withControlBar:[poiVC initBar]]autorelease]; 

    NSArray *tabViewControllerArray = [NSArray arrayWithObjects:mapNavBar, poiNavBar, nil]; 
    self.tbc.viewControllers = tabViewControllerArray; 
    self.tbc.delegate = self; 

    [mapVC release]; 
    [poiVC release]; 
    [window addSubview:tbc.view]; 

} 사용자가 첫 화면을보고있는 동안

은 내가 poiVC 렌더링을받을 수 있으므로 전환이 빠른 것?

+0

왜 당신은 명시 적으로 작성하는 탐색 모음을 ? 왜 네비게이션 바를 관리하기 위해 뷰 컨트롤러에서 navigationItem을 사용하지 않는 것이 좋을까요? 그것은 문제의 일부일 수 있습니다. (그리고 NavControlBar는 무엇입니까?) – Nimrod

+0

NavControlBars는 사용자 정의보기에서 UIBarButtonItems를 사용하는 방법을 이해하기 전에 UINavigationBar에 임의의 요소를 추가하기 위해 만든 바보 같은 클래스입니다. 다음은 클래스의 github 저장소입니다. http://github.com/andrewljohnson/NavControlBar. 그게 문제라고 생각하지 않습니다 ... 일반 navigationController를 사용하더라도 화면에 처음 표시 될 때까지 뷰가 렌더링되지 않으며 첫 번째로드에서 약간의 지연이 계속 표시됩니다. –

답변

2
[self.mapVC view]; 
[self.poiVC view]; 

단순히보기 컨트롤러의보기를 요청할 수 있으며 아무 것도하지 않을 수 있습니다. 이렇게하면 뷰가 반환되므로 필요한 경우로드 할 수 있습니다. 단점은 물론 시작 시간을 늘리는 것입니다. 또한 메모리가 부족할 때보기가 언로드 될 수 있으므로 탭으로 전환 할 때 다시 느리게 들리지만 (적어도 시도하려면) 앱을 계속 실행 (일반적으로 좋은 것으로 간주)하려고합니다.

+0

전에 다음을 시도했습니다. self.mapVC.view; -이게 똑같은가요? 이것은 아무 것도하지 않습니다. –

+0

아 ... 그게 아마도'-init'을 사용했기 때문일 겁니다. 반면에 UIViewController (또는 추가 한 경우 MapViewController)에 지정된 이니셜 라이저를 사용해야합니다. 'UIViewController'의 경우 이것은'- (id) initWithNibName : (NSString *) nibName 번들 : (NSBundle *) nibBundle'입니다. –

+1

인터페이스 빌더를 사용하지 않습니다 ... 그리고 내 init 함수는 [super init]을 호출합니다. 이게 정확하지 않니? –

1

저는 같은 문제로 고심하고 있습니다. 내가 본 모든 대답은 viewController.view으로 전화를 걸어 미리보기를 시도하는 것에 대한 이야기이지만 주 병목 현상이 아니며 기껏해야 몇 백 밀리 초만 저장합니다. 실제 렌더링 작업의 대부분은 viewWillAppearviewDidAppear 사이에서 발생하므로 초기 전환 중에 지연을 피하려면 렌더링을 트리거해야합니다.

이렇게하려면 기본 뷰 내에 뷰 컨트롤러를 하위 뷰 컨트롤러로 추가해야합니다. 이 작업을 수행 할 수있는 가장 좋은 장소는 주보기 컨트롤러의 콜백 viewDidAppear입니다. 주보기 로딩 속도가 느려지지 않기 때문입니다. 그리고 주 스레드에서 하위 뷰를로드하고 추가하더라도 UI를 차단하지 않는 것 같습니다. (I는 배경 비디오 재생이있는보기에서 테스트했습니다.)

여기 좀보기 컨트롤러 사전 렌더링하기 위해 작성한 스위프트 코드입니다 :

enum ViewPreloadingState { 
    case Pending, Preloading, Loaded 
} 
var viewPreloadingState = ViewPreloadingState.Pending 

override func viewDidAppear(animated: Bool) { 
    super.viewDidAppear(animated) 

    if viewPreloadingState == .Pending { 
     viewPreloadingState = .Preloading 

     addChildViewController(loginViewController) 
     view.addSubview(loginViewController.view) 
     loginViewController.didMoveToParentViewController(self) 

     addChildViewController(signupViewController) 
     view.addSubview(signupViewController.view) 
     signupViewController.didMoveToParentViewController(self) 

     // Place view controllers off screen 
     let f = view.frame, 
      offScreenFrame = CGRect(x: f.width, y: 0, width: f.width, height: f.height) 
     loginViewController.view.frame = offScreenFrame 
     signupViewController.view.frame = offScreenFrame 
    } 
} 

override func viewDidLayoutSubviews() { 
    super.viewDidLayoutSubviews() 

    if viewPreloadingState == .Preloading { 
     viewPreloadingState = .Loaded 

     loginViewController.willMoveToParentViewController(nil) 
     loginViewController.view.removeFromSuperview() 
     loginViewController.removeFromParentViewController() 

     signupViewController.willMoveToParentViewController(nil) 
     signupViewController.view.removeFromSuperview() 
     signupViewController.removeFromParentViewController() 
    } 
} 
관련 문제