简体   繁体   中英

IOS/Objective-C:Two images showing at same time in barbutton

I am trying to create an animation effect where a UIBarButton temporarily changes to a different image and then changes back again. I am using a barbutton created in storyboard. Since uibarbuttons inherit from NSObject instead of UIView, however, I am first assigning a regular button to the uibarbutton. This lets me access UIView properities. All that works fine.

To do the animation, I am doing four animations in a row. Fade out the first button, fade in the second button, fade out the second button and fade in the first button again.

The problem is that when the second button loads, it also shows the first button at the same time, superimposing the buttons on one another. This is really strange and I can't figure out what is causing it. Here is code:

//I. Fade out first image
     [UIView animateWithDuration:0.2
                          delay:1.0
                        options: UIViewAnimationCurveEaseOut
                     animations:^{
                         self.hamburgerButton.customView.alpha=0;
                     }
                     completion:^(BOOL finished) {
  //II. Fade in second image.
                          [self.hamButton setBackgroundImage:nil forState:UIControlStateNormal];
                          [self.hamButton setBackgroundImage:secondImage forState:UIControlStateNormal];

                         [UIView animateWithDuration:0.6
                                               delay:0.0
                                             options: UIViewAnimationCurveEaseOut
                                          animations:^{
                                              self.hamburgerButton.customView.alpha=1;
                                          }
                                          completion:^(BOOL finished) {

    //III. Fade out second image
                               [UIView animateWithDuration:0.6
                               delay:0.0//was 2
                               options: UIViewAnimationCurveEaseOut
                               animations:^{
                               self.hamburgerButton.customView.alpha=0;
                               }
                               completion:^(BOOL finished) {

  //IV. Fade in First Image
                                [self.hamButton setBackgroundImage:firstImage forState:UIControlStateNormal];

                                [UIView animateWithDuration:0.6
                                delay:0.0//was 2
                                options: UIViewAnimationCurveEaseOut
                                animations:^{
                                self.hamburgerButton.customView.alpha=1;
                                }
                                completion:^(BOOL finished) {    
                               }];                
                               }];
                }];       
                }];

Instead of setting image of the same button take two separate buttons. Add them in a UIView. Place the one that needs to be faded at the back with alpha 0 and the one that needs to be visible in front with alpha 1.

On tap animate the alpha of front button to zero while at the same time animate the alpha of the second button to 1. Upon the completion of the animation bring back button to front.

This is how it can be done in obj-c:

 @interface ViewController ()
@property (strong, nonatomic) IBOutlet UIBarButtonItem *barButtonItem;
@property (strong, nonatomic) UIView *customView;
@property (strong, nonatomic) UIButton *menuButton;
@property (strong, nonatomic) UIButton *closeMenuButton;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    _menuButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [_menuButton setImage:[UIImage imageNamed:@"menu"] forState:UIControlStateNormal];
    [_menuButton addTarget:self action:@selector(menuButtonTapped) forControlEvents:UIControlEventTouchUpInside];

    _closeMenuButton = [UIButton buttonWithType:UIButtonTypeCustom];
    [_closeMenuButton setImage:[UIImage imageNamed:@"menu-back"] forState:UIControlStateNormal];
    [_closeMenuButton addTarget:self action:@selector(closeMenuButtonTapped) forControlEvents:UIControlEventTouchUpInside];
    _closeMenuButton.alpha = 0.0;

    _customView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 30)];
    _closeMenuButton.frame = _customView.bounds;
    _menuButton.frame = _customView.bounds;
    [_customView addSubview:_closeMenuButton];
    [_customView addSubview:_menuButton];

    _barButtonItem.customView = _customView;
}

- (void)menuButtonTapped {
    NSLog(@"Menu button tapped");

    [UIView animateWithDuration:0.5 animations:^{
        _menuButton.alpha = 0.0;
        _closeMenuButton.alpha = 1.0;
    } completion:^(BOOL finished) {
        [_customView bringSubviewToFront:_closeMenuButton];
    }];
}

- (void)closeMenuButtonTapped {
    NSLog(@"Close menu button tapped");
    [UIView animateWithDuration:0.5 animations:^{
        _closeMenuButton.alpha = 0.0;
        _menuButton.alpha = 1.0;
    } completion:^(BOOL finished) {
        [_customView bringSubviewToFront:_menuButton];
    }];
}
@end

Here is how I achieved it in Swift:

class ViewController: UIViewController {

    @IBOutlet var barButtonItem: UIBarButtonItem!

    let menuButton = UIButton.init(type: .custom)
    let backMenuButton = UIButton(type: .custom)
    let customView = UIView(frame: CGRect(x: 0, y: 0, width: 30, height: 30))

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        menuButton.setImage(#imageLiteral(resourceName: "menu"), for: .normal)
        menuButton.addTarget(self, action: #selector(menuButtonTapped), for: .touchUpInside)

        backMenuButton.setImage(#imageLiteral(resourceName: "menu-back"), for: .normal)
        backMenuButton.addTarget(self, action: #selector(backMenuButtonTapped), for: .touchUpInside)



        backMenuButton.frame = customView.bounds
        customView.addSubview(backMenuButton)
        backMenuButton.alpha = 0

        menuButton.frame = customView.bounds
        customView.addSubview(menuButton)

        self.barButtonItem.customView = customView
    }

    @objc func menuButtonTapped()  {
        print("Menu button tapped")
        UIView.animate(withDuration: 0.5, animations: {
            self.menuButton.alpha = 0.0
            self.backMenuButton.alpha = 1.0
        }) { (finished) in
            self.customView.bringSubview(toFront: self.backMenuButton)
        }
    }

    @objc func backMenuButtonTapped() {
        print("Back menu button tapped")
        UIView.animate(withDuration: 0.5, animations: {
            self.backMenuButton.alpha = 0.0
            self.menuButton.alpha = 1.0
        }) { (finished) in
            self.customView.bringSubview(toFront: self.menuButton)
        }
    }
}

Result:

在此处输入图片说明

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM