[TOC]

UIMotionEffect实现效果

UIMotionEffect(运动效果)

UIMotionEffect是iOS7.0推出的API。

作用:根据设备运动角度来改变对应UIView的属性,从而实现动态效果。

API介绍


@interface UIMotionEffect : NSObject <NSCopying, NSCoding>
   @interface UIInterpolatingMotionEffect : UIMotionEffect
   @interface UIMotionEffectGroup : UIMotionEffect

UIMotionEffect 抽象类;直接继承自NSObject,支持了NSCopying和NSCoding protocol。
只提供了一个子类必须override的方法。
这个方法的输入参数只有一个,观察者角度的偏移。
这个方法的输出则是一个灵活的NSDictionary对象,里面包含了最终影响视差效果的各项属性和对应的值。

@interface UIMotionEffect : NSObject <NSCopying, NSCoding>

- (instancetype)init;
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder;

//子类重写的方法:
- (nullable NSDictionary<NSString *, id> *)keyPathsAndRelativeValuesForViewerOffset:(UIOffset)viewerOffset;
//e.g.
 return value: @{ @"center": [NSValue valueFromCGPoint:CGPointMake(3.4, 1.2)],
                  @"layer.shadowOffset.x": @(-1.1)
                }

@end


实际操作中,我们主要使用子类:
  1.系统提供的子类
  2.自定义子类

//---------------------------------------------------------------------

@interface UIInterpolatingMotionEffect : UIMotionEffect

- (instancetype)initWithKeyPath:(NSString *)keyPath type:(UIInterpolatingMotionEffectType)type;
- (nullable instancetype)initWithCoder:(NSCoder *)aDecoder;

//有4个property:
@property (readonly, nonatomic) NSString *keyPath; //左右翻转屏幕将要影响到的属性,比如center.x
@property (readonly, nonatomic) UIInterpolatingMotionEffectType type; //观察者视角,也就是屏幕倾斜的方式
      typedef NS_ENUM(NSInteger, UIInterpolatingMotionEffectType) {
          UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis, //水平
          UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis //垂直
      };

@property (nullable, strong, nonatomic) id minimumRelativeValue; //keyPath对应的值的变化范围 最小值
@property (nullable, strong, nonatomic) id maximumRelativeValue; //keyPath对应的值的变化范围 最大值

@end


//---------------------------------------------------------------------
@interface UIMotionEffectGroup : UIMotionEffect

@property (nullable, copy, nonatomic) NSArray<__kindof UIMotionEffect *> *motionEffects;

@end

实践

1.直接使用子类:UIInterpolatingMotionEffect

self.imgv = [[UIImageView alloc] initWithFrame:CGRectMake(10, 100, 300, 300)];
self.imgv.backgroundColor = [UIColor orangeColor];
self.imgv.image = [UIImage imageNamed:@"pikaqiu.jpg"];
[self.view addSubview:self.imgv];


//直接使用子类:UIInterpolatingMotionEffect
UIInterpolatingMotionEffect * xEffect = [[UIInterpolatingMotionEffect alloc] initWithKeyPath:@"center.x" type:UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis];
xEffect.minimumRelativeValue =  [NSNumber numberWithFloat:-40.0];
xEffect.maximumRelativeValue = [NSNumber numberWithFloat:40.0];
[self.view addMotionEffect:xEffect];

2.自定义类: 继承UIMotionEffect

//重写这个方法
- (NSDictionary *)keyPathsAndRelativeValuesForViewerOffset:(UIOffset)viewerOffset
{
    CGFloat originalOffset = viewerOffset.horizontal ;
    CGFloat targetOffset = 512 * originalOffset;
    return @{@"center.y": @(targetOffset)};
}


Swift

public class MyMotionEffect:UIMotionEffect {
    override public func keyPathsAndRelativeValuesForViewerOffset(viewerOffset: UIOffset) -> [String : AnyObject]? {
        //打印设备水平角度
        NSLog("x:%f,y:%f", viewerOffset.horizontal,viewerOffset.vertical)
        //返回对象是一个字典类型,key是修改UIView的键路径,value是修改的值
        return ["center.y":fabs(viewerOffset.horizontal*1000)]
    }
}

//e.g.
  myView = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 300))
    myView.backgroundColor = UIColor.redColor()
    view.addSubview(myView)

    myMotionEffect = MyMotionEffect()
    myView.addMotionEffect(myMotionEffect)

results matching ""

    No results matching ""