UITabBarItem图标动画

时间:2010-08-19 08:41:41

标签: iphone animation uitabbaritem

适用于iPhone的Skype应用使用动画TabBar图标。例如,在登录期间,最右侧的选项卡图标显示循环箭头。在调用“呼叫”选项卡图标时,会轻轻地闪烁,这显然是通过动画完成的。

我想知道如何设置标签栏项目的图标动画。

在我的特殊情况下,当用户按下“收藏夹”按钮时,它会跳转到“收藏夹”标签栏项目。我已经实现了跳跃动画,但我希望相应的标签栏图标在动画结束时闪烁,以给它带来完整感。

关于我应该关注的方向的任何建议?

提前致谢。

8 个答案:

答案 0 :(得分:12)

我很惊讶解决方案有多简单!

将方法添加到包含以下例程的Application Delegate类.m文件(或管理UITabBar的任何其他类):

  1. 创建一个将用于动画的UIImageView。
  2. 使用addSubview:方法将其添加到TabBar视图中。
  3. 将其缩小为UITabBarItem的大小(使用UITabBar框架大小和标签栏项目数来计算框架大小)。
  4. 调整imageView的frame.origin.x值,将图像放在要制作动画的标签页项目正上方。
  5. 将您想要的动画添加到imageView(您可以使用不透明度,交换多个图像 - 您想要的任何内容)。
  6. 很简单,你不这么认为吗?

    您可以在UIApplicationDelegate实例上的任何位置调用此方法,以便为标签栏项目设置动画。

    同样重要的是要注意,您可以点击通过imageView选择标签栏项目,就好像标签栏上没有图像一样。如果你知道的话,可以在这里做一些有趣的结论......

答案 1 :(得分:3)

我找到了解决这个问题的更好方法。添加自定义图像视图不是更好的方法,因为在iOS 10.0及更高版本中更改图标框架和方向的方向。文字位置改变了。你只需要设置UITabBarController&的类。把以下代码。

override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {

    let index = self.tabBar.items?.index(of: item)
    let subView = tabBar.subviews[index!+1].subviews.first as! UIImageView
    self.performSpringAnimation(imgView: subView)
}

//func to perform spring animation on imageview
func performSpringAnimation(imgView: UIImageView) {

    UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {

        imgView.transform = CGAffineTransform.init(scaleX: 1.4, y: 1.4)

        //reducing the size
        UIView.animate(withDuration: 0.5, delay: 0.2, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.5, options: .curveEaseInOut, animations: {
            imgView.transform = CGAffineTransform.init(scaleX: 1, y: 1)
        }) { (flag) in
        }
    }) { (flag) in

    }
}  

答案 2 :(得分:1)

答案 3 :(得分:1)

您可以通过获取其视图为tabbar图标设置动画,然后根据需要为UIView执行任何动画。下面是一个简单的缩放变换示例,欢呼!

func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem){
        var tabBarView: [UIView] = []

        for i in tabBar.subviews {
            if i.isKind(of: NSClassFromString("UITabBarButton")! ) {
                tabBarView.append(i)
            }
        }

        if !tabBarView.isEmpty {
            UIView.animate(withDuration: 0.15, animations: {
                tabBarView[item.tag].transform = CGAffineTransform(scaleX: 1.2, y: 1.2)
            }, completion: { _ in
                UIView.animate(withDuration: 0.15) {
                    tabBarView[item.tag].transform = CGAffineTransform.identity
                }
            })
        }
    }

ps:请按顺序为每个UITabBarItem分配标签

答案 4 :(得分:0)

我还没有这样做,但我会尝试构建一个CAAnimation,例如使用CABasicAnimation并将其添加到您想要设置动画的UITabBarItem。

有关如何设置CABasicAnimation的详细信息,请参阅Core Animation Programming Guide: http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/CoreAnimation_guide/Articles/AnimatingLayers.html#//apple_ref/doc/uid/TP40006085-SW1

答案 5 :(得分:0)

请记住,UITabBar中子视图的顺序可能是无序的,因此使用here所建议的使用索引从其访问正确的项可能无法正常工作。看看这篇帖子Naresh answer

我发现的解决方案是首先对视图进行过滤和排序,然后使用tabBarItem的正确索引对其进行访问。

null

答案 6 :(得分:0)

不能保证subviewsUIImageView的索引为拳头。

在相关子视图中,不能保证UIImageView的索引为拳头。

因此最好通过类类型访问它,并检查索引是否超出范围。

override func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
    guard let idx = tabBar.items?.firstIndex(of: item),
        tabBar.subviews.count > idx + 1,
        let imageView = tabBar.subviews[idx + 1].subviews.compactMap({ $0 as? UIImageView }).first else {
        return
    }
    
    imageView.layer.add(bounceAnimation, forKey: nil)
}

这是使用CAKeyframeAnimation的示例基本弹跳动画:

private var bounceAnimation: CAKeyframeAnimation = {
    let bounceAnimation = CAKeyframeAnimation(keyPath: "transform.scale")
    bounceAnimation.values = [1.0, 1.3, 0.9, 1.0]
    bounceAnimation.duration = TimeInterval(0.3)
    bounceAnimation.calculationMode = CAAnimationCalculationMode.cubic
    return bounceAnimation
}()

My Caption

答案 7 :(得分:0)

在目标c中为标签栏项目设置动画的简单方法

在标签栏控制器类中

    - (void)tabBar:(UITabBar *)tabBar didSelectItem:(UITabBarItem *)item
    {
        UIVisualEffectView *viv = tabBar.subviews[item.tag].subviews.firstObject;
        UIImageView *img = viv.contentView.subviews.firstObject;
       // If UIImageView not get use this code
       // UIImageView *img  = tabBar.subviews[item.tag].subviews.lastObject;


        [self shakeAnimation:img];
      //[self bounceAnimation:img];

    }



- (void)shakeAnimation:(UIImageView *)img
{
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"];
    [animation setDuration:0.05];
    [animation setRepeatCount:2];
    [animation setAutoreverses:YES];
    [animation setFromValue:[NSValue valueWithCGPoint: CGPointMake([img center].x - 10.0f, [img center].y)]];
    [animation setToValue:[NSValue valueWithCGPoint: CGPointMake([img center].x + 10.0f, [img center].y)]];
    [[img layer] addAnimation:animation forKey:@"position"];
}


- (void)bounceAnimation:(UIImageView *)img
{
    img.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.001, 0.001);

    [UIView animateWithDuration:0.3/1.5 animations:^{
        img.transform = CGAffineTransformScale(CGAffineTransformIdentity, 1.1, 1.1);
    } completion:^(BOOL finished) {
        [UIView animateWithDuration:0.3/2 animations:^{
            img.transform = CGAffineTransformScale(CGAffineTransformIdentity, 0.9, 0.9);
        } completion:^(BOOL finished) {
            [UIView animateWithDuration:0.3/2 animations:^{
                img.transform = CGAffineTransformIdentity;
            }];
        }];
    }];
}