web-dev-qa-db-fra.com

Effet de parallaxe iOS 7 dans mon contrôleur de vue

Je développe une application pour iOS 7 en Objective-C. J'ai un écran dans mon application avec quelques boutons et une jolie image de fond. (C'est un simple xib avec UIButtons au dessus d'un UIImageView.)

Je pensais que ce serait génial si ces boutons avaient l’effet de parallaxe que l’écran d’accueil d’IOS 7 a. Par conséquent, si vous inclinez le téléphone, vous pouvez voir l’arrière-plan.

Comment puis-je implémenter cet effet dans ma propre application?

111
Dan Fabulich

Avec iOS 7, Apple introduit UIMotionEffect pour ajouter des effets de mouvement liés à l'orientation du périphérique de l'utilisateur. Par exemple, pour émuler la parallaxe effet sur l'écran d'accueil, vous pouvez utiliser la sous-classe UIInterpolationMotionEffect , comme expliqué ici et ici , avec seulement quelques lignes de code.

Objective-C :

// Set vertical effect
UIInterpolatingMotionEffect *verticalMotionEffect = 
  [[UIInterpolatingMotionEffect alloc] 
  initWithKeyPath:@"center.y"
             type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];
verticalMotionEffect.minimumRelativeValue = @(-10);
verticalMotionEffect.maximumRelativeValue = @(10);

// Set horizontal effect 
UIInterpolatingMotionEffect *horizontalMotionEffect = 
  [[UIInterpolatingMotionEffect alloc] 
  initWithKeyPath:@"center.x"     
             type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
horizontalMotionEffect.minimumRelativeValue = @(-10);
horizontalMotionEffect.maximumRelativeValue = @(10);

// Create group to combine both
UIMotionEffectGroup *group = [UIMotionEffectGroup new];
group.motionEffects = @[horizontalMotionEffect, verticalMotionEffect];

// Add both effects to your view
[myBackgroundView addMotionEffect:group];

Swift (Merci à @Lucas):

// Set vertical effect
let verticalMotionEffect = UIInterpolatingMotionEffect(keyPath: "center.y",
type: .TiltAlongVerticalAxis)
verticalMotionEffect.minimumRelativeValue = -10
verticalMotionEffect.maximumRelativeValue = 10

// Set horizontal effect
let horizontalMotionEffect = UIInterpolatingMotionEffect(keyPath: "center.x",
    type: .TiltAlongHorizontalAxis)
horizontalMotionEffect.minimumRelativeValue = -10
horizontalMotionEffect.maximumRelativeValue = 10

// Create group to combine both
let group = UIMotionEffectGroup()
group.motionEffects = [horizontalMotionEffect, verticalMotionEffect]

// Add both effects to your view
myBackgroundView.addMotionEffect(group)

En outre, vous pouvez trouver un ensemble de bibliothèques pour simplifier cette tâche ou pour ajouter cette fonctionnalité à des versions iOS plus anciennes:

272
veducm

Traduit en Swift au cas où quelqu'un serait paresseux. Merci de voter @veducm réponse up si vous avez trouvé cela utile.

@IBOutlet var background : UIImageView!

func parallaxEffectOnBackground() {
    let relativeMotionValue = 50
    var verticalMotionEffect : UIInterpolatingMotionEffect = UIInterpolatingMotionEffect(keyPath: "center.y",
        type: .TiltAlongVerticalAxis)
    verticalMotionEffect.minimumRelativeValue = -relativeMotionValue
    verticalMotionEffect.maximumRelativeValue = relativeMotionValue

    var horizontalMotionEffect : UIInterpolatingMotionEffect = UIInterpolatingMotionEffect(keyPath: "center.x",
        type: .TiltAlongHorizontalAxis)
    horizontalMotionEffect.minimumRelativeValue = -relativeMotionValue
    horizontalMotionEffect.maximumRelativeValue = relativeMotionValue

    var group : UIMotionEffectGroup = UIMotionEffectGroup()
    group.motionEffects = [horizontalMotionEffect, verticalMotionEffect]

    self.background.addMotionEffect(group)
}
16
Lucas

La solution de @ veducm peut être un peu plus courte. UIMotionEffectGroup pour ses mouvements x et y est obsolète si vous ajoutez les effets de mouvement x et y-axis séparément.

UIInterpolatingMotionEffect *motionEffect;
motionEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x"
                                                               type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
motionEffect.minimumRelativeValue = @(-25);
motionEffect.maximumRelativeValue = @(25);
[bgView addMotionEffect:motionEffect];

motionEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y"
                                                               type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];
motionEffect.minimumRelativeValue = @(-25);
motionEffect.maximumRelativeValue = @(25);
[bgView addMotionEffect:motionEffect];
7
XOXO
const static CGFloat kCustomIOS7MotionEffectExtent = 10.0; 

- (void)applyMotionEffects:(UIView *YOUR_VIEW) {
     if (NSClassFromString(@"UIInterpolatingMotionEffect")) {
         UIInterpolatingMotionEffect *horizontalEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x"
                                                                                                        type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
         horizontalEffect.minimumRelativeValue = @(-kCustomIOS7MotionEffectExtent);
         horizontalEffect.maximumRelativeValue = @( kCustomIOS7MotionEffectExtent);
         UIInterpolatingMotionEffect *verticalEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.y"
                                                                                                      type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];
         verticalEffect.minimumRelativeValue = @(-kCustomIOS7MotionEffectExtent);
         verticalEffect.maximumRelativeValue = @( kCustomIOS7MotionEffectExtent);
         UIMotionEffectGroup *motionEffectGroup = [[UIMotionEffectGroup alloc] init];
         motionEffectGroup.motionEffects = @[horizontalEffect, verticalEffect]; 
         [YOUR_VIEW addMotionEffect:motionEffectGroup];
     }
}
6
damithH

Voici une catégorie facile à intégrer l'effet sur iOs7 +:

NSString *const centerX = @"center.x";
NSString *const centerY = @"center.y";

//#define IS_OS_7_OR_LATER    ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0)

@implementation UIView (TLMotionEffect)

- (void)addCenterMotionEffectsXYWithOffset:(CGFloat)offset {

//    if(!IS_OS_7_OR_LATER) return;
    if(floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1) return;

    UIInterpolatingMotionEffect *xAxis;
    UIInterpolatingMotionEffect *yAxis;

    xAxis = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:centerX type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
    xAxis.maximumRelativeValue = @(offset);
    xAxis.minimumRelativeValue = @(-offset);

    yAxis = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:centerY type:UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis];
    yAxis.minimumRelativeValue = @(-offset);
    yAxis.maximumRelativeValue = @(offset);

    UIMotionEffectGroup *group = [[UIMotionEffectGroup alloc] init];
    group.motionEffects = @[xAxis, yAxis];

    [self addMotionEffect:group];
}

@end

https://github.com/jvenegas/TLMotionEffect

5
Bejil

UIMotionEffect fournit une implémentation gratuite de parallaxe sur iOS 7.

http://www.teehanlax.com/blog/introduction-to-uimotioneffect/

https://github.com/michaeljbishop/NGAParallaxMotion vous permet de définir simplement l'intensité de la parallaxe.

4
Dan Fabulich

Cela aidera quelqu'un qui cherche à implémenter la parallaxe pour tableView ou collectionView.

  • tout d’abord, créez la cellule pour la vue tableau et placez-y la vue image.

  • définissez la hauteur de l'image légèrement plus que la hauteur de la cellule. si hauteur de la cellule = 160, laissez la hauteur de l'image à 200 (pour obtenir l'effet de parallaxe et modifiez-le en conséquence).

  • placez ces deux variables dans votre viewController ou dans toute classe dans laquelle votre délégué tableView est étendu

let imageHeight:CGFloat = 150.0
let OffsetSpeed: CGFloat = 25.0
  • ajoute le code suivant dans la même classe
 func scrollViewDidScroll(scrollView: UIScrollView) {
    //  print("inside scroll")

    if let visibleCells = seriesTabelView.visibleCells as? [SeriesTableViewCell] {
        for parallaxCell in visibleCells {
            var yOffset = ((seriesTabelView.contentOffset.y - parallaxCell.frame.Origin.y) / imageHeight) * OffsetSpeedTwo
            parallaxCell.offset(CGPointMake(0.0, yOffset))
        }
    }
}
  • où seriesTabelView est mon UItableview

  • et laisse maintenant aller à la cellule de cette table et ajouter le code suivant

func offset(offset: CGPoint) {
        posterImage.frame = CGRectOffset(self.posterImage.bounds, offset.x, offset.y)
    }
  • ont été posterImage est mon UIImageView

Si vous voulez implémenter ceci dans collectionView, il suffit de changer la tableView en fonction de votre variable collectionView

et c'est tout. Je ne sais pas si c'est le meilleur moyen. Mais cela fonctionne pour moi. J'espère que ça marchera pour toi aussi. et laissez-moi savoir s'il y a un problème

3
Muneef M

Vraiment barrage facile à faire alors pourquoi se réfère à un code complexe. juste l'essayer. de travail

Prenez une vue sur imageview exactement la taille de la vue d'image. Par défaut, alpha pour la vue définie sur 0.

//MARK: Scroll View Delegate methods
-(void)scrollViewDidScroll:(UIScrollView *)scrollView{

NSLog(@"X: %f Y: %f",scrollView.contentOffset.x,scrollView.contentOffset.y);

CGFloat scrollY = _mainScrollView.contentOffset.y;
CGFloat height = _alphaView.frame.size.height;

CGFloat alphaMonitor = scrollY/height;

_alphaView.alpha = alphaMonitor;
}
2
Mr.Javed Multani