【问题标题】:Animating only the image in UIBarButtonItem仅对 UIBarButtonItem 中的图像进行动画处理
【发布时间】:2013-02-03 02:39:38
【问题描述】:

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

动画在 UIBarButtonItem 中,并且只针对图像。图像是 + 符号,它会旋转到 X。

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

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

【问题讨论】:

    标签: objective-c uiimageview rotation uibarbuttonitem uiviewanimation


    【解决方案1】:

    所以这个问题的答案是你必须创建一个 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;
    }
    

    【讨论】:

      【解决方案2】:

      最近不得不在 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
          }
      }
      

      【讨论】:

      • 如果您希望按钮在动画期间可点击,请添加 .AllowUserInteraction 选项
      • 为什么要使用 customView 类型?这是否适用于任何其他类型
      【解决方案3】:

      我想保留原生 UIBarButtonItem 视图提供的扩展点击大小(例如 -initWithBarButtonSystemItem:target:action:-initWithCustomView:)。

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

      - (void)setup {
          self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(navigationBarRightAction)];
      }
      
      - (void)navigationBarRightAction {
          UIView *itemView = [self.navigationItem.rightBarButtonItem performSelector:@selector(view)];
          UIImageView *imageView = [itemView.subviews firstObject];
      
          if (self.shouldRotate) {
              imageView.contentMode = UIViewContentModeCenter;
              imageView.autoresizingMask = UIViewAutoresizingNone;
              imageView.clipsToBounds = NO;
              imageView.transform = CGAffineTransformMakeRotation(M_PI_4);
      
          } else {
              imageView.transform = CGAffineTransformIdentity;
          }
      }
      

      【讨论】:

        【解决方案4】:

        您不必将按钮用作自定义视图,实际上它使用 UIImageView 并添加 UITapGestureRecognizer 的代码更少。

        我希望我下面的解决方案能帮助我解决这个问题很长时间的人,直到我得到条形按钮项目来接收点击并让它与我想要的所有功能一起工作。就我而言,我制作了一个“警报铃”栏按钮项目,当有通知时会发出叮当声,然后在点击时切换到新的 tableview 控制器。

        这是我的解决方案(Swift 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,所以效果很好。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-11-17
          • 1970-01-01
          相关资源
          最近更新 更多