2013-03-07 3 views
13

So che mi manca qualcosa di stupido, ma in ogni caso, qui è il mio codice:Posizionare un UIActivityIndicator all'interno di un UIButton

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

Ecco il risultato finale:

Screenshot of misplaced UIActivityIndicator

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

Grazie in anticipo!

+0

Chiunque? Davvero non afferrando il posizionamento in iOS. –

risposta

29

Penso che il concetto che ti manca sia che il frame di una vista (e il suo centro) siano entrambi in relazione alla sua superview. In base al tuo screenshot, suppongo che i tuoi campi di testo e i pulsanti siano tutti in una vista che agisce da contenitore. Quindi il centro del tuo pulsante, il centro &, è in relazione a quella vista del contenitore e non alla vista del controller della vista nel suo insieme. Assegnate lo stesso fotogramma & al centro dell'indicatore di attività, ma in seguito aggiungete l'indicatore come vista secondaria della vista principale e non della vista del contenitore. Quindi ora hai due viste (il pulsante e l'indicatore) con lo stesso fotogramma, ma quella cornice è in relazione a due diverse interviste.

Il cambiamento più semplice sarebbe semplicemente aggiungere l'indicatore alla vista del contenitore che si sta utilizzando. Ma suggerirei di aggiungere l'indicatore come sottoview del pulsante, quindi basta fare un po 'di matematica per modificare la sua posizione.

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]; 

Come nota a margine: l'impostazione del centro di una vista subito dopo la cornice della vista è ridondante. Inoltre, l'ultima vista aggiunta come sottoview è automaticamente la vista secondaria anteriore.

3

Swift Soluzione:

var indicator = UIActivityIndicatorView() 
var halfButtonHeight = btnLogin.bounds.size.height/2; 
var buttonWidth = btnLogin.bounds.size.width; 
indicator.center = CGPointMake(buttonWidth - halfButtonHeight , halfButtonHeight); 
x.addSubview(indicator) 
indicator.startAnimating() 

E per rendere al centro del pulsante

indicator.center = CGPointMake(buttonWidth/2, halfButtonHeight); 

O Utilizzare grande biblioteca

https://github.com/souzainf3/RNLoadingButton-Swift

15

Sulla base @Musa almatri risposta, creo estensione:

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() 
     } 
    } 
}} 

allora si può usare in questo modo:

yourButton.loadingIndicator(show: true) //hide -> show: false 
+0

Nota questo pone l'indicatore al centro del pulsante. Risposta accettata con 'CGPointMake (buttonWidth - halfButtonHeight, halfButtonHeight)' la colloca sul lato destro (in modo semplice, intelligente, IMO). – dbreaux

2

sto usando vincoli per centrare l'indicatore all'interno del UIButton. Adattare l'estensione della @DanielQ, che diventa:

extension UIButton { 
    func loadingIndicator(show: Bool) { 
     let tag = 9876 
     if show { 
      let indicator = UIActivityIndicatorView() 
      indicator.tag = tag 
      self.addSubview(indicator) 
      indicator.translatesAutoresizingMaskIntoConstraints = false 
      let horizontalConstraint = NSLayoutConstraint(item: indicator, attribute: NSLayoutAttribute.centerX, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.centerX, multiplier: 1, constant: 0) 
      let verticalConstraint = NSLayoutConstraint(item: indicator, attribute: NSLayoutAttribute.centerY, relatedBy: NSLayoutRelation.equal, toItem: self, attribute: NSLayoutAttribute.centerY, multiplier: 1, constant: 0) 
      self.addConstraints([horizontalConstraint, verticalConstraint]) 
      indicator.startAnimating() 
     } else { 
      if let indicator = self.viewWithTag(tag) as? UIActivityIndicatorView { 
       indicator.stopAnimating() 
       indicator.removeFromSuperview() 
      } 
     } 
    } 
} 
4

Ecco una versione Swift 3, senza l'utilizzo di tag.

import UIKit 

extension UIButton { 
    func loadingIndicator(show: Bool) { 
     if show { 
      let indicator = UIActivityIndicatorView() 
      let buttonHeight = self.bounds.size.height 
      let buttonWidth = self.bounds.size.width 
      indicator.center = CGPoint(x: buttonWidth/2, y: buttonHeight/2) 
      self.addSubview(indicator) 
      indicator.startAnimating() 
     } else { 
      for view in self.subviews { 
       if let indicator = view as? UIActivityIndicatorView { 
        indicator.stopAnimating() 
        indicator.removeFromSuperview() 
       } 
      } 
     } 
    } 
} 
0

ho rimosso il titolo dal pulsante poi aggiunto indietro una volta che l'animazione ha finito piuttosto che l'indicatore sovrascrivendo il titolo:

extension UIButton { 

func loadingIndicator(show: Bool) { 
    let tag = 9876 

    var color: UIColor? 

    if show { 
     color = titleColor(for: .normal) 
     let indicator = UIActivityIndicatorView() 
     let buttonHeight = self.bounds.size.height 
     let buttonWidth = self.bounds.size.width 
     indicator.center = CGPoint(x: buttonWidth/2, y: buttonHeight/2) 
     indicator.tag = tag 
     indicator.color = UIColor.white 
     setTitleColor(.clear, for: .normal) 

     self.addSubview(indicator) 
     indicator.startAnimating() 
    } else { 
     if let indicator = self.viewWithTag(tag) as? UIActivityIndicatorView { 
      indicator.stopAnimating() 
      indicator.removeFromSuperview() 
      setTitleColor(color, for: .normal) 
     } 
    } 
} 
} 
1

Piccolo aggiornamento: (tasto aggiungendo superview)

extension UIButton { 
    func loadingIndicator(_ show: Bool) { 
     let indicatorTag = 808404 
     if show { 
      isEnabled = false 
      alpha = 0 
      let indicator = UIActivityIndicatorView(activityIndicatorStyle: .gray) 
      indicator.center = center 
      indicator.tag = indicatorTag 
      superview?.addSubview(indicator) 
      indicator.startAnimating() 
     } else { 
      isEnabled = true 
      alpha = 1.0 
      if let indicator = superview?.viewWithTag(indicatorTag) as? UIActivityIndicatorView { 
       indicator.stopAnimating() 
       indicator.removeFromSuperview() 
      } 
     } 
    } 
}