objective c - How can I modify PKRevealController slide-out menus to deal with iOS 7? -
i have application using pkrevealcontroller implements slide-out menu similar ones in popular facebook , gmail apps on ios. app built in xcode 5, , runs on ios 6 , ios 7. need figure out how have work sanely in both places, simple .xib hack makes okay in ios 7 makes worse in ios 6 not okay.
the code works great ios 6, status bar opaque , top view not alpha-blended status bar.
however, on ios 7, example, have created view in .xib file, here how appears running in ios 6 simulator, shown here slide out menu opened:

the same .xib file running on ios 7, when slide-out menu open, top of slide out menu's .xib content under status bar, apple said in ios 7 transition guide:

the class need modify in pkrevealcontroller presenting view controller creating , presenting contained view, contained view called pkrevealcontrollercontainerview, think. think need create kind of view hierarchy this:
[ outermost view container [ kind of blob occupy header area ] [ client view want appear way did in ios 6] ] i've been reading around, , there may simpler approaches, don't quite understand them, approaches adding properties info.plist, view controller-based status bar appearance = yes. tried did not have desired effect.
how go fixing this? have read fine guide published apple , has not provided code, general guidance page on status bar.
it's easy replicate problem, clone git repo https://github.com/pkluz/pkrevealcontroller, build , run.
the code brings pop-up view looks this:
- (void)addleftviewcontrollertohierarchy { if (self.leftviewcontroller != nil && ![self.childviewcontrollers containsobject:self.leftviewcontroller]) { [self addchildviewcontroller:self.leftviewcontroller]; self.leftviewcontainer.viewcontroller = self.leftviewcontroller; if (self.leftviewcontainer == nil) { self.leftviewcontainer = [[pkrevealcontrollercontainerview alloc] initforcontroller:self.leftviewcontroller shadow:no]; self.leftviewcontainer.autoresizingmask = [self autoresizingmaskforleftviewcontainer]; } self.leftviewcontainer.frame = [self leftviewframe]; [self.view insertsubview:self.leftviewcontainer belowsubview:self.frontviewcontainer]; [self.leftviewcontroller didmovetoparentviewcontroller:self]; } } the above invoked pkrevealcontroller.m, this:
- (void)showleftviewcontrolleranimated:(bool)animated completion:(pkdefaultcompletionhandler)completion { __weak pkrevealcontroller *weakself = self; void (^showleftviewblock)(bool finished) = ^(bool finished) { [weakself removerightviewcontrollerfromhierarchy]; [weakself addleftviewcontrollertohierarchy]; // hello left slide-out menu. .... is there better approach idea? did apple provide way make easy or trying support ios 6 , ios 7 in single codebase leave me doing hacks above i'm considering?
here, instance, ugly hack don't bother placing view underneath apple system status bar, leaving black bar @ top, no good, shows i'm modifying right area in code, @ least:
- (void)addleftviewcontrollertohierarchy { cgrect lvframe; if (self.leftviewcontroller != nil && ![self.childviewcontrollers containsobject:self.leftviewcontroller]) { [self addchildviewcontroller:self.leftviewcontroller]; self.leftviewcontainer.viewcontroller = self.leftviewcontroller; if (self.leftviewcontainer == nil) { self.leftviewcontainer = [[pkrevealcontrollercontainerview alloc] initforcontroller:self.leftviewcontroller shadow:no]; self.leftviewcontainer.autoresizingmask = [self autoresizingmaskforleftviewcontainer]; } lvframe = [self leftviewframe]; lvframe.origin.y += 20; // ugly hack demo code only! don't badly! lvframe.size.height -= 20; self.leftviewcontainer.frame = lvframe; [self.view insertsubview:self.leftviewcontainer belowsubview:self.frontviewcontainer]; [self.leftviewcontroller didmovetoparentviewcontroller:self]; } } the above hack enough, if add uiviewcontroller+pkrevealcontroller.m:
-(uistatusbarstyle)preferredstatusbarstyle{ return uistatusbarstyleblackopaque; } the above code, when added, causes following hint/warning:
category implementing method implemented primary class.
i'm including above notes show i've tried, , welcome idea of how real experts doing this.
my own modified copy of pkrevealcontroller code, including hack above, in improved form, found here: https://github.com/wpostma/pkrevealcontroller
i've been struggling pkrevealcontroller well. while i'm still looking better solutions share came until now.
my 2 problems were:
- status bar style same , wanted different style front view , menu;
- the menu view top cell (it's table view controller) showed behind status bar.
1. dynamic status bar style
first had own pkrevealcontroller subclass having custom initialiser , custom methods load new view controllers front view navigation view controller. that's not relevant now.
i used subclass implement preferredstatusbarstyle follows reveal controller can provide right style each state:
- (uistatusbarstyle)preferredstatusbarstyle { switch (self.state) { case pkrevealcontrollerfocusesleftviewcontroller: return [self.leftviewcontroller preferredstatusbarstyle]; break; case pkrevealcontrollerfocusesrightviewcontroller: return [self.rightviewcontroller preferredstatusbarstyle]; break; case pkrevealcontrollerfocusesfrontviewcontroller: return [self.frontviewcontroller preferredstatusbarstyle]; break; case pkrevealcontrollerfocusesleftviewcontrollerinpresentationmode: return [self.leftviewcontroller preferredstatusbarstyle]; break; case pkrevealcontrollerfocusesrightviewcontrollerinpresentationmode: return [self.rightviewcontroller preferredstatusbarstyle]; break; default: return uistatusbarstyledefault; break; } } this alone doesn't work however. still have status bar style needs change setneedsstatusbarappearanceupdate. apple says should called inside animation loop , can find 1 in pkrevealcontroller's setfrontviewframelinearly method. how looks after i've modified it:
- (void)setfrontviewframelinearly:(cgrect)frame animated:(bool)animated duration:(cgfloat)duration options:(uiviewanimationoptions)options completion:(pkdefaultcompletionhandler)completion { [uiview animatewithduration:duration delay:0.0f options:options animations:^ { self.frontviewcontainer.frame = frame; if ([[[uidevice currentdevice] systemversion] compare:@"7.0" options:nsnumericsearch] != nsorderedascending) { [self setneedsstatusbarappearanceupdate]; } } completion:^(bool finished) { safelyexecutecompletionblockonmainthread(completion, finished); }]; } if try out @ point styles mixed up. can conclude time preferredstatusbarstyle called reveal controller state still not changed. go every method sets state, e.g. enterpresentationmodeforrightviewcontrolleranimated , set state before calls change frame (the 1 going trigger animation loop). did in 5 different places.
2. left/right menu inset
for 1 have used workaround: i've set header view on table view (tableheaderview property).
put in viewdidload of uitableviewcontroller:
uiview *headerview = [[uiview alloc] initwithframe:cgrectmake(0.f, 0.f, self.tableview.frame.size.width, 20.f)]; headerview.backgroundcolor = [uicolor whitecolor]; self.tableview.tableheaderview = headerview; don't forget add condition doesn't executed in ios 6. use this other answer know how it.
Comments
Post a Comment