2013-07-25 12 views
26

mam UIViewController nazywa RootViewController i A UIViewController nazywa NewsViewController. Chcę pokazać NewsViewController wewnątrz UIView (UIView to tylko część ekranu), którą utworzyłem wewnątrz RootViewController. Używam storyboard i moja aplikacja musi obsługiwać iOS 5 (więc nie mogę korzystać z wbudowanych segues aka pojemników z IB) kodobciążenia UIViewController wewnątrz kontenera przy użyciu widoku Storyboard

RootViewController:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    NewsViewController *news = [[NewsViewController alloc]init]; 
    news.view.frame = self.newsSection.bounds; 
    [self.newsSection addSubview:news.view]; 
    [self addChildViewController:news]; 
    // Do any additional setup after loading the view. 
} 

ja również połączony z obu UIViewControllers segue. UIView newsSection pozostanie pusty. Co robię źle?

Edit:

Działa to dla mnie jest to, że właściwym podejściem?

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; 
    NewsViewController *news = [storyboard instantiateViewControllerWithIdentifier:@"NewsViewControllerID"]; 
    news.view.frame = self.newsSection.bounds; 
    [self.newsSection addSubview:news.view]; 
    [self addChildViewController:news]; 
    [news didMoveToParentViewController:self]; 
} 
+0

Próbowano mój odpowiedź? – stosha

+0

Tak. To nie zadziałało. – Segev

Odpowiedz

41
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil]; 
    NewsViewController *news = [storyboard instantiateViewControllerWithIdentifier:@"NewsViewControllerID"]; 
    news.view.frame = self.newsSection.bounds; 
    [self.newsSection addSubview:news.view]; 
    [self addChildViewController:news]; 
    [news didMoveToParentViewController:self]; 
} 

Swift

override func viewDidLoad() { 
    super.viewDidLoad() 
    let news = self.storyboard?.instantiateViewControllerWithIdentifier("NewsViewControllerID") as! NewsViewController 
    news.view.frame = newsSection.bounds 
    newsSection.addSubview(news.view) 
    addChildViewController(news) 
    news.didMoveToParentViewController(self) 
} 

Swift> = 3:

override func viewDidLoad() { 
    super.viewDidLoad() 
    let news = self.storyboard?.instantiateViewController(withIdentifier: "NewsViewControllerID") as! NewsViewController 
    news.view.frame = newsSection.bounds 
    newsSection.addSubview(news.view) 
    addChildViewController(news) 
    news.didMove(toParentViewController: self) 
} 
+0

Świetna odpowiedź, a także uwaga: http://stackoverflow.com/a/13867671/294884 – Fattie

+1

Użyj self.storyboard w kontroler widoku zamiast go ponownie załadować. –

+0

Podjąłem decyzję, nie spodziewając się, że zrobi to dokładnie tak, jak chciałem ... ale tak było! Na początku miałem nieskończoną pętlę, ponieważ ładowałem kontroler widoku w samej klasie. Po przeniesieniu kodu do 'initWithNibName' wszystko działało świetnie. Naprawiono to, ponieważ '[storyboard instantiate ..]' wywołuje 'initWithCoder', tym samym unikając rekursywnej nieskończonej pętli. – Matthew

10

Tworzenie dziecko, podczas tworzenia głównego VC:

-(void)awakeFromNib 
{ 
    [super awakeFromNib]; 
    // Create news vc from storyboard 
    UIStoryboard* storyboard = [UIStoryboard storyboardWithName:@"YourStoryboard" bundle:nil]; 
    NewsViewController *news = [storyboard instantiateViewControllerWithIdentifier:@"News VC ID, you should set it in IB"]; 
    // Add it as a child to root 
    [self addChildViewController:news]; 
    [news didMoveToParentViewController:self]; 
    // Save it for future use 
    self.news = news; 
} 

Dodaj widok dziecka, kiedy widok roota jest tworzony:

-(void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    self.news.view.frame = self.newsSection.bounds; 
    [self.newsSection addSubview:self.news.view]; 
} 
+0

Twoje rozwiązanie zadziałało. Dzięki. Zastanawiam się, dlaczego powinienem używać awakeFromNib zamiast mojego edytowanego pytania (dodałem tam rozwiązanie tymczasowe) – Segev

+0

Na iOS <6 widok może być ładowany/rozładowywany więcej niż jeden raz, więc za każdym razem viewDidLoad jest nazywane instancją NewsViewController zostanie utworzony i dodane jako dziecko. Oczywiście możesz obsłużyć viewDidUnload i usunąć go tam, ale tworzenie mojego dziecka podczas tworzenia rodzica jest w mojej opinii lepsze. –

1

Spróbuj tego:

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" 
                bundle:nil]; 
NewsViewController *rootViewController = 
[storyboard instantiateViewControllerWithIdentifier:@"NewsViewControllerID"]; 
+0

Czy to nie będzie wyświetlać ViewController na całym ekranie? Chcę wyświetlić go tylko na części ekranu kontrolera widoku administratora. – Segev

+1

Dlaczego po prostu nie tworzysz klasy UIView zamiast UIViewcontroller? Można go dodać za pomocą metody 'addsubview:' –

0

Powinieneś przenieś swój kod do - (void) viewDidApp ucho: (BOOL) animowane jak ten

- (void) viewDidAppear: (BOOL) animated 
{ 
    [super viewDidAppear: animated]; 

    NewsViewController *news = [[NewsViewController alloc]init]; 
    news.view.frame = self.newsSection.bounds; 
    [self.newsSection addSubview:news.view]; 
    [self addChildViewController:news]; 
    // Do any additional setup after loading the view. 
} 

ponieważ ramy i granice w viewDidLoad jest {0,0} {0,0}

+0

Nie działa dla mnie. – Segev

+0

można wstawić NSLog (@ "% @", NSStringFromCGRect (self.newsSection.bounds)); po [super viewDidAppear: ...? – stosha

+0

2013-07-25 12: 54: 04.470 containerTests [6683: 11303] {{0, 0}, {320, 146}} – Segev

1

Oto podejście sposób pracował dla mnie.

Mam 3 przyciski u góry Kup, Wyprzedaż, Wypożycz. teraz przy kliknięciu dowolnego przycisku ładuję odpowiedni UIViewController i używam storyboardu.

Podałem Storyboard Id za każde UIViewController.

Dodałem dwa UIView do mojego Main ViewController, które mają te 3 przyciski (Zakup, Sprzedaż, Wynajem).

Jeden widok używam dla powyższych trzech przycisków i innych używam do ładowania UIViewController.

Teraz stukając w konkretny przycisk i dotykając konkretnego przycisku robię następujący kod.

- (IBAction)sellingClicked:(id)sender 
{   
    UIStoryboard *storyboard=[UIStoryboard storyboardWithName:@"Main" bundle:nil]; 

    TestViewController *tvc=[storyboard instantiateViewControllerWithIdentifier:@"test"]; 

    [self.viewContainer addSubview:tvc.view]; 
    [self addChildViewController:tvc];  
} 

i działa doskonale dla mnie dalej możesz dodać przewijanie Widok, który chcesz tam przewinąć.

+1

Użyj "self.storyboard" zamiast ładowania całego storyboardu. To zasysa dużo pamięci i procesora. – Andy

1
 otherController!.view.frame = container.bounds; 
     self.addChildViewController(otherController!); 
     container.addSubview(otherController!.view); 
     container.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("H:|[view]|", options: .allZeros, metrics: nil, views: ["view": otherController!.view])) 
     container.addConstraints(NSLayoutConstraint.constraintsWithVisualFormat("V:|[view]|", options: .allZeros, metrics: nil, views: ["view": otherController!.view])) 
     otherController!.didMoveToParentViewController(self); 

Nie zapomnij podać ograniczenie zwłaszcza jeśli chcesz wykonać animacje

Powiązane problemy