仅为UIBarButtonItem中的图像设置动画

时间:2013-02-18 15:52:58

标签: objective-c uiimageview rotation uibarbuttonitem uiviewanimation

我已经在2个应用程序中看到了这种效果,我真的想找到如何做到这一点。

动画位于UIBarButtonItem中,仅适用于图像。图像是+符号,它旋转为X。

如果你想看到效果,你必须开始与某人对话,然后在文本输入旁边有图像和表情符号的+按钮。或者在另一个应用程序中看到效果的视频,在点击条形按钮后,您会看到它旋转为X,http://www.youtube.com/watch?v=S8JW7euuNMo

我已经找到了如何做效果但只在UIImageView上,我必须关闭所有自动调整并且视图模式必须居中,然后对其应用旋转变换。我已经尝试了很多尝试让它在条形项目中工作的方法,到目前为止,最好的方法是添加图像视图实例,然后设置它并将视图模式设置为居中并自动恢复,然后使用该图像视图进行自定义栏项目视图。但是当我这样做时,效果会有效,除非它这样做,图像会偏向一边而不是停留在已经存在的位置。我已经尝试在动画之前获取中心并在动画期间设置它但是它没有做任何事情。

4 个答案:

答案 0 :(得分:6)

所以答案就是你必须创建一个Image视图的实例,然后设置它而不调整大小并且视图模式居中。然后将图像视图添加到具有自定义类型的UIButton,然后使用该按钮作为条形项的自定义视图。

- (IBAction)animate {
    [UIView animateWithDuration:0.5 delay:0.0 options:UIViewAnimationOptionCurveLinear animations:^{
        imageView.transform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(45));
    } completion:^(BOOL finished) {
        imageView.transform = CGAffineTransformMakeRotation(DEGREES_TO_RADIANS(0));
        if ([imageView.image isEqual:[UIImage imageNamed:@"Add.png"]]) {
            imageView.image = [UIImage imageNamed:@"Close.png"];
        }
        else imageView.image = [UIImage imageNamed:@"Add.png"];
    }];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    imageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Add.png"]];
    imageView.autoresizingMask = UIViewAutoresizingNone;
    imageView.contentMode = UIViewContentModeCenter;
    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    button.frame = CGRectMake(0, 0, 40, 40);
    [button addSubview:imageView];
    [button addTarget:self action:@selector(animate) forControlEvents:UIControlEventTouchUpInside];
    imageView.center = button.center;
    barItem = [[UIBarButtonItem alloc] initWithCustomView:button];
    navItem.rightBarButtonItem = barItem;
}

答案 1 :(得分:4)

最近不得不在Swift做同样的事情。我created a tutorial包括入门和最终项目,并逐步提供一些提示。代码如下:

@IBOutlet weak var rightBarButton: UIBarButtonItem! {
    didSet {
        let icon = UIImage(named: "star")
        let iconSize = CGRect(origin: CGPointZero, size: icon!.size)
        let iconButton = UIButton(frame: iconSize)
        iconButton.setBackgroundImage(icon, forState: .Normal)
        rightBarButton.customView = iconButton
        rightBarButton.customView!.transform = CGAffineTransformMakeScale(0, 0)

        UIView.animateWithDuration(1.0,
            delay: 0.5,
            usingSpringWithDamping: 0.5,
            initialSpringVelocity: 10,
            options: .CurveLinear,
            animations: {
                self.rightBarButton.customView!.transform = CGAffineTransformIdentity
            },
            completion: nil
        )    

        iconButton.addTarget(self, action: "tappedRightButton", forControlEvents: .TouchUpInside)        
    }
}

func tappedRightButton(){
    rightBarButton.customView!.transform = CGAffineTransformMakeRotation(CGFloat(M_PI * 6/5))
    UIView.animateWithDuration(1.0) {
        self.rightBarButton.customView!.transform = CGAffineTransformIdentity
    }
}

答案 2 :(得分:1)

我希望保留原始const char *视图提供的展开式点击大小(例如UIBarButtonItem-initWithBarButtonSystemItem:target:action:)。

这是我的代码的基本实现。

-initWithCustomView:

答案 3 :(得分:0)

您不必使用按钮作为自定义视图,实际上,使用UIImageView并添加UITapGestureRecognizer可以减少代码的工作量。

我希望我下面的解决方案可以帮助我为此苦苦挣扎很长时间的b / c,直到我获得bar按钮项来接收水龙头并使其能够与我想要的所有功能一起使用。以我为例,我制作了一个“警报铃”栏按钮项,当有通知时发出叮当声,然后在点击时锁定到新的tableview控制器。

这是我的解决方法(快速5):

@IBOutlet weak var notifyBell: UIBarButtonItem!

    func updateNumNotesAndAnimateBell(_ numNotes: Int) {

    guard let image = UIImage(named: "alertBellFill_\(numNotes)") else { return }
    let imageView = UIImageView(image: image)
    notifyBell.customView = imageView
    notifyBell.customView?.contentMode = .center
    let tap = UITapGestureRecognizer(target: self, action: #selector(notifyBellPressed))
    notifyBell.customView?.addGestureRecognizer(tap)

    let scaleTransformA = CGAffineTransform(scaleX: 0.8, y: 0.8)
    let rotateTransformA = CGAffineTransform(rotationAngle: 0.0)
    let hybridTransformA = scaleTransformA.concatenating(rotateTransformA)
    let rotateTransformB = CGAffineTransform(rotationAngle: -1*CGFloat.pi*20.0/180.0)
    let hybridTransformB = scaleTransformA.concatenating(rotateTransformB)

    notifyBell.customView?.transform = hybridTransformA
    UIView.animate(withDuration: 3,
                   delay: 1,
        usingSpringWithDamping: 0.1,
        initialSpringVelocity: 10,
        options: [.allowUserInteraction, .curveEaseInOut],
        animations: {
            self.notifyBell.customView?.transform = numNotes > 0 ? hybridTransformB : scaleTransformA
        },
        completion: nil
    )

}
@objc func notifyBellPressed(_ sender: UIBarButtonItem) {
    performSegue(withIdentifier: "goToNotificationsTVC", sender: self)
}

对我来说,关键发现是:

-.allowUserInteraction必须包含在动画选项中,否则UIBarButtonItem在动画完成之前不会处于活动状态。

-使用CGAffineTransform(rotationAngle:)时,您可能必须声明YourBarButtonItem.customView?.contentMode = .center,否则在尝试旋转时会扭曲图像。

-上面的代码包括一个缩放动画和旋转动画,具体取决于我收到的通知数量。通知为零时,该图像为空铃,否则,它在响铃图像中显示通知数。我可能可以使用更新标签来完成此操作,但是我已经走了为每个标签制作单独的PNG的路线,因此效果很好。