web-dev-qa-db-fra.com

la vue iOS 7 avec un contenu transparent chevauche la vue précédente

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.rootViewContro‌​ller = 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];
34
Edvardas

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.

15
snoersnoer

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];
}
18
Alexandre

Je l'ai corrigé en faisant ceci lors de l'initialisation de la vue:

self.view.clipsToBounds = YES;
6
Enrico Susatyo

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/

4
John Jacecko

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

1
giuseppe

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.

1
Kevin

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"]];
1
user3010978

Des accessoires pour @snoersnoer. 


Voici le code dans Swift 3.

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é.

0
Brandon A

Jetez un coup d'œil à la catégorie UINavigationController de ce message (le problème m'a résolu)

https://stackoverflow.com/a/18882232/2826409

0
Eran Katsav