Come si visualizza la vista sotto la barra verde durante una chiamata? in questo momento la mia app è parzialmente coperta dalla barra verde durante una telefonata.Come posizionare la vista sotto la barra verde durante la telefonata?
risposta
Se si' usando l'Interface Builder, assicurati che le tue maschere di autoresize siano impostate in modo che ridimensionino le viste invece di lasciarle lì sedute nella stessa posizione. È possibile utilizzare l'opzione Attiva/disattiva barra di stato di attivazione in Hardware in Simulatore per testarla.
Se non si utilizza IB, è possibile impostare le maschere di autoresize nel codice.
Se non si utilizzano le viste, è necessario ridimensionare la grafica quando si ricevono le notifiche appropriate.
Si può scoprire quando questo sta per accadere con i seguenti metodi UIApplicationDelegate:
- (void)application:(UIApplication *)application willChangeStatusBarFrame:(CGRect)newStatusBarFrame {
NSLog(@"willChangeStatusBarFrame : newSize %f, %f", newStatusBarFrame.size.width, newStatusBarFrame.size.height);
}
- (void)application:(UIApplication *)application didChangeStatusBarFrame:(CGRect)newStatusBarFrame {
NSLog(@"didChangeStatusBarFrame : newSize %f, %f", newStatusBarFrame.size.width, newStatusBarFrame.size.height);
}
In alternativa, è possibile registrarsi per una notifica nella sottoclasse UIViewController:
- (void)viewDidLoad {
[super viewDidLoad];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarFrameChanged:) name:UIApplicationDidChangeStatusBarFrameNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(statusBarFrameWillChange:) name:UIApplicationWillChangeStatusBarFrameNotification object:nil];
}
- (void)statusBarFrameWillChange:(NSNotification*)notification {
NSValue* rectValue = [[notification userInfo] valueForKey:UIApplicationStatusBarFrameUserInfoKey];
CGRect newFrame;
[rectValue getValue:&newFrame];
NSLog(@"statusBarFrameWillChange: newSize %f, %f", newFrame.size.width, newFrame.size.height);
// Move your view here ...
}
- (void)statusBarFrameChanged:(NSNotification*)notification {
NSValue* rectValue = [[notification userInfo] valueForKey:UIApplicationStatusBarFrameUserInfoKey];
CGRect oldFrame;
[rectValue getValue:&oldFrame];
NSLog(@"statusBarFrameChanged: oldSize %f, %f", oldFrame.size.width, oldFrame.size.height);
// ... or here, whichever makes the most sense for your app.
}
Si noti che i suggerimenti sopra riportati si attivano anche quando il dispositivo viene ruotato. Se vuoi solo trovare quando la barra di stato è cresciuta in altezza a causa di una chiamata in arrivo/in corso. Ho trovato il seguente codice al lavoro:
AppDelegate.m
- (void)application:(UIApplication *)application didChangeStatusBarFrame:(CGRect)oldStatusBarFrame
{
float adjustment = 0;
if ([UIApplication sharedApplication].statusBarFrame.size.height == 40)
{
adjustment = -20;
}
else if ([UIApplication sharedApplication].statusBarFrame.size.height == 20 && oldStatusBarFrame.size.height == 40)
{
adjustment = 20;
}
else
{
return;
}
CGFloat duration = [UIApplication sharedApplication].statusBarOrientationAnimationDuration;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:duration];
{YOUR VIEW Controller - remove .view if a view}.view.frame = CGRectMake({YOUR VIEW Controller}.view.frame.origin.x, {YOUR VIEW Controller}.view.frame.origin.y + adjustment, {YOUR VIEW Controller}.view.frame.size.width, {YOUR VIEW Controller}.view.frame.size.height);
[UIView commitAnimations];
}
Idem con un Tab Bar App e iOS6/7, grazie alla user1208489 s' answer.
I valori sono completamente diversi e strani per ogni iOS. ; OP
mainAppDelegate.m
- (void)application:(UIApplication *)application didChangeStatusBarFrame:(CGRect)oldStatusBarFrame
{
float vue = 0;
float barre = 0;
float hauteur = 0;
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 // pour Xcode5/SDK7
if ([UIApplication sharedApplication].statusBarFrame.size.height == 40)
{
vue = -20;
barre = +20;
}
else
if ([UIApplication sharedApplication].statusBarFrame.size.height == 20 && oldStatusBarFrame.size.height == 40)
{
vue = 0;
barre = -20;
}
else return;
#else // pour Xcode4/SDK6
if ([UIApplication sharedApplication].statusBarFrame.size.height == 40)
{
vue = +20;
hauteur = 1;
barre = -1-20;
}
else
if ([UIApplication sharedApplication].statusBarFrame.size.height == 20 && oldStatusBarFrame.size.height == 40)
{
vue = -20;
hauteur = -1;
barre = +1+20;
}
else return;
#endif
CGFloat duration = [UIApplication sharedApplication].statusBarOrientationAnimationDuration;
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:duration];
self.tabBarController.view.frame = CGRectMake(self.tabBarController.view.frame.origin.x, self.tabBarController.view.frame.origin.y + vue, self.tabBarController.view.frame.size.width, self.tabBarController.view.frame.size.height+hauteur);
self.tabBarController.tabBar.frame = CGRectMake(self.tabBarController.tabBar.frame.origin.x, self.tabBarController.tabBar.frame.origin.y + barre, self.tabBarController.tabBar.frame.size.width, self.tabBarController.tabBar.frame.size.height);
[UIView commitAnimations];
}
Testato su iPhone 4S 7.0.4 (11B554a) con Xcode 4.6.3 (4H1503) e Xcode 5.0.2 (5A3005).
È possibile utilizzare anche le estensioni UIKit in questo modo: CGRect newFrame = [rectValue CGRectValue]; - in entrambi i casi! –
Voglio solo aggiungere che NSLog e la convenzione di denominazione sono leggermente sbagliati. statusBarFrameWillChange viene chiamato prima statusBarFrameChanged in modo che la notifica da statusBarFrameWillChange sia effettivamente il valore OLD e non il nuovo valore. Viceversa con l'altro metodo. – micnguyen