J'essaie de configurer un geste de balayage Edge dans iOS 8 sur iPad, mais j'obtiens une erreur qui ressemble à un bogue.
J'ai le code suivant:
UIScreenEdgePanGestureRecognizer *edgeRecognizer = [[UIScreenEdgePanGestureRecognizer alloc] initWithTarget:self action:@selector(handleRightEdgeSwipe:)];
edgeRecognizer.edges = UIRectEdgeRight;
[self.view addGestureRecognizer:edgeRecognizer];
et puis je gère le geste:
-(void)handleRightEdgeSwipe:(UIGestureRecognizer*)sender
{
//slide in view code here
}
Le problème est qu'il ne détecte pas toujours le bon balayage Edge. Et parfois, il le détecte plusieurs fois.
Qu'il détecte ou non, il affiche toujours les informations suivantes dans la console lorsque vous glissez le bon Edge sur iPad:
2014-10-07 00: 04: 40.386 Journal Office [1531: 500896] aucune fenêtre inattendue dans _UIApplicationHandleEventFromQueueEvent, _windowServerHitTestWindow:; couche =>
Que signifie ce message et comment puis-je le corriger pour que le bon balayage Edge soit détecté de manière cohérente?
Je pense que c'est un bug dans iOS, que je peux confirmer sur un iPad mini 2 et un iPad Air sur iOS 7 ou supérieur, même sur l'écran d'accueil.
Dans "Paysage de gauche" (bouton Accueil à gauche), un "geste du bord droit" de l'extérieur de l'écran ne fonctionne pas pour moi. Testez-le vous-même sur l'écran d'accueil.
J'ai signalé un bogue à Apple il y a 9 mois, mais j'ai noté que cela s'était passé.
J'ai un peu joué avec l'initialisation UIWindow et quand il est un peu plus gros qu'il ne l'est vraiment, le geste fonctionne. Bien sûr, c'est une solution horrible.
self.window = [UIWindow new];
self.window.rootViewController = [[UIViewController alloc] init];
// Real Size
CGRect frame = [UIScreen mainScreen].bounds;
// Real Size + 0.000001
self.window.frame = CGRectMake(0, 0, frame.size.width+0.000001, frame.size.height+0.000001);
[self.window makeKeyAndVisible];
J'ai le même problème. Ma solution fonctionne bien: il suffit de définir dans votre xib votre Windows comme étant masqué.
Je ne comprends pas vraiment pourquoi ça marche, mais ça marche.
EDIT 1:
J'ai trouvé une autre solution, mieux je pense, et plus compréhensible:
Mettez ce code sur votre willFinishLaunchingWithOptions, dans votre appDelegate:
- (BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
CGRect bounds = [[UIScreen mainScreen] bounds];
[self.window setFrame:bounds];
[self.window setBounds:bounds];
return YES;
}
Ensuite, sur votre didFinishLaunchingWithOptions:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Your codes...
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}
Vous pouvez ensuite définir votre objet window masqué sur NO, et cela devrait fonctionner.
J'ai eu un problème lors du test de l'application iPhone sur iPad. Pas de problème sur simulateur et pas de problème si je compile une application aussi universelle que sur iPad.
unexpected nil window in _UIApplicationHandleEventFromQueueEvent, _windowServerHitTestWindow: <UIClassicWindow: 0x1276065a0; frame = (0 0; 768 1024); userInteractionEnabled = NO; gestureRecognizers = <NSArray: 0x1740557e0>; layer = <UIWindowLayer: 0x17403fd80>>
Peut-être que l'image est mal notée? (frame = (0 0; 768 1024))
iOS 8 présente un bogue qui fait que tout contact qui commence exactement sur un iPad à droite en mode Portrait à l'envers (bouton principal en haut) ou Paysage à gauche (bouton principal en bas à gauche) ne parvient pas à être testé avec la vue correcte.
Le correctif consiste à placer la sous-classe UIWindow
dans le test correct du côté droit.
@implementation FixedWindow
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event
{
UIView* hit = [super hitTest:point withEvent:event];
if (!hit && point.x >= CGRectGetMaxX(self.bounds))
hit = [super hitTest:CGPointMake(point.x - 0.5, point.y) withEvent:event];
return hit;
}
@end
Attachez la fenêtre à votre délégué d'application via la propriété window
.
@implementation AppDelegate
- (UIWindow*)window
{
if (!_window)
_window = [[IVWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
return _window;
}
@end
Dans les modes Portrait et Paysage à droite, j'ai confirmé que les touches droites du bord sont toujours à au moins 0,5 px du bord plutôt que exactement sur le bord. Ce correctif devrait donc fonctionner de manière analogue à celle-ci.
Agrandir le cadre de la fenêtre
Notez que firebug's fix fonctionnera également en élargissant légèrement le cadre de la fenêtre pour inclure le côté droit. Toutefois:
application:willFinishLaunchingWithOptions:
ou application:didFinishLaunchingWithOptions:
, votre hiérarchie de vues ne sera pas redimensionnée en fonction du nouveau cadre et les touches droites de Edge ne parviendront pas à traverser la hiérarchie.iOS 7:
iOS 7 présente un bogue similaire en ce sens que le test de réussite échoue également, mais avec un résultat non nul et une géométrie sans rotation. Ce correctif devrait fonctionner avec iOS 7 et 8:
@implementation FixedWindow
- (UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event
{
UIView* hit = [super hitTest:point withEvent:event];
if (!hit || hit == self)
{
CGRect bounds = self.bounds;
hit = [super hitTest:CGPointMake(MIN(MAX(point.x, CGRectGetMinX(bounds) + 0.5), CGRectGetMaxX(bounds) - 0.5),
MIN(MAX(point.y, CGRectGetMinY(bounds) + 0.5), CGRectGetMaxY(bounds) - 0.5))
withEvent:event];
}
return hit;
}
@end
Une solution possible est de supprimer ou de commenter le code pour masquer la barre d'état si vous avez cela. Je tirais mes cheveux pour les résoudre et je ne pouvais les reproduire que sur ma vue racine. Il semble que si vous masquez la barre d'état, vous ne pouvez pas faire glisser les widgets/le centre de notification aujourd'hui (vous pouvez le faire avec un peu d'effort).
/* <- add this
- (BOOL)prefersStatusBarHidden
{
return YES;
}
add this -> */
C’est peut-être trop tard, mais certaines personnes en ont encore besoin, Normalement parce que vous n’avez pas fourni des images de lancement correctement dimensionnées ni un écran de lancement et/ou l’interface principale n’est pas configurée sur votre propre scénarimage chez General > Informations de déploiement
Définissez votre déploiement sur 8.x ou plus, définissez l’écran de lancement comme xib principal.
Terminé!