cocoa touch - Why isn't a registered UIDeviceOrientationDidChangeNotification always called? -
i wrote simple view controller shows modal popup dialog. because creates new window lay on entire screen, i've added uideviceorientationdidchangenotification
observer figures out how rotate view using cgaffinetransformmakerotation()
. , seems work.
mostly. downside can fiddle orientation , end sideways or upside down. check out this 18s video demonstrating issue. in debugging, appears notification doesn't fire, or @ least doesn't call callback method that's listening it.
i must missing something, though, because if @ video again, you'll notice view behind does rotate properly. 1 managed -willanimaterotationtointerfaceorientation:duration:
. how ios controller method called (presumably managed uideviceorientationdidchangenotification
observer in uiviewcontroller) own code not?
i used uiapplicationwillchangestatusbarorientationnotification
in kobo, appears trick. it's lot more reliable, because want match ui's chosen orientation, not device happens be. in other words, can let apple decide when should re-orient window.
here few snippets kobo app's popup dialog code on ipad (uialertview looks kinda dinky on ipad, richard penner wrote better one). after few glitches more recent ios versions , having display these dialogs in different situations (all around orientation iirc), had tweak sit directly inside uiwindow, meant duplicating orientation transformation logic.
this code comes uiviewcontroller view gets dropped straight onto current window.
- (void) presentdialogwindow { // register orientation change notification [[nsnotificationcenter defaultcenter] addobserver: self selector: @selector(orientationwillchange:) name: uiapplicationwillchangestatusbarorientationnotification object: nil]; [[nsnotificationcenter defaultcenter] addobserver: self selector: @selector(orientationdidchange:) name: uiapplicationdidchangestatusbarorientationnotification object: nil]; } - (void) orientationwillchange: (nsnotification *) note { uiinterfaceorientation current = [[uiapplication sharedapplication] statusbarorientation]; uiinterfaceorientation orientation = [[[note userinfo] objectforkey: uiapplicationstatusbarorientationuserinfokey] integervalue]; if ( [self shouldautorotatetointerfaceorientation: orientation] == no ) return; if ( current == orientation ) return; // direction , angle cgfloat angle = 0.0; switch ( current ) { case uiinterfaceorientationportrait: { switch ( orientation ) { case uiinterfaceorientationportraitupsidedown: angle = (cgfloat)m_pi; // 180.0*m_pi/180.0 == m_pi break; case uiinterfaceorientationlandscapeleft: angle = (cgfloat)(m_pi*-90.0)/180.0; break; case uiinterfaceorientationlandscaperight: angle = (cgfloat)(m_pi*90.0)/180.0; break; default: return; } break; } case uiinterfaceorientationportraitupsidedown: { switch ( orientation ) { case uiinterfaceorientationportrait: angle = (cgfloat)m_pi; // 180.0*m_pi/180.0 == m_pi break; case uiinterfaceorientationlandscapeleft: angle = (cgfloat)(m_pi*90.0)/180.0; break; case uiinterfaceorientationlandscaperight: angle = (cgfloat)(m_pi*-90.0)/180.0; break; default: return; } break; } case uiinterfaceorientationlandscapeleft: { switch ( orientation ) { case uiinterfaceorientationlandscaperight: angle = (cgfloat)m_pi; // 180.0*m_pi/180.0 == m_pi break; case uiinterfaceorientationportraitupsidedown: angle = (cgfloat)(m_pi*-90.0)/180.0; break; case uiinterfaceorientationportrait: angle = (cgfloat)(m_pi*90.0)/180.0; break; default: return; } break; } case uiinterfaceorientationlandscaperight: { switch ( orientation ) { case uiinterfaceorientationlandscapeleft: angle = (cgfloat)m_pi; // 180.0*m_pi/180.0 == m_pi break; case uiinterfaceorientationportrait: angle = (cgfloat)(m_pi*-90.0)/180.0; break; case uiinterfaceorientationportraitupsidedown: angle = (cgfloat)(m_pi*90.0)/180.0; break; default: return; } break; } } cgaffinetransform rotation = cgaffinetransformmakerotation( angle ); [uiview beginanimations: @"" context: null]; [uiview setanimationduration: 0.4]; self.view.transform = cgaffinetransformconcat(self.view.transform, rotation); [uiview commitanimations]; } - (void) orientationdidchange: (nsnotification *) note { uiinterfaceorientation orientation = [[[note userinfo] objectforkey: uiapplicationstatusbarorientationuserinfokey] integervalue]; if ( [self shouldautorotatetointerfaceorientation: [[uiapplication sharedapplication] statusbarorientation]] == no ) return; self.view.frame = [[uiscreen mainscreen] applicationframe]; [self didrotatefrominterfaceorientation: orientation]; }
we use loading view controller, adding view window, calling -presentmodaldialog, so:
uiview *window = [[uiapplication sharedapplication] keywindow]; [window addsubview: thecontroller.view]; [thecontroller presentdialogwindow];
i'm going make simple uiviewcontroller subclass implement fiddly bits soon, , post on github account. when do, i'll edit & link it.
Comments
Post a Comment