iphone - iOS 7 UIRefreshControl tintColor no funciona para beginRefreshing
objective-c xcode (15)
Estoy tratando de establecer un tintColor en mi UIRefreshControl (basado en iOS 7). He habilitado la actualización de tableViewController en el guión gráfico, luego en mi método ViewController viewDidLoad
hice lo siguiente:
[self.refreshControl setTintColor:[UIColor redColor]];
Así que ahora, cuando selecciono para refrescar, el color del control de refresco es rojo:
Quiero que mi vista se actualice automáticamente cuando aparece, así que lo hice:
- (void)viewDidAppear:(BOOL)animated{
[self.refreshControl beginRefreshing];
}
No mostró la rueda giratoria, de acuerdo con https://stackoverflow.com/a/16250679/1809736 , agregué
[self.tableView setContentOffset:CGPointMake(0, -self.refreshControl.frame.size.height) animated:NO];
forzar a mostrarlo. Lo muestra, pero ahora vuelve al color predeterminado:
Si trato manualmente de tirar para actualizar después, es rojo.
Intenté construirlo en iOS6 y funciona como debería, ¿así que es un error iOS7?
PD: no es un problema con el simulador, intenté construirlo en el dispositivo, el mismo error.
PPS: construí un proyecto de ejemplo, ¿puedes decirme si tienes el mismo error o si hay un problema en mi código? Aquí está el enlace: http://d.pr/f/pGrV
Muchas gracias !
¡SOLUCIÓN SWIFT! Inserta el siguiente código en viewDidLoad
:
self.refreshControl.tintColor = UIColor.orangeColor()
self.tableView.contentOffset = CGPointMake(0, -self.refreshControl.frame.size.height)
self.refreshControl.beginRefreshing()
Swift 3.1
self.refreshControl.tintColor = UIColor.orange
self.tableView.contentOffset = CGPoint(x:0, y:-self.refreshControl.frame.size.height)
self.refreshControl.beginRefreshing()
Agregue una extensión para UIResfreshControl.
extension UIRefreshControl {
func beginRefreshingManually() {
self.tintColor = UIColor.white
if let scrollView = superview as? UIScrollView {
scrollView.setContentOffset(CGPoint(x: 0, y:scrollView.contentOffset.y - frame.height), animated: false)
}
beginRefreshing()
}
}
Combiné algunas de las respuestas anteriores. Esto funciona para mí en iOS 9 y Swift 2:
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
let contentOffset = self.tableView.contentOffset.y
UIView.animateWithDuration(0, delay: 0, options: .BeginFromCurrentState, animations: {
print(self.tableView.contentOffset.y)
self.tableView.setContentOffset(CGPointMake(0, -self.refreshControl.frame.size.height), animated: false)
}, completion: { finished in
self.refreshControl.beginRefreshing()
self.tableView.setContentOffset(CGPointMake(0, contentOffset/2-self.refreshControl.frame.size.height), animated: true)
self.refresh() // Code that refresh table data
})
}
Desarrollé para iOS usando Xamarin (C #) y encontré el mismo problema.
RefreshControl
el problema de la coloración estableciendo el AttributedTitle
de RefreshControl
:
private CGPoint originalOffset;
...
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
...
originalOffset = TableView.ContentOffset; // Store the original offset of the table view
RefreshControl = new UIRefreshControl (){ TintColor = UIColor.Red };
RefreshControl.ValueChanged += ((s,e) => { Update (this, EventArgs.Empty); });
// Hack so the TintColor of the RefreshControl will be properly set
RefreshControl.AttributedTitle = new NSAttributedString ("Fetching data");
}
Mi método de actualización se ve así:
private async void Update(object sender, EventArgs args)
{
try {
TableView.UserInteractionEnabled = false;
// I find -100 to be a big enough offset
TableView.SetContentOffset (new CGPoint (0, -100), true);
RefreshControl.BeginRefreshing ();
... // Fetch data & update table source
TableView.ReloadData ();
} catch(Exception) {
// Respond to exception
} finally {
// Put the offset back to the original
TableView.SetContentOffset (originalOffset, true);
RefreshControl.EndRefreshing ();
TableView.UserInteractionEnabled = true;
}
}
Una vez que ViewDidAppear
, llamo a Update
programmatically. Antes de configurar el título atribuido, mi spinner habría sido negro. Ahora tiene el color rojo adecuado.
Vale la pena notar que este ''hack / fix'' también viene con un segundo error. La primera vez que actualice, notará que no se muestra AttributedTitle
. Actualizar una segunda (, tercera, cuarta, ...) vez mostrará el título correctamente. Pero si no quieres un título, simplemente lo inicializas con una cadena vacía, y este no es un gran problema para ti.
Espero que esto pueda ser útil para otros.
Encontré algunos Work Around, espero que funcione para ti
[_TBL setContentOffset:CGPointMake(0,_TBL.contentOffset.y-_refreshControl.frame.size.height) animated:YES];
[_refreshControl performSelector:@selector(beginRefreshing) withObject:nil afterDelay:0.25];
[self getLatestUpdates];
Estoy trabajando con Xamarin C # (iOS 10) y descubrí que una combinación de todas estas respuestas es lo que me solucionó.
En mi ViewDidLoad
tengo lo siguiente:
RefreshControl = new UIRefreshControl();
RefreshControl.TintColor = UIColor.White;
RefreshControl.ValueChanged += OnRefresh;
RefreshControl.BackgroundColor = UIColor.Clear;
Y luego ViewDidAppear
programáticamente la animación de actualización en mi ViewDidAppear
con lo siguiente:
BeginInvokeOnMainThread(() =>
{
UIView.Animate(0, 0.2, UIViewAnimationOptions.BeginFromCurrentState, () =>
{
TableView.SetContentOffset(new CGPoint(0, TableView.ContentOffset.Y - RefreshControl.Frame.Size.Height), true);
RefreshControl.AttributedTitle = new NSAttributedString("");
},
() =>
{
RefreshControl.BeginRefreshing();
});
});
Tenga en cuenta que la configuración del título atribuido y el bloque de animación fueron las partes que me faltaba para que mi RefreshControl
tomara mi color de tinte blanco.
Gracias a todos los que han contribuido a esta pregunta.
Forzar el setTintColor para que se ejecute en el hilo principal. (El hilo principal actualiza el ui).
[[NSOperationQueue mainQueue] addOperationWithBlock:^ {
[self.refreshControl setTintColor:[UIColor redColor]];
[self.refreshControl beginRefreshing];
}];
Hola, me encontré con este problema exacto.
Curiosamente, arreglé mi código configurando contentOffset primero y luego llamando a beginRefreshing
if(self.tableView.contentOffset.y == 0){
self.tableView.contentOffset = CGPointMake(0, -self.refreshControl.frame.size.height);
[self.refreshControl beginRefreshing];
}
Es posible que desee animar este proceso:
[UIView animateWithDuration:0.25 delay:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^(void){
self.tableView.contentOffset = CGPointMake(0, -self.refreshControl.frame.size.height);
} completion:^(BOOL finished) {
[self.refreshControl beginRefreshing];
}];
Espero que esto te ayude.
W
Intenta configurar el tintColor de tu UIRefreshControl en viewWillAppear.
La respuesta de @ william-george me puso en la dirección correcta, pero me estaba dando problemas extraños de animación de autolayout.
Así que aquí está la versión que funcionó para mí:
- (void)programaticallyRefresh {
// Hack necessary to keep UIRefreshControl''s tintColor
[self.scrollView setContentOffset:CGPointMake(0, -1.0f) animated:NO];
[self.scrollView setContentOffset:CGPointMake(0, -self.refreshControl.frame.size.height) animated:YES];
[self.refreshControl beginRefreshing];
[self refresh];
}
-refresh
es el método relacionado con UIRefreshControl
.
Ninguna de estas respuestas me funciona correctamente en iOS8, siendo la más cercana la respuesta de @ jpsim pero que aún dejaba un desagradable control de actualización en negro durante su animación de fundido de entrada (se desvanecería entre negro y durante el transcurso de la animación )
La solución que funcionó para mí fue poner esto inmediatamente después de crear el control de actualización en mi viewDidLoad:
self.refreshControl = [[UIRefreshControl alloc] init];
self.refreshControl.tintColor = [UIColor whiteColor];
...
self.refreshControlHeight = self.refreshControl.frame.size.height;
[self.tableView setContentOffset:CGPointMake(0, -1) animated:NO];
[self.tableView setContentOffset:CGPointMake(0, 0) animated:NO];
Luego, para mostrar el UIRefreshControl mediante programación:
[self.tableView setContentOffset:CGPointMake(0, self.tableView.contentOffset.y-self.refreshControlHeight) animated:YES];
[self.refreshControl beginRefreshing];
Tuve que almacenar la altura del control de actualización, ya que mientras estaba configurado para la primera invocación, las llamadas posteriores tendrían una altura de 0.
RÁPIDO:
Estoy usando Swift y> iOS8. La mayoría de las soluciones alternativas descritas no funcionaron para mí. Así es como lo hice funcionar:
En viewDidLoad:
customRefreshControl.tintColor = UIColor.clearColor()
Lo siguiente no tiene que estar dentro de viewDidLoad. Lo puse en una función extra que se llama cada vez que actualizo TableView:
private func startRefreshControlAnimation() {
self.tableView.setContentOffset(CGPointMake(0, -self.customRefreshControl.frame.size.height), animated: true)
CATransaction.begin()
self.customRefreshControl.beginRefreshing()
CATransaction.commit()
}
Solución para el problema tintColor: agregar esto en viewDidLoad
[self.refreshControl setTintColor:[UIColor whiteColor]];
[self.refreshControl tintColorDidChange];
Ahora tiene un indicador blanco cuando llama a beginRefresh manualmente.
este truco es muy funcional
var refreshWasProgramBeginning: Bool = false
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
if !refreshWasProgramBeginning {
UIView.animate(withDuration: 0.25, animations: {
self.tableView.contentOffset = CGPoint.init(x: 0, y: -self.refreshControl.frame.height)
}) { (_) in
self.refreshControl.beginRefreshing()
self.refreshWasProgramBeginning = true
}
}
}
Creé un drop-in UIRefreshControl + categoría beginRefreshing que soluciona este problema.
En resumen, corrige el problema de tintColor y manualmente tableView ajusta contentOffset para asegurarse de que el control de actualización esté visible. Por favor, inténtalo :)