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:

enter image description here

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:

enter image description here

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:

  1. status bar style same , wanted different style front view , menu;
  2. 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

Popular posts from this blog

c++ - CryptStringToBinary API behavior -

c++ - Correct method for redrawing a layered window -

java.util.scanner - How to read and add only numbers to array from a text file -