Récemment, j'ai mis à jour mon projet xcode pour qu'il fonctionne avec iOS 7, mais j'ai rencontré un gros problème. Comme toute mon application n'a qu'une image d'arrière-plan (UIImageView ajouté à la fenêtre de clé) et que toutes les vues sont transparentes, je rencontre un problème lorsque je pousse UIViewController, car le contrôleur de vue poussé chevauche la vue précédente (vous pouvez le voir dans l'image ici: http : //grab.by/qp0k ). Je peux prédire que cela est dû au fait que la transition Push dans iOS 7 a été modifiée, car elle effectue maintenant un demi-écran. Peut-être que quelqu'un sait comment résoudre ce problème?
C’est comme cela que je règle mes fenêtres clés
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
UIImageView *background = [[UIImageView alloc]initWithFrame:[[UIScreen mainScreen] bounds]];
background.image = [UIImage imageNamed:@"background.png"];
UINavigationController *navi = [[UINavigationController alloc]initWithRootViewController:self.viewController];
self.window.rootViewController = navi;
[self.window makeKeyAndVisible];
Ensuite, lorsque l'utilisateur clique sur le bouton "Démarrer l'entraînement", j'appuie comme toujours sur la vue suivante:
workoutView *w = [[workoutView alloc]initWithNibName:@"workoutView" bundle:nil];
[self.navigationController pushViewController:w animated:YES];
J'ai résolu le problème en implémentant la nouvelle méthode UINavigationControllerDelegate
, animationControllerForOperation
.
Par exemple:
- (id<UIViewControllerAnimatedTransitioning>)navigationController:(UINavigationController *)navigationController
animationControllerForOperation:(UINavigationControllerOperation)operation
fromViewController:(UIViewController *)fromVC
toViewController:(UIViewController *)toVC
{
PushTransition* transition = [PushTransition new];
[transition setNavigationControllerOperation: operation];
return transition;
}
PushTransition est une classe qui implémente le protocole UIViewControllerAnimatedTransitioning
et les deux méthodes transitionDuration et animateTransition à partir de ce protocole. De plus, j'ai ajouté une propriété pour passer l'opération (m'indique s'il s'agit d'une transition Push ou Pop).
Il suffit de mettre le code d'animation pour déplacer les vues dans animateTransition comme suit:
// the containerView is the superview during the animation process.
UIView *container = transitionContext.containerView;
UIViewController *fromVC = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey];
UIViewController *toVC = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey];
UIView *fromView = fromVC.view;
UIView *toView = toVC.view;
CGFloat containerWidth = container.frame.size.width;
// Set the needed frames to animate.
CGRect toInitialFrame = [container frame];
CGRect fromDestinationFrame = fromView.frame;
if ([self navigationControllerOperation] == UINavigationControllerOperationPush)
{
toInitialFrame.Origin.x = containerWidth;
toView.frame = toInitialFrame;
fromDestinationFrame.Origin.x = -containerWidth;
}
else if ([self navigationControllerOperation] == UINavigationControllerOperationPop)
{
toInitialFrame.Origin.x = -containerWidth;
toView.frame = toInitialFrame;
fromDestinationFrame.Origin.x = containerWidth;
}
// Create a screenshot of the toView.
UIView *move = [toView snapshotViewAfterScreenUpdates:YES];
move.frame = toView.frame;
[container addSubview:move];
[UIView animateWithDuration:TRANSITION_DURATION delay:0
usingSpringWithDamping:1000 initialSpringVelocity:1
options:0 animations:^{
move.frame = container.frame;
fromView.frame = fromDestinationFrame;
}
completion:^(BOOL finished) {
if (![[container subviews] containsObject:toView])
{
[container addSubview:toView];
}
toView.frame = container.frame;
[fromView removeFromSuperview];
[move removeFromSuperview];
[transitionContext completeTransition: YES];
}];
décrit et vous pouvez vous avez terminé. De plus, vous pouvez créer n'importe quelle animation Push ou pop de votre choix.
J'ai fait ça.
-(void)viewWillDisappear:(BOOL)animated{
[super viewWillDisappear:animated];
[self.view setAlpha:0];
}
N'oubliez pas de remettre l'alpha à votre retour.
- (void) viewWillAppear:(BOOL)animated{
[super viewWillAppear:animated];
[self.view setAlpha:1];
}
Je l'ai corrigé en faisant ceci lors de l'initialisation de la vue:
self.view.clipsToBounds = YES;
Vous voudrez peut-être examiner une nouvelle fonctionnalité iOS7 qui vous permettra de définir vos propres transitions UIViewController personnalisées. Recherchez dans la documentation UIViewControllerTransitioningDelegate. Aussi, voici un lien vers un article à ce sujet: http://www.doubleencore.com/2013/09/ios-7-custom-transitions/
J'ai eu le même problème. Essayez de charger votre image de fond dans la méthode init. Pour moi, cela a fonctionné (parfois): Par exemple:
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
self.view.backgroundColor = [UIColor whiteColor];
[self.imageBack setImage:[UIImage imageNamed:@"mayBack.png"]];
}
return self;
}
Cependant, vous pouviez entrevoir .. La meilleure solution que j'ai trouvée, en plus de l'implémentation du nouveau protocole de transition iOS7, est d'implémenter une catégorie et de l'utiliser à chaque fois que vous en avez besoin .. Vous pouvez trouver la réponse ici
Ah, maintenant je comprends le problème. Vous aviez raison, cela semble être dû au fait que l'ancien UIViewController n'était pas caché après la transition (en raison du nouvel effet de transition).
Il ne semble pas y avoir de méthode SDK pour contrôler ce comportement. À moins de repenser l’application pour ne pas exiger que l’arrière-plan soit statique, vous devrez probablement faire défiler votre propre navigation. OSNavigationController est une réimplémentation complète de UINavigationController qui pourrait vous aider. S'ils n'ont pas mis à jour la transition iOS 7, vous serez probablement prêt à partir. Si c'est le cas, vous pouvez toujours utiliser une version plus ancienne.
Le réglage de l'image sur la couleur d'arrière-plan a résolu le problème:
self.view.backgroundColor =
[UIColor colorWithPatternImage:[UIImage imageNamed:@"mainback.png"]];
Des accessoires pour @snoersnoer.
func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
let pushTransition = SUPushTransition()
pushTransition.navigationControllerOperation = operation
return pushTransition
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
// the containerView is the superview during the animation process.
let container = transitionContext.containerView
let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)
let toVC = transitionContext.viewController(forKey:UITransitionContextViewControllerKey.to);
if let from = fromVC,
let fromView = from.view,
let to = toVC,
let toView = to.view {
let containerWidth = container.frame.size.width
// Set the needed frames to animate.
var toInitialFrame = container.frame
var fromDestinationFrame = fromView.frame
if self.navigationControllerOperation == .Push {
toInitialFrame.Origin.x = containerWidth;
toView.frame = toInitialFrame;
fromDestinationFrame.Origin.x = -containerWidth;
}
else if self.navigationControllerOperation == .pop {
toInitialFrame.Origin.x = -containerWidth;
toView.frame = toInitialFrame;
fromDestinationFrame.Origin.x = containerWidth;
}
// Create a screenshot of the toView.
if let move = toView.snapshotView(afterScreenUpdates: true) {
move.frame = toView.frame
container.addSubview(move)
UIView.animate(withDuration: Constants.MainPage.navControllerDuration, delay: 0.0, usingSpringWithDamping: 1000, initialSpringVelocity: 1, options: .curveEaseInOut, animations: {
move.frame = container.frame;
fromView.frame = fromDestinationFrame;
}, completion: { (finished) in
if finished {
if !container.subviews.contains(toView) {
container.addSubview(toView)
}
toView.frame = container.frame
fromView.removeFromSuperview()
move.removeFromSuperview()
transitionContext.completeTransition(true)
}
})
}
}
}
À votre santé.
Jetez un coup d'œil à la catégorie UINavigationController de ce message (le problème m'a résolu)