我正在为Objective-C开发iOS 7应用程序。我的应用程序中有一个屏幕,带有几个按钮和漂亮的背景图像。 (这是一个简单的xib,UIButtons
上有UIImageView
。)
我觉得如果这些按钮具有iOS 7主屏幕的视差效果会很酷,所以如果你倾斜手机就可以看到背景。
如何在我自己的应用中实现该效果?
答案 0 :(得分:272)
借助iOS 7,Apple推出了UIMotionEffect
来添加与用户设备方向相关的动作效果。例如,要模拟主屏幕上的视差效果,您可以使用子类UIInterpolationMotionEffect
,如here和here所述,只需几行代码。
<强>目标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)
此外,您可以找到一堆库来更轻松地执行此操作或将此功能添加到较旧的iOS版本中:
答案 1 :(得分:16)
如果有人懒惰,请翻译成swift。如果您发现这个有用的
,请投票@veducm answer@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)
}
答案 2 :(得分:7)
@ veducm的解决方案可以缩短一点。如果分别添加x轴和y轴motionEffects,则其x和y运动的UIMotionEffectGroup已过时。
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];
答案 3 :(得分:6)
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];
}
}
答案 4 :(得分:5)
这是一个将效果整合到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
答案 5 :(得分:4)
UIMotionEffect在iOS 7上提供了一个免费的视差实现。
http://www.teehanlax.com/blog/introduction-to-uimotioneffect/
https://github.com/michaeljbishop/NGAParallaxMotion可让您设置视差强度。
答案 6 :(得分:3)
这将有助于那些希望为tableView或collectionView实现视差的人。
首先为tableview创建单元格并将图像视图放入其中。
将图像高度设置为略高于单元格高度。如果单元格高度= 160,则让图像高度为200(以产生视差效果,您可以相应地更改它)
将这两个变量放在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更改为collectionView变量
就是这样。我不确定这是不是最好的方法。但它对我有用。希望它也适合你。并告诉我是否有任何问题
答案 7 :(得分:2)
真的很容易 这样做为什么会引用复杂的代码。就试一试吧。的工作强>
在imageview上查看图像视图的大小。 默认为视图集0的alpha。
//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;
}
答案 8 :(得分:-1)
迅速翻译:
// 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)