Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Place a UIActivityIndicator inside a UIButton

I know I'm missing something stupid, but anyway, here is my code:

UIActivityIndicatorView indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
indicator.hidesWhenStopped = YES;
indicator.frame = btnLogin.frame;
indicator.center = btnLogin.center;
[self.view addSubview:indicator];
[indicator bringSubviewToFront:indicator];

Here is the end result:

Screenshot of misplaced UIActivityIndicator

http://img542.imageshack.us/img542/8172/uiactivity.png

Thank you in advance!

like image 555
Matthys Du Toit Avatar asked Mar 07 '13 10:03

Matthys Du Toit


Video Answer


2 Answers

I think the concept you are missing is that a view's frame (and its center) are both in relation to its superview. Based on your screenshot I would guess that your textfields and buttons are all in a view that is acting as a container. So your button's frame & center are in relation to that container view and not to the view controller's view as a whole. You assign the same frame & center to the activity indicator, but then you add the indicator as a subview of the main view and not the container view. So you now have two views (the button and the indicator) with the same frame, but that frame is in relation to two different superviews.

The easiest change would just be to add your indicator to the container view you are using. But I would suggest adding the indicator as a subview of the button, then just do a little math to tweak its position.

UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
CGFloat halfButtonHeight = btnLogin.bounds.size.height / 2;
CGFloat buttonWidth = btnLogin.bounds.size.width;
indicator.center = CGPointMake(buttonWidth - halfButtonHeight , halfButtonHeight);
[btnLogin addSubview:indicator];
[indicator startAnimating];

As a side note: Your setting of the center of a view just after the frame of the view is redundant. Also, the last view added as a subview is automatically the front subview.

like image 122
NJones Avatar answered Oct 14 '22 21:10

NJones


Based on @Musa almatri answer, I create extension:

extension UIButton {
func loadingIndicator(show show: Bool) {
    let tag = 9876
    if show {
        let indicator = UIActivityIndicatorView()
        let buttonHeight = self.bounds.size.height
        let buttonWidth = self.bounds.size.width
        indicator.center = CGPointMake(buttonWidth/2, buttonHeight/2)
        indicator.tag = tag
        self.addSubview(indicator)
        indicator.startAnimating()
    } else {
        if let indicator = self.viewWithTag(tag) as? UIActivityIndicatorView {
            indicator.stopAnimating()
            indicator.removeFromSuperview()
        }
    }
}}

then you can use it like this:

yourButton.loadingIndicator(show: true) //hide -> show: false
like image 21
Daniel Kuta Avatar answered Oct 14 '22 19:10

Daniel Kuta