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):
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:
is there workaround enable me achieve intended behavior using presentviewcontroller? e.g., root --> view2 --> view1
what other method(s) more practical achieving desired behavior? it/they must use app delegate because in real application unavoidable.
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?)
what mean "present" view controller? functional limitations or capabilities entail beyond creating pointers between presenting , presenter? importance of leaving presenting view controller "active"?
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
Post a Comment