Agregar vista sobre tableview (UITableViewController)

Situación: Tengo un UITableViewController cargando algunos datos de forma asíncrona desde un service. Durante este time, me gustaría colocar una vista de pantalla completa (excepto la barra de navigation) sobre la vista de la tabla que muestra mi indicador personalizado y el text.

Problema: El problema al que me enfrento es que cuando mi vista personalizada (tiene un background rojo) se coloca sobre UITableView, las líneas de la vista de la tabla se muestran a través de mi vista personalizada (ver la image a continuación).

Lo que intenté: intenté usar insertBelow y más arriba, no funcionó. También traté de hacer: tableview.Hidden = true, pero esto también oculta la vista personalizada por alguna razón como se ve en la image 2.

Ver líneas

Imagen1: Por alguna razón puedo ver las líneas que arrojaron mi vista.

Oculto verdadero

Imagen 2: Tableview + vista personalizada desapareció cuando se ocultaba = true utilizado.

Mi código:

public override void ViewDidLoad () { base.ViewDidLoad (); UIView view = new UIView (new RectangleF (0, 0, this.TableView.Frame.Width, this.TableView.Frame.Height)); view.BackgroundColor = UIColor.Red; this.TableView.AddSubview (view); TableView.Source = new SessionTableViewSource (); } 

El problema es que la vista de un UITableViewController es un UITableView , por lo que no puede agregar subvistas al controller en la parte superior de la tabla.

Recomendaría cambiar de UITableViewController a UIViewController simple que contenga una UITableView . De esta forma, la vista principal del controller es una vista UIView simple que contiene una tabla, y puede agregar subvenciones a la UIView principal y se colocarán en la parte superior de la vista de la tabla.

Puede usar self.navigationController.view como vista para agregar subvista.

Puede intentar agregar la vista a la window en lugar de anidarla en la vista de tabla así:

 UIWindow* mainWindow = [[UIApplication shanetworkingApplication] keyWindow]; [mainWindow addSubview: overlayview]; 
 UIWindow* window = [[UIApplication shanetworkingApplication].delegate.window; [window addSubview: your-overlayview]; 

Solución Swift / Storyboard

Nota: El código a continuación asume que uno tiene una vista personalizada (ratingView en mi caso) que se presentará en una UITableView.

He leído muchas respuestas a esta y otras preguntas similares sobre SO . Las otras respuestas de estas fonts funcionaron en diferentes grados para mí (p. Ej., Vista cargada pero no mostrada o no accesible, …). Estoy usando Swift 2.0+ y estoy compartiendo la solución completa para hacerlo usando un UITableViewController .

Cree una salida a la barra de navigation y la vista, que desea llevar a la vista de tabla.

 //MARK:Outlets @IBOutlet weak var navBar:UINavigationBar! @IBOutlet var ratingView: MNGStarRating! 

En mi caso, también quería animar la vista sobre la vista de tabla, así que utilicé una variable de class para mantener una reference al punto de inflexión y un punto sobre la escena (fuera de la pantalla).

 var centerYInflection:NSLayoutConstraint! var aPointAboveScene = -(max(UIScreen.mainScreen().bounds.width,UIScreen.mainScreen().bounds.height) * 2.0) 

Entonces, en viewDidLoad llamé a una function (configureRatingViewAutoLayout) que configura y agrega las restricciones para que la nueva vista sea animada sobre la vista de tabla.

 func configureRatingViewAutoLayout() { //REQUIRED self.navBar.superview?.addSubview(self.ratingView) var newConstraints:[NSLayoutConstraint] = [] newConstraints.append(self.ratingView.leadingAnchor.constraintEqualToAnchor(self.view.leadingAnchor,constant: 10)) newConstraints.append(self.ratingView.trailingAnchor.constraintEqualToAnchor(self.view.trailingAnchor,constant: 10)) newConstraints.append(self.ratingView.centerXAnchor.constraintEqualToAnchor(self.view.centerXAnchor)) //hides the rating view above the scene self.centerYInflection = self.ratingView.centerYAnchor.constraintEqualToAnchor(self.view.centerYAnchor, constant: self.aPointAboveScene) //the priority must be set below 1000 if you intend to change it after it has been added to a view self.centerYInflection.priority = 750 newConstraints.append(self.centerYInflection) //constraints must be added to the container view of the two items self.ratingView.superview?.addConstraints(newConstraints) } 

Nota Bene: en un UITableViewController; la vista self.view es self.tableView. Señalan lo mismo, así que supongo que también se podría usar la reference self.tableView anterior.

Algún time después … En respuesta a un evento de UIControl llamo a este método.

 @IBAction func toggleRatingView (sender:AnyObject?){ //REQUIRED self.ratingView.superview?.layoutIfNeeded() UIView.animateWithDuration(1.0, delay: 0.0, usingSpringWithDamping: 0.37, initialSpringVelocity: 0.99, options: [.CurveEaseOut], animations: { () -> Void in if CGRectContainsRect(self.view.frame, self.ratingView.frame) { //in frame ~ animate away //I play a sound to alert the user something is happening self.centerYInflection.constant = self.aPointAboveScene self.centerYInflection.priority = UILayoutPriority(950) //I disable portions of the UI self.disableUIElements(nil) } else { //out of frame ~ animate in //I play a different sound here self.centerYInflection.constant = 0 self.centerYInflection.priority = UILayoutPriority(950) //I enable the UI fully self.enableUIElements(nil) } //REQUIRED self.ratingView.superview?.setNeedsLayout() self.ratingView.superview?.layoutIfNeeded() }) { (success) -> Void in //do something else } } 

Estos methods auxiliares se pueden configurar para controlar el acceso a los elementos en su escena durante la presentación de la vista.

 func disableUIElements(sender:AnyObject?) { //UI } func enableUIElements(sender:AnyObject?) { //UI } 

Advertencias

Mi vista es una vista personalizada en el Storyboard (sentado fuera de la table pero conectado al controller TableView). La vista tiene un atributo de time de ejecución de usuario requerido layer.zPosition definido con un valor de número establecido en 2 (esto asegura que se presente delante de UITableView).

También se podría intentar jugar con bringSubviewToFront: y sendSubviewToBack: methods si no desea establecer la position z (creo que zPosition es más fácil de usar)

2

3