ios iphone uiscrollview xamarin.ios uirefreshcontrol

ios - ¿Puedo usar un UIRefreshControl en UIScrollView?



iphone xamarin.ios (8)

Aquí es cómo haces esto en C # / Monotouch. No puedo encontrar ninguna muestra para C # en ninguna parte, así que aquí está ... Gracias Log139!

public override void ViewDidLoad () { //Create a scrollview object UIScrollView MainScrollView = new UIScrollView(new RectangleF (0, 0, 500, 600)); //set the content size bigger so that it will bounce MainScrollView.ContentSize = new SizeF(500,650); // initialise and set the refresh class variable refresh = new UIRefreshControl(); refresh.AddTarget(RefreshEventHandler,UIControlEvent.ValueChanged); MainScrollView.AddSubview (refresh); } private void RefreshEventHandler (object obj, EventArgs args) { System.Threading.ThreadPool.QueueUserWorkItem ((callback) => { InvokeOnMainThread (delegate() { System.Threading.Thread.Sleep (3000); refresh.EndRefreshing (); }); }); }

Tengo alrededor de 5 UIScrollView ya en mi aplicación que cargan múltiples archivos .xib . Ahora queremos usar un UIRefreshControl . Están diseñados para ser utilizados con UITableViewControllers (según la referencia de clase UIRefreshControl). No quiero volver a hacer cómo funcionan todos los 5 UIScrollView . Ya he intentado usar el UIRefreshControl en mis UIScrollView , y funciona como esperaba, excepto por algunas cosas.

  1. Justo después de que la imagen de actualización se convierta en el cargador, UIScrollView salta alrededor de 10 píxeles, lo que no ocurre cuando tengo mucho cuidado de arrastrar el UIScrollview hacia abajo muy lentamente.

  2. Cuando me desplazo hacia abajo e inicio la recarga, a continuación, suelte el UIScrollView , el UIScrollView queda donde lo dejé ir. Cuando termina de volver a cargar, UIScrollView salta a la parte superior sin animación.

Aquí está mi código:

-(void)viewDidLoad { UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init]; [refreshControl addTarget:self action:@selector(handleRefresh:) forControlEvents:UIControlEventValueChanged]; [myScrollView addSubview:refreshControl]; } -(void)handleRefresh:(UIRefreshControl *)refresh { // Reload my data [refresh endRefreshing]; }

¿Hay alguna manera de que pueda ahorrar mucho tiempo y usar un UIRefreshControl en UIScrollView ?

¡¡¡Gracias!!!


Cómo hacerlo en Swift 3:

override func viewDidLoad() { super.viewDidLoad() let scroll = UIScrollView() scroll.isScrollEnabled = true view.addSubview(scroll) let refreshControl = UIRefreshControl() refreshControl.addTarget(self, action: #selector(pullToRefresh(_:)), for: .valueChanged) scroll.addSubview(refreshControl) } func pullToRefresh(_ refreshControl: UIRefreshControl) { // Update your conntent here refreshControl.endRefreshing() }


Hice que UIRefreshControl funcionara correctamente dentro de UIScrollView . Heredé UIScrollView , bloqueé el cambio de contentInset y overrided contentOfset setter:

class ScrollViewForRefreshControl : UIScrollView { override var contentOffset : CGPoint { get {return super.contentOffset } set { if newValue.y < -_contentInset.top || _contentInset.top == 0 { super.contentOffset = newValue } } } private var _contentInset = UIEdgeInsetsZero override var contentInset : UIEdgeInsets { get { return _contentInset} set { _contentInset = newValue if newValue.top == 0 && contentOffset.y < 0 { self.setContentOffset(CGPointZero, animated: true) } } } }


Para el tema Jumping, la respuesta de Tim Norman lo resuelve.

Aquí está la versión rápida si está usando swift2:

import UIKit class NoJumpRefreshScrollView: UIScrollView { /* // Only override drawRect: if you perform custom drawing. // An empty implementation adversely affects performance during animation. override func drawRect(rect: CGRect) { // Drawing code } */ override var contentInset:UIEdgeInsets { willSet { if self.tracking { let diff = newValue.top - self.contentInset.top; var translation = self.panGestureRecognizer.translationInView(self) translation.y -= diff * 3.0 / 2.0 self.panGestureRecognizer.setTranslation(translation, inView: self) } } } }


Si se suman las respuestas anteriores, en algunas situaciones no se puede establecer el tamaño del contenido (¿es posible utilizar el diseño automático?) O la altura del tamaño del contenido es menor o igual que la altura del UIScrollView. En estos casos, UIRefreshControl no funcionará porque UIScrollView no rebotará.

Para arreglar este conjunto, la propiedad alwaysBounceVertical es TRUE .


Si tiene la suerte de ser compatible con iOS 10+, ahora puede simplemente configurar el refreshControl de refreshControl de UIScrollView . Esto funciona de la misma manera que el refreshControl existente anteriormente en UITableView .


Simplemente puede crear una instancia del control de actualización y agregarla en la parte superior de la vista de desplazamiento. luego, en los métodos de delegado, usted ajusta su comportamiento a sus requisitos.


UIRefreshControl un UIRefreshControl para trabajar con UIScrollView :

- (void)viewDidLoad { UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, 500, 500)]; scrollView.userInteractionEnabled = TRUE; scrollView.scrollEnabled = TRUE; scrollView.backgroundColor = [UIColor whiteColor]; scrollView.contentSize = CGSizeMake(500, 1000); UIRefreshControl *refreshControl = [[UIRefreshControl alloc] init]; [refreshControl addTarget:self action:@selector(testRefresh:) forControlEvents:UIControlEventValueChanged]; [scrollView addSubview:refreshControl]; [self.view addSubview:scrollView]; } - (void)testRefresh:(UIRefreshControl *)refreshControl { refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:@"Refreshing data..."]; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ [NSThread sleepForTimeInterval:3];//for 3 seconds, prevent scrollview from bouncing back down (which would cover up the refresh view immediately and stop the user from even seeing the refresh text / animation) dispatch_async(dispatch_get_main_queue(), ^{ NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; [formatter setDateFormat:@"MMM d, h:mm a"]; NSString *lastUpdate = [NSString stringWithFormat:@"Last updated on %@", [formatter stringFromDate:[NSDate date]]]; refreshControl.attributedTitle = [[NSAttributedString alloc] initWithString:lastUpdate]; [refreshControl endRefreshing]; NSLog(@"refresh end"); }); }); }

Necesita hacer la actualización de datos en un hilo separado o bloqueará el hilo principal (que la interfaz de usuario usa para actualizar la interfaz de usuario). Entonces, mientras el hilo principal está ocupado actualizando los datos, la IU también está bloqueada o congelada, y nunca se ven las animaciones suaves o el giro.

EDIT: ok, estoy haciendo lo mismo que OP y ahora le agregué texto (es decir, "Pull to Refresh") y necesito volver al hilo principal para actualizar ese texto.

Respuesta actualizada