ios - buttons - uicontrol swift
Coloque un UIActivityIndicator dentro de un UIButton (7)
Sé que me estoy perdiendo algo estúpido, pero de todos modos, aquí está mi código:
UIActivityIndicatorView indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
indicator.hidesWhenStopped = YES;
indicator.frame = btnLogin.frame;
indicator.center = btnLogin.center;
[self.view addSubview:indicator];
[indicator bringSubviewToFront:indicator];
Aquí está el resultado final:
http://img542.imageshack.us/img542/8172/uiactivity.png
¡Gracias de antemano!
Aquí hay una versión de Swift 3, sin usar etiquetas.
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()
}
}
}
}
}
Basado en la respuesta de @Musa almatri, creo una extensión:
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()
}
}
}}
entonces puedes usarlo así:
yourButton.loadingIndicator(show: true) //hide -> show: false
Creo que el concepto que te falta es que el marco de una vista (y su centro) están relacionados con su supervisión. Según su captura de pantalla, supongo que sus campos de texto y botones están todos en una vista que actúa como un contenedor. Por lo tanto, el marco y el centro de su botón están relacionados con la vista del contenedor y no con la vista del controlador de vista en su conjunto. Asigna el mismo marco y centro al indicador de actividad, pero luego agrega el indicador como una subvista de la vista principal y no la vista de contenedor. Así que ahora tiene dos vistas (el botón y el indicador) con el mismo marco, pero ese marco está en relación con dos superviews diferentes.
El cambio más fácil sería simplemente agregar su indicador a la vista de contenedor que está utilizando. Pero sugeriría agregar el indicador como una subvista del botón, y luego hacer un poco de matemáticas para modificar su posición.
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];
Como nota al margen: la configuración del centro de una vista justo después del marco de la vista es redundante. Además, la última vista agregada como una subvista es automáticamente la subvista frontal.
Estoy usando contraints para centrar el indicador dentro de la UIButton. Adaptar la extensión de @DanielQ, que se convierte en:
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()
}
}
}
}
Poca actualización: (agregar botón en 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()
}
}
}
}
Quité el título del botón y luego lo volví a agregar una vez que la animación ha terminado, en lugar del indicador que anula el título:
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)
}
}
}
}
Solución rápida :
var indicator = UIActivityIndicatorView()
var halfButtonHeight = SOME_BUTTON.bounds.size.height / 2;
var buttonWidth = SOME_BUTTON.bounds.size.width;
indicator.center = CGPointMake(buttonWidth - halfButtonHeight , halfButtonHeight);
SOME_BUTTON.addSubview(indicator)
indicator.startAnimating()
Y para hacerlo en el centro del botón.
indicator.center = CGPointMake(buttonWidth/2, halfButtonHeight);
O usar una gran biblioteca