父老鄉(xiāng)親們,我葫蘆娃又回來了~
今天我們來侃一侃tabBarItem中動畫的另一種實現(xiàn)方式;
前幾日學習項目,需要給tabBarItem添加一個類似彈簧效果的動畫,原作者的思路是自定義了幾個View填充了tabBar
,給這些View設置了手勢監(jiān)聽來實現(xiàn)動畫效果,代碼非常繁瑣,如果只是簡單的讓tabBarItem實現(xiàn)需求的動畫,我嘗試著有沒有更簡單的方法來做;原項目的效果如下:
動畫的實現(xiàn),本質來講就是拿到需要實現(xiàn)動畫的UIView
,然后把需求動畫添加到它的layer上就可以了;
我們現(xiàn)在的目的就是拿到TabBar
上對應的控件,把對應的動畫添加上去;這樣就可以既使用系統(tǒng)的tabBar原有的功能,又添加了動畫;
假定我現(xiàn)在的需求是只給tabBarItem中的image添加一個彈簧效果;
- 自定義tabBar
- 在自定義的tabBar中拿到點擊控件,添加點擊的監(jiān)聽事件
- 在監(jiān)聽事件中把動畫添加到動畫控件的layer上
(1) 由于tabBar
是tabBarController
的只讀屬性,因此我們用KVC來設置
- (void)viewDidLoad {
[super viewDidLoad];
//使用KVC來進行設置
FGTabBar *myTabBar = [[FGTabBaralloc] init];
[selfsetValue:myTabBar forKey:@"tabBar"];
}
(2) 在自定義的tabBar
中,嘗試從tabBar
的子控件中下手;
- (void)layoutSubviews
{
[super layoutSubviews];
NSLog(@"%@",self.subviews);
}
打印結果如下:
"<_UITabBarBackgroundView: 0x7fddb21236e0; frame = (0 0; 375 49); autoresize = W; userInteractionEnabled = NO; layer = <CALayer: 0x7fddb21297d0>>",
"<UITabBarButton: 0x7fddb23bb500; frame = (2 1; 90 48); opaque = NO; layer = <CALayer: 0x7fddb2130880>>",
"<UITabBarButton: 0x7fddb217e1a0; frame = (96 1; 90 48); opaque = NO; layer = <CALayer: 0x7fddb217eec0>>",
"<UITabBarButton: 0x7fddb2184700; frame = (190 1; 89 48); opaque = NO; layer = <CALayer: 0x7fddb2184e20>>",
"<UITabBarButton: 0x7fddb21893c0; frame = (283 1; 90 48); opaque = NO; layer = <CALayer: 0x7fddb2189b60>>",
"<UIImageView: 0x7fddb217ea70; frame = (0 -0.5; 375 0.5); autoresize = W; userInteractionEnabled = NO; layer = <CALayer: 0x7fddb219fa40>>"
中間的四個子控件就是tabBarItem中對應的每個按鈕(到這里就可以類比UIButton
的思想來繼續(xù)了),它有沒有可能也是繼承自UIControl
的一種按鈕類型?
在layoutSubviews
中添加下面的代碼:
for (UIView *tabBarButton in self.subviews) {
if ([tabBarButton isKindOfClass:NSClassFromString(@"UITabBarButton")]) { // 之所以這么寫是因為UITabBarButton是蘋果私有API
NSLog(@"%@",tabBarButton.superclass);
}
}
打印出的結果不出所料正是UIControl
,那么就可以添加addTarget
的監(jiān)聽方法;
(3) 由于需求只是讓tabBarButton上的圖片進行動畫,因此我們通過打印tabBarButton的子控件,可以找到其中展示圖片的imageView,把動畫添加到這個imageView的layer上就可以了;打印結果如下:
"<UITabBarSwappableImageView: 0x7fd7ebc52760; frame = (32 5.5; 25 25); opaque = NO; userInteractionEnabled = NO; tintColor = UIDeviceWhiteColorSpace 0.572549 1; layer = <CALayer: 0x7fd7ebc52940>>",
"<UITabBarButtonLabel: 0x7fd7ebc4f360; frame = (29.5 35; 30 12); text = '\U8d2d\U7269\U8f66'; opaque = NO; userInteractionEnabled = NO; layer = <_UILabelLayer: 0x7fd7ebc4e090>>"
在監(jiān)聽的方法中,通過與第(2)步類似的步驟,拿到這個ImageView,添加動畫就可以了;當然也可以給label添加動畫,也可以給整個tabBarButton添加動畫;
完整的代碼如下:
- (void)layoutSubviews{
[super layoutSubviews];
for (UIControl *tabBarButton in self.subviews) {
if ([tabBarButton isKindOfClass:NSClassFromString(@"UITabBarButton")]) {
[tabBarButton addTarget:selfaction:@selector(tabBarButtonClick:) forControlEvents:UIControlEventTouchUpInside];
}
}
}
- (void)tabBarButtonClick:(UIControl *)tabBarButton
{
for (UIView *imageView in tabBarButton.subviews) {
if ([imageView isKindOfClass:NSClassFromString(@"UITabBarSwappableImageView")]) {
//需要實現(xiàn)的幀動畫,這里根據需求自定義
CAKeyframeAnimation *animation = [CAKeyframeAnimationanimation];
animation.keyPath = @"transform.scale";
animation.values = @[@1.0,@1.3,@0.9,@1.15,@0.95,@1.02,@1.0];
animation.duration = 1;
animation.calculationMode = kCAAnimationCubic;
//把動畫添加上去就OK了
[imageView.layeraddAnimation:animation forKey:nil];
}
}
}
最后實現(xiàn)的效果如下:
總結
因此,如果以后只是單純的實現(xiàn)tabBarItem上的動畫,不需要對tabBar進行大刀闊斧的改動,也可以嘗試用這種方法來做;
今天就先侃到這里了,小弟只是拋磚引玉,大家有建議的話可以留言給我,共同玩耍于iOS樂園;
散了散了,回家收衣服了~