我的视图控制器中的iOS 7视差效果

我正在Objective-C中为iOS 7开发一个应用程序。 我在我的应用程序中有一个屏幕,有几个button和一个漂亮的背景图片。 (这是一个简单的xib在UIImageView之上的UIButtons 。)

我在想,如果这些button具有iOS 7主屏幕的视差效果,它会很酷,所以如果你倾斜手机,你可以看到背景。

我如何在自己的应用程序中实现这种效果?

在iOS 7中,Apple引入了UIMotionEffect来添加与用户设备的方向相关的Motion效果。 例如,要在主屏幕上模拟视差效果,可以使用子类UIInterpolationMotionEffect ,如这里和这里所解释的,只需要几行代码即可。

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 (感谢@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) 

此外,你可以find一堆库来做到这一点,或者将这个function添加到旧的iOS版本:

  • NGAParallaxMotion (需要iOS 7 )。
  • DVParallaxView (需要iOS 5.0或更高版本和ARC )。
  • MKParallaxView (用iOS 6.0testing,需要ARC )。
  • UIView-MWParallax (用iOS 6.1testing,需要ARC )。

如果有人懒惰,翻译成swift。 如果您发现这个有用,请投票@veducm 答案

 @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) } 

@ veducm的解决scheme可以缩短一点。 如果分别添加x和y轴motionEffects,则UIMotionEffectGroup对于其x和y运动已过时。

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

这里是一个简单的类别来整合对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

这将帮助那些正在寻求实现tableView或collectionView的视差的人。

  • 首先为tableview创build单元格,并将图像视图放在其中。

  • 将图像高度设置为比单元格高度略高。 如果单元格高度= 160,则图像高度为200(为了产生视差效果,并且可以相应地改变它)

  • 把这两个variables放在你的viewController或者你的tableView委托被扩展的任何类中

 let imageHeight:CGFloat = 150.0 let OffsetSpeed: CGFloat = 25.0 
  • 在同一个类中添加下面的代码
  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)) } } } 
  • seriesTabelView是我的UItableView

  • 现在让我们转到这个tableView的单元格,并添加下面的代码

 func offset(offset: CGPoint) { posterImage.frame = CGRectOffset(self.posterImage.bounds, offset.x, offset.y) } 
  • 是posterImage是我的UIImageView

如果你想实现这个collectionView只是改变tableView vairable到你的collectionViewvariables

这就是它。 我不确定这是否是最好的方法。 但它适用于我。 希望它也适合你。 并让我知道是否有任何问题

真的很容易做到这一点为什么指的是复杂的代码。 去尝试一下。 加工

在imageview上查看图像视图的大小。 默认情况下alpha为视图集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; } 

迅速翻译:

 // Set vertical effect let verticalMotionEffect = UIInterpolatingMotionEffect(keyPath: "center.y", type: .TiltAlongVerticalAxis) verticalMotionEffect.minimumRelativeValue = -value verticalMotionEffect.maximumRelativeValue = value // Set vertical effect let horizontalMotionEffect = UIInterpolatingMotionEffect(keyPath: "center.x", type: .TiltAlongHorizontalAxis) verticalMotionEffect.minimumRelativeValue = -value verticalMotionEffect.maximumRelativeValue = value let group = UIMotionEffectGroup() group.motionEffects = [horizontalMotionEffect, verticalMotionEffect] self.motionEffect = group self.addMotionEffect(group)