前几天看到Google Design guidelines - Components - Bottom(点击文字跳转,可能要翻墙)上的TabBar动画,试着写了一下,比较简陋,仅供娱乐,
Github搜索 ZHTabBarAimation
效果
缩放
位移
实现思路
比较简单的实现方法,缩放就是在tabBarButton的点击方法中对self.imageView 和 self.titleLabel执行缩放动画。
位移动画,在每次选中tabBarButton时以动画的形式改变button的frame,同时对tabBar中所有的button的imageView和titleLabel重新布局,可以在button的layoutSubViews方法里执行,且不需要添加动画,因为button自己已经在执行动画了。
关键代码
项目中用到了自定UITabBar,继承自UIView。另外还有通过模型设置tabBarButton的子控件值,具体的实现方法百度谷歌一大堆,这里不写了。这里只贴出和动画部分相关的代码。
缩放动画
ZHTabBarButton.m
// 在button的seSelected方法中调用
- (void)selectedScaleAnimation:(BOOL)selected
{
[UIView animateWithDuration:0.3 animations:^{
if (selected) {
self.imageView.transform = CGAffineTransformMakeScale(1.1, 1.1);
self.titleLabel.transform = CGAffineTransformMakeScale(1.1, 1.1);
self.titleLabel.font = [UIFont boldSystemFontOfSize:12];
} else {
self.imageView.transform = CGAffineTransformIdentity;
self.titleLabel.transform = CGAffineTransformIdentity;
self.titleLabel.font = [UIFont systemFontOfSize:12];
}
}];
}
位移动画
// ZHTabBar.m
// 以动画的方式布局所有button
- (void)layoutSubviewsAnimated:(BOOL)animated
{
// 计算每个tabBarButton的frame
CGFloat w = self.bounds.size.width;
CGFloat h = self.bounds.size.height;
CGFloat btnX = 0;
CGFloat btnW = w / self.buttons.count;
CGFloat minW = w / (self.buttons.count + 0.5);
ZHTabBarButton *lastView = nil;
for (ZHTabBarButton *subView in self.buttons) {
if (_style == ZHTabBarAnimationStyleTranslation) {
btnW = subView.isSelected ? minW * 1.5 : minW;
}
btnX = CGRectGetMaxX(lastView.frame);
// 被点击的按钮宽度变大,其他变小
if (animated) {
[UIView animateWithDuration:0.3 animations:^{
subView.frame = CGRectMake(btnX, 0, btnW, h);
}];
} else {
subView.frame = CGRectMake(btnX, 0, btnW, h);
}
lastView = subView;
}
}
// button点击事件
- (void)buttonClick:(UIButton *)button
{
// 代理方法
if ([_delegate respondsToSelector:@selector(tabBar:didSelectedItemFrom:to:)]) {
[_delegate tabBar:self didSelectedItemFrom:self.selectedButton.tag to:button.tag];
}
_selectedButton.selected = NO;
button.selected = YES;
_selectedButton = button;
// 每次点击按钮,重新布局
[self layoutSubviewsAnimated:YES];
}
ZHTabBarButton.m
// 重写来自定义布局
- (void)layoutSubviews
{
[super layoutSubviews];
CGFloat imageRatio = 0.7;
CGFloat imgX = 0;
CGFloat imgY = 0;
CGFloat imgW = CGRectGetWidth(self.frame);
CGFloat imgH = (self.isSelected || _isShowTitle) ? CGRectGetHeight(self.frame) * imageRatio : CGRectGetHeight(self.frame);
self.imageView.frame = CGRectMake(imgX, imgY, imgW, imgH);
CGFloat ttlY = CGRectGetHeight(self.frame) * imageRatio;
CGFloat ttlW = CGRectGetWidth(self.frame);
CGFloat ttlH = CGRectGetHeight(self.frame) * 0.2;
if (_isShowTitle) {
self.titleLabel.frame = CGRectMake(0, 0, ttlW, ttlH);
}
self.titleLabel.center = CGPointMake(ttlW/2.f, ttlY + ttlH/2.f);
// 显隐动画
[UIView animateWithDuration:0.3 animations:^{
self.titleLabel.alpha = _isShowTitle || self.isSelected;
}];
}
谢谢!