lanzamiento - ios 12 iphone 6
Método de llamada en el controlador de vista actual desde el delegado de la aplicación en iOS (4)
Tengo dos controladores de vista (BuildingsViewController y RoomsViewController) que usan una función dentro del delegado de la aplicación llamada carga. La función de carga básicamente hace una solicitud HTTP, y si tiene éxito o no, desencadena una vista previa. Esto está funcionando bien.
La parte con la que estoy luchando es desde el método connectionDidFinishLoading
del delegado de la aplicación. Necesito poder actualizar básicamente el controlador de vista actual a través del método viewWillAppear
de ese controlador de vista. Dentro de la función viewWillAppear
de cada controlador de vista, tengo un código que determina los botones en la barra de herramientas inferior.
Quiero que el botón "subir" en la barra de herramientas de cada controlador de vista se elimine automáticamente cuando la carga se realiza a través del delegado de la aplicación.
Intenté hacer [viewController viewWillAppear:YES]
desde el método connectionDidFinishLoading
del delegado de la aplicación, pero nunca se llama.
Espero ser lo suficientemente claro. Cualquier ayuda es muy apreciada.
Gracias.
Lo peor de todo es que puede hacer que ambos controladores de vista se adhieran a un protocolo de método simple que eliminará ese botón y actualizará la vista. Luego, en su método connectionDidFinishLoading, ya que sabe que su controlador de vista debe cumplir con ese protocolo, por su diseño, simplemente haga algo como
ViewController<MyProtocol> curView = (Get the current view controller somehow);
[curview refreshView];
Para hacer la actualización de la vista, no llame a viewWillAppear
si la vista ya se muestra. Lo que quieres hacer es lo siguiente:
Cuando el método ConnectionDidFinishLoading
se desencadena publicar una notificación
[[NSNotificationCenter defaultCenter] postNotificationName:@"refreshView" object:nil];
En su viewController
observe esta notificación. Lo haces al agregar este código a tu método init o viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(refreshView:) name:@"refreshView" object:nil];
Ahora implemente -(void)refreshView:(NSNotification *) notification
método de -(void)refreshView:(NSNotification *) notification
en su viewController
para administrar su vista a su gusto.
Paso 1:
En el archivo .h de tu delegado de aplicaciones, debes declarar un protocolo como este:
@protocol AppConnectionDelegate <NSObject>
@required
-(void)connectionFinished:(NSObject*)outObject;
@end
En el mismo archivo, agregue un ivar como ese:
id *delegate;
Declara el ivar como una propiedad:
@property (nonatomic, assign) id<AppConnectionDelegate> delegate;
En el archivo Delegado .m de la aplicación, sintetice el ivar:
@synthesize delegate;
En el archivo .m de la aplicación Delegado, en connectionDidFinishLoading, haga lo siguiente:
if([self.delegate respondsToSelector:@selector(connectionFinished:)])
{
[self.delegate connectionFinished:objectYouWantToSend];
}
En el archivo .h de su viewcontroller, implemente AppConnectionDelegate importando una referencia al archivo delegado de la aplicación:
#import "AppDelegate_iPhone.h" //if using iPhone
#import "AppDelegate_iPad.h" //if using iPad
En el mismo archivo, al final de la primera línea de la declaración de interfaz, haga lo siguiente:
@interface AppDelegate_iPhone : AppDelegate_Shared <AppConnectionDelegate>
Declarar ivars en consecuencia:
AppDelegate_iPhone *appDelegate; //if using iPhone
AppDelegate_iPad *appDelegate; // if using iPad
En el archivo .m de viewcontroller en viewDidLoad (), obtenga una referencia al delegado de su aplicación usando:
Si iPhone;
appDelegate = (AppDelegate_iPhone*)[[UIApplication sharedApplication] delegate];
Si iPad:
appDelegate = (AppDelegate_iPad*)[[UIApplication sharedApplication] delegate];
Luego configure el viewcontroller para que sea el delegado en viewDidLoad () haciendo:
appDelegate.delegate = self;
Ahora solo necesita implementar el método connectionFinished en el archivo .m:
- (void)connectionFinished:(NSObject*)incomingObject
{
//Do whatever you want here when the connection is finished. IncomingObject is the object that the app delegate sent.
}
Ahora, cuando se invoca connectionDidFinishLoading de su delegado de aplicación, se notificará al controlador de vista.
[Es una práctica recomendada configurar appDelegate.delegate = nil si ha terminado de usar la conexión de devolución de llamada finalizada]
Esto es probado y probado. Si tienes preguntas, deja un comentario ......
--EDITAR--
Esta es una alternativa robusta a NSNotification. Yo uso ambos dependiendo de los requisitos. El proceso que uso para decidir entre usar NSNotification o una devolución de llamada de delegado usando un protocolo es simplemente:
Para notificaciones:
Un emisor, múltiples oyentes.
No hay referencia posible entre el emisor y el oyente.
No es necesario enviar objetos complejos / múltiples
Para devolución de llamadas de delegados usando protocolos:
Un remitente, limitado (por lo general 1) oyentes.
Una referencia entre el emisor y el oyente es posible.
Se deben enviar objetos complejos / múltiples (por ejemplo, objetos de respuesta que deben enviarse)
Sé que enviar objetos es posible a través de notificaciones, pero prefiero los protocolos para eso.
--EDITAR--
Si se dirige a iOS 4.0 y posterior, puede usar la propiedad rootViewController
la ventana para obtener el controlador de vista actual.
[window.rootViewController viewWillAppear];
Si desea que su aplicación se ejecute en versiones anteriores a iOS 4.0, puede agregar una variable de instancia al delegado de la aplicación para recordar qué controlador de vista llamó al método de upload
, haciendo que el controlador se envíe a sí mismo como parámetro.
- (void)upload:(UIViewController *)viewController {
self.uploadingViewController = viewController; // This is the property you add
...
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[self.uploadingViewController viewWillAppear];
self.uploadingViewController = nil;
}
También debería considerar usar un método diferente para volver a cargar los botones, algo así como reloadButtons
, ya que no está relacionado con la vista que aparece en este caso. Luego llamaría a ese método desde viewWillAppear
.