HYBControllerTransitions是自定义围场动画API封装类库,使用简便。使用者不须要了解太多转场动画知识,便可轻松接入项目使用。spring
这是一个给开发者们提供自定义push、pop、dismiss和present转场动画的开源组件。如今库中支持泡泡放大缩小围场、模态半屏转场和移动切换转场(KeyNote某转场效果)。对于开发者们来讲,这是一个很不错的开源库。开发者不须要了解转场知识,只须要简单一个API就能够实现对应的功能。闭包
若是想要更深刻地学习,请在源码中查看对应的注释说明!less
在设计此类库时,但愿以最简洁的API来实现转场功能。若是不懂任何转场知识的人,也能轻松使用,那才算达到目标。ide
所以,若是您没有学习过相关转场方面的知识,请不要担忧,这个类库不须要您掌握太多转场的知识,只须要懂基本的OC语法便可轻松接入项目使用。函数
公共的属性及API都封装在HYBBaseTransition类型中,它遵照了须要实现转场的全部协议并实现之。若是目前类库中所提供的效果不知足您的需求,您能够直接继承于HYBBaseTransition于实现您但愿获得的效果。布局
默认转场动画使用的不是弹簧动画效果,若是以为弹簧动画效果更佳,仅须要设置为YES便可。学习
1
2
3
4
5
6
7
|
/**
* Default is NO, if set to YES, it will be presented and dismissed with
* spring animation.
*/
@property (nonatomic, assign) BOOL animatedWithSpring;
|
固然,使用到弹簧天然须要设置其参数。不过做者都提供有默认值,都是通过调试过获得的值。若是以为默认值所获得的效果不够好,请自行调整参数:动画
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
/**
* The initial Spring velocity, Only when animatedWithSpring is YES, it will take effect.
* Default is 1.0 / 0.5. If you don't know, just use the default value.
*/
@property (nonatomic, assign) CGFloat initialSpringVelocity;
/**
* The Spring damp, Only when animatedWithSpring is YES, it will take effect.
*
* Default is 0.5. If you don't know, just use the default value.
*/
@property (nonatomic, assign) CGFloat damp;
|
目前所支持的动画效果有如下:this
present时,以泡泡圆形放大;dismiss时,以泡泡圆形缩小至起点。当须要实现此转场效果时,请使用HYBBubbleTransition类型。效果图以下:atom
使用起来很是简单,只须要一个API且只在一处调用便可。好比,如今有HYBModalBubbleViewController,它有一个点击事件,在点击后会回调onPresent函数,而后配置以下便可实现转场:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
- (void)onPresent {
HYBBubbleFromBottomController *vc = [[HYBBubbleFromBottomController alloc] init];
vc.modalPresentationStyle = UIModalPresentationCustom;
// Remember to own it strongly
// Because delegate is weak reference, and it will be released after out of the function body.
self.bubbleTransition = [[HYBBubbleTransition alloc] initWithPresented:^(UIViewController *presented, UIViewController *presenting, UIViewController *source, HYBBaseTransition *transition) {
// You need to cast type to the real subclass type.
HYBBubbleTransition *bubble = (HYBBubbleTransition *)transition;
// If you want to use Spring animation, set to YES.
// Default is NO.
// bubble.animatedWithSpring = YES;
bubble.bubbleColor = presented.view.backgroundColor;
// 因为一个控制器有导航,一个没有,致使会有64的偏差,因此要记得处理这种状况
CGPoint center = [self.view viewWithTag:1010].center;
center.y += 64;
bubble.bubbleStartPoint = center;
} dismissed:^(UIViewController *dismissed, HYBBaseTransition *transition) {
// Do nothing and it is ok here.
// If you really want to do something, here you can set the mode.
// But inside the super class, it is set to be automally.
// So you do this has no meaning.
transition.transitionMode = kHYBTransitionDismiss;
}];
vc.transitioningDelegate = self.bubbleTransition;
[self presentViewController:vc animated:YES completion:NULL];
}
|
这里会present HYBBubbleFromBottomController这个控制器类,可是HYBBubbleFromBottomController对象什么也不须要作,就能够直接实现了转场。
是否是真的很简单呢?
若是想要了解更多功能功能,请在源代码中查看类中所提供的全部公开属性,几乎都有默认值,若不须要修改,直接使用默认值就能够了。
注意事项:必定要将代理设置为对应的转场类对象。并且必定要在当前控制器强引用该转场类对象,由于设置为转场代理,只是弱使用,若是没有强引用,它就会被释放掉:
1
2
3
4
|
// 代理再也不是设置为self,而是设置为转场对象
vc.transitioningDelegate = self.bubbleTransition;
|
当须要实现半屏呈现且带缩放效果的转场动画时,可使用此HYBModalTransition类。它仅支持present/dismiss模式。它提供了更多的属性设置,稍候讲解。效果以下:
使用很是简单。假设在HYBModalHalfController有一个点击事件,点击后会回调onPresent函数,只须要在此函数中实现便可:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
- (void)onPresent {
HYBModalHalfDetailController *vc = [[HYBModalHalfDetailController alloc] init];
self.transition = [[HYBModalTransition alloc] initWithPresented:^(UIViewController *presented, UIViewController *presenting, UIViewController *source, HYBBaseTransition *transition) {
HYBModalTransition *modal = (HYBModalTransition *)transition;
modal.scale = (CGPoint){0.95, 0.95};
// If you don't specify, it will use default value
// modal.presentedHeight = 350.0;
// If you don't want to, set to YES or do no set.
modal.shouldDismissOnTap = YES;
// Default is NO, if set to YES, it will use spring animation.
modal.animatedWithSpring = YES;
// Default is YES. including navigation bar when take snapshots.
// When has navigation bar, if set to NO, it looks not so good.
// modal.scapshotIncludingNavigationBar = NO;
} dismissed:^(UIViewController *dismissed, HYBBaseTransition *transition) {
// do nothing
// 注释掉也没有关系,内部已经自动设置了。
transition.transitionMode = kHYBTransitionDismiss;
}];
vc.transitioningDelegate = self.transition;
[self presentViewController:vc animated:YES completion:NULL];
}
|
对于HYBModalHalfDetailController控制器类,什么也不须要操做。这是否是有点太过于简单了?对于dismissed这个block,其实这里彻底能够设置为nil,由于不须要作任何操做,默认就自动设置了mode。
若是当前控制器类有导航,最好仍是连导航条也一块儿生成截图,这样效果会好不少。默认就是YES。若是不但愿如此,请手动设置为N:
1
2
3
4
5
6
7
|
/**
* Whether to include navigation bar when take snapshots.
* Default is YES. If NO, it has only the presenting view.
*/
@property (nonatomic, assign) BOOL scapshotIncludingNavigationBar;
|
在弹出来以后,默认是添加了点击手势,能够自动dismiss。默认为YES,若是不但愿如此,请手动设置为NO:
1
2
3
4
5
6
7
8
|
/**
* When tap on the presenting view, should it automatically is dismissed.
*
* Default is YES.
*/
@property (nonatomic, assign) BOOL shouldDismissOnTap;
|
都提供了默认值,可是若是想要调整到一个让您满意的效果,也许这些属性就能够帮助您实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
/**
* Make the from view scale to the specified scale.
*
* Default is (0.9, 0.9)
*/
@property (nonatomic, assign) CGPoint scale;
/**
* The height for destination view to present.
*
* Default is half of destination view, it means desView.frame.size.height / 2
*/
@property (nonatomic, assign) CGFloat presentedHeight;
|
相似于KeyNote的神奇移动效果push、pop动画。效果图以下:
使用起来也是很简单的,不一样于present/dismiss模式,因为push的时候还不能获得转场过去的目标视图,好比效果图中的切换过去后看到的图片控件。在建立控制器类的时候,控件是不存在的,所以只能使用其它的办法来实现。
这里所采用的方案是经过给UIViewController添加扩展属性,如此就能够在建立UI的地方,将目标控件赋值。扩展所添加的属性为:
1
2
3
4
5
6
7
|
/**
* Set a target view to show. When push, it will transition to
* the target view. and when poped, it will pop from the target view.
*/
@property (nonatomic, strong, nonnull) UIView *hyb_toTargetView;
|
假设当前控制器类为HYBMoveViewController,它有一个collectionview,呈风格布局显示一个图片列表。当点击cell的时候,就切换(push)到HYBMoveDetailController控制器中显示更多内容。
实现以下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath {
HYBMoveDetailController *vc = [[HYBMoveDetailController alloc] init];
HYBGridModel *model = self.datasource[indexPath.item];
vc.image = model.clipedImage;
self.transition = [[HYBMoveTransition alloc] initWithPushed:^(UIViewController *fromVC, UIViewController *toVC, HYBBaseTransition *transition) {
HYBMoveTransition *move = (HYBMoveTransition *)transition;
HYBGridCell *cell = (HYBGridCell *)[collectionView cellForItemAtIndexPath:indexPath];
move.targetClickedView = cell.imageView;
move.animatedWithSpring = YES;
} poped:^(UIViewController *fromVC, UIViewController *toVC, HYBBaseTransition *transition) {
// Do nothing, unless you really need to.
}];
self.navigationController.delegate = self.transition;
[self.navigationController pushViewController:vc animated:YES];
}
|
在点击的时候,须要建立一个转场对象,而后咱们将导航类的代理设置为这个转场对象,以下:
1
2
3
|
self.navigationController.delegate = self.transition;
|
这样就能够实现内部自动处理了。当push的时候,会回调pushed闭包,在这里返回了转场对象,须要提供相关属性设置,才能实现。必定要传targetClickedView属性,这是被点击的控件,也是用于切换效果用的。
注意:若是导航的代理原来是其它类对象持有,在poded闭包中应该要设置成原来的导航代理。
在HYBMoveDetailController控制器中,在viewDidLoad这里建立UI的地方,建立了一个图片控件,而后如些设置:
1
2
3
4
|
// You must specify a target view with this.
self.hyb_toTargetView = imgView;
|
OK,到此就实现好功能了!
是否足够简单?
支持pod,可直接使用pod添加如下代码到Podfile中:
1
2
3
|
pod 'HYBControllerTransitions', '~> 1.0.0'
|
若是您的工程不支持Pod,呆直接将HYBControllerTransitions目录放到您的工程中便可!
使用pod来安装