objective c - view controllers: presentation, dismissal -


just purpose of learning particular aspects of xcode, creating simple app has 2 functional view controllers. each contains button can pressed switch other. not using segues. using pointers retrieved app delegate.

visual illustration (click higher resolution): visual

when app loads, root view controller presents view 1. when click "switch view 2," following code causes view 2 appear:

- (ibaction)buttonpressed:(id)sender {     appdelegate *appdelegate = (appdelegate*)[[uiapplication sharedapplication] delegate];     [self presentviewcontroller:appdelegate.view2 animated:yes completion:nil]; } 

so far, good.

but when click "switch view 1" on second view, same code (replacing "view2" "view1") gives following error:

application tried present modally active controller.

so summarize (where --> = presents), have root --> view1 --> view2 -x-> view1

i don't care retaining history of presents whom. want buttons bring top (make visible) displayed view controller, maintaining state of views.

it nice know following:

  1. is there workaround enable me achieve intended behavior using presentviewcontroller? e.g., root --> view2 --> view1

  2. what other method(s) more practical achieving desired behavior? it/they must use app delegate because in real application unavoidable.

  3. am breaking rules trying put view controller on top without integrating larger architecture? e.g, sort of behavior supposed handled navigation conrollers , pushing/popping? if so, can explain why xcode doesn't want me this? why can't display whatever view controller want, without having relationship other view controllers? (maybe because lead abuse of app delegate?)

  4. what mean "present" view controller? functional limitations or capabilities entail beyond creating pointers between presenting , presenter? importance of leaving presenting view controller "active"?

  5. if instead make button on view1 send presentviewcontroller message root view (which hoped change presentation chain root --> view1 root --> view2, leaving view1 still existing in memory not part of chain), different error: "attempt present on view not in window hierarchy!" mean? can't find explanation of window hierarchy.

okay, know i'm asking lot here, amount of enlightenment appreciated!!

the correct way underlying rootvc presenting and dismissing (as attempt - without dismissing part - in point 5). can achieve sending message + completion block rootvc each of view1 , view2 when want present other.

when in view1:

- (ibaction)buttonpressed:(id)sender      appdelegate *appdelegate = (appdelegate*)[[uiapplication sharedapplication] delegate];      uiviewcontroller* presentingvc = self.presentingviewcontroller;     [presentingvc dismissviewcontrolleranimated:yes completion:^{           [presentingvc presentviewcontroller:appdelegate.view2                                       animated:yes                                     completion:nil];     }]; } 

and view2. take care need line:

        uiviewcontroller* presentingvc = self.presentingviewcontroller; 

as can't refer 'self.presentingviewcontroller' inside completion block it's controller has been dismissed @ point.

i think answers points 1 , 2.

to answer point 3 "why can't display whatever view controller want, without having relationship other view controllers?" - can (via rootviewcontroller property of window), you going have implement navigation , manage viewcontroller pointers, means end creating controller of sort. apple helping here providing few cover needs.

as regards point 4 - presenting of viewcontroller controlled presenting vc, why want keep 1 'active'. when send message: [self dismissviewcontrolleranimated:completion:], self reroutes messge it's presentingviewcontroller. if rid of presentingviewcontroller dismiss method break.

point 5 answered above. need dismiss topmost view first before asking underlying view present. note view1 "still in memory" because have retained pointer in app delegate.

update

as trying work initial launch-straight-to-view1, make bool launched property , check/set rootviewcontroller's viewdidappear:

- (void) viewdidappear:(bool)animated {     [super viewdidappear:animated];     if (!self.launched) {         self.launched = true;         appdelegate *appdelegate = (appdelegate*)[[uiapplication sharedapplication] delegate];         [self presentviewcontroller:appdelegate.view1                            animated:yes                          completion:nil];     } } 

Comments

Popular posts from this blog

c# - DetailsView in ASP.Net - How to add another column on the side/add a control in each row? -

javascript - firefox memory leak -

Trying to import CSV file to a SQL Server database using asp.net and c# - can't find what I'm missing -