2011-01-09 36 views
46

tengo dificultades para agregar una vista secundaria (UIView) desde dentro del método viewDidLoad de un UITableViewControllerCómo añadir un UIView por encima de la UITableViewController actual

Esto funciona:

[self.view addSubview:self.progView]; 

Pero se puede ver la celda de la tabla las líneas sangran a través de Uiview progView.

He intentado este enfoque:

[self.view.superview insertSubview:self.progView aboveSubview:self.view]; 

¿Qué es un intento de añadir el progView, UIView a la supervista, por encima de la vista actual. Cuando intento esto, el UIView nunca aparece.

- ACTUALIZACIÓN -

siguiente es el último intento:

UIView *myProgView = (UIView *)self.progView; //progView is a method that returns a UIView 

[self.tableView insertSubview:myProgView aboveSubview:self.tableView]; 
[self.tableView bringSubviewToFront:myProgView]; 

El resultado es el mismo que [addSubview self.view: self.progView]; La UIView aparece pero aparentemente detrás de la mesa.

+2

¿Ha intentado utilizar 'aboveSubview: self.view'? No digo que resolvería tu problema, pero parece que eliminaría el mensaje de error que recibes. –

+0

Sí, lo intenté. Es cierto que pierdo la advertencia, pero todavía no representa la vista. Voy a editar mi publicación sin embargo. – user558096

+0

un método simple es establecer el marco de progVIew, y estoy seguro de que puede funcionar. Cualquier restricción no funcionará, incluso VFL – BollMose

Respuesta

1

intento: [self.view bringSubviewToFront:self.progView];

O puede tratar de añadir self.progView a la vista de su mesa.

+0

[self.view bringSubViewToFront: self.progView]; me da la advertencia: 'UIView' puede no responder a '-bringSubViewToFront:' y bloquea la aplicación con una excepción de '' selector no reconocido enviado a la instancia ''. – user558096

+0

entonces su controlador es un UITableViewController? – WrightsCS

+0

Sí, mi controlador es un UITableViewController. – user558096

6

El problema es que la propiedad view de UITableViewController es idéntica a la propiedad tableView. Lo que esto significa es que la vista raíz es siempre un controlador de vista de tabla, y todo lo agregado como subvista estará sujeto a la funcionalidad de vista de tabla. Esto tiene otros efectos secundarios indeseables, como el desplazamiento de subvistas cuando no lo desee.

Aquí hay un par de opciones. Se podría anular loadView e instalar su propio punto de vista y la tabla de vista:

// note: untested 
- (void)loadView { 
    self.view = [[[UIView alloc] initWithFrame:CGRectZero] autorelease]; 
    self.view.backgroundColor = [UIColor whiteColor]; 

    UITableView *tblView = [[UITableView alloc] 
     initWithFrame:CGRectZero 
     style:UITableViewStylePlain 
    ]; 

    tblView.autoresizingMask = 
     UIViewAutoresizingFlexibleWidth | 
     UIViewAutoresizingFlexibleHeight 
    ; 

    self.tableView = tblView; 
    [self.view addSubview:tblView]; 
    [tblView release]; 
} 

Y luego, cuando es necesario agregar una vista secundaria, añadirlo debajo o por encima self.tableView según corresponda.

Otra opción es crear una subclase UIViewController que hace lo que necesita. UITableViewController honestamente no agrega mucho, y la poca funcionalidad que implementa se replica fácilmente. Hay artículos como Recreating UITableViewController to increase code reuse que explican cómo hacer esto con bastante facilidad.

+0

Gracias por la ayuda aquí. Lamentablemente, me cuesta trabajo hacer que tu primera sugerencia funcione. Quizás lo que trato de hacer simplemente no es posible. En este punto, estoy tratando de hacer una UIView a mi mismo.vista de una subclase UITableViewController. Y luego haga de UITableView una subvista de UIView. No parece que sea posible hacerlo y realmente necesito convertir mi UITableViewController a un UIViewController según sus segundas sugerencias. Cualquier idea o puntero a tutoriales o código de ejemplo que pueda ser útil. Gracias por adelantado. – user558096

+1

No me referiría a self.view para leer en loadView, terminará en un bucle infinito. Solo asignarlo. – Diziet

5

El ejemplo de Apple "iPhoneCoreDataRecipes" está utilizando un NIB para cargar un encabezado en un UITableView. Ver here:

+0

¡Estoy de acuerdo con esta respuesta! – Jagie

11

He podido agregar una subvista en la parte superior de un controlador de uitable mediante el uso de la contención uiviewcontroller.

UITableViewController es realmente muy útil cuando se trata de células estáticas y este es probablemente el único momento en el que la respuesta común "simplemente use uitableview" puede no ser viable.

Así que así es como lo hago.

  1. dar a su UITableViewController un StoryBoard identificador es decirMyStaticTableView
  2. crear una marca nueva UIViewController subclase y llamarlo UITableViewControllerContainer
  3. lugar este controlador en lugar de su UITableViewController dentro de su guión gráfico
  4. añadir una vista secundaria al nuevo controlador y vincularlo a una salida llamada como "view_container"
  5. en usted UITableViewControllerContainer método viewDidLoad código

complemento como:

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    // Do any additional setup after loading the view. 
    UITableViewController *vc = [self.storyboard instantiateViewControllerWithIdentifier:@"MyStaticTableView"]; 
    [self addChildViewController:vc]; 
    [self.view_container addSubview:vc.view]; 
} 

problema que pueda tener:

  1. entonces, si usted tiene un espacio superior adicional asegúrese de agregar la opción "quiere pantalla completa" para su UITableViewController
  2. si no cambia el tamaño correctamente en su UITableViewControllerContainer
código

complemento:

- (void)viewWillAppear:(BOOL)animated 
{ 
    [[self.view_container.subviews lastObject] setFrame:self.view.frame]; 
} 

en este punto de su UITableViewController que se puede acceder a la vista de contenedores directamente con

self.view.superview.superview

y todo lo que se agrega se mostrará en la parte superior su controlador de vista de tabla

+1

Desde iOS 6.0 y superior, un UIContainerView hace que la solución sea aún más fácil. – eladleb

87

Probé la a Probar arriba, pero no lo hizo funcionar. También encontré que requiere demasiada configuración y código, ya que requiere configurar la vista de tabla desde cero (algo que se hace fácilmente desde el guión gráfico).

En cambio, he añadido la opinión de que quería añadir por encima de mi UITableView a la vista de la UITableViewController UINavigationController, como tal:

[self.navigationController.view addSubview:<view to add above the table view>]; 

Este enfoque requiere que se haya incorporado la UITableViewController en un UINavigationController, pero incluso si no desea un controlador de navegación, puede seguir utilizando este enfoque y simplemente ocultar la barra de navegación.

+9

El problema con su solución es que cuando hace esto, la vista también se agrega sobre la barra de navegación – Mittchel

+34

Puede hacer esto: '[self.navigationController.view insertSubview: holderView belowSubview: self.navigationController.navigationBar];' –

+1

Otro El problema es que la vista agregada permanece encima del UINavigationController, incluso después de presionar un nuevo UIViewController. – Raphael

28

Esto es bastante posible y fácil, solo requiere un poco de cableado. Encontré una situación similar y codifiqué esto para permitirme agregar pantallas de carga en la parte superior de las vistas de mi tabla. Este enfoque también le permite usar celdas de tabla estáticas con su propio contenido.

Si su controlador es un UITableViewController en un Storyboard o XIB y desea reasignar uno mismo.Ver a un UIView estándar, mientras que la preservación de su vista de tabla existente:

Añadir estas variables de instancia a su archivo cabecera:

IBOutlet UITableView *tableViewReference; // to keep a reference to the tableview 
UIView *viewReference; // a reference to the new background view 

En su Storyboard o XI ter archivo: Conectar el tableView en el UITableViewController a la variable tableViewReference.

A continuación, en el archivo de aplicación :

// Override the default accessors of the tableview and view 
- (UITableView*)tableView { return tableViewReference; } 
- (UIView*)view { return viewReference; } 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    // instantiate the new self.view, similar to the tableview 
    viewReference = [[UIView alloc] initWithFrame:tableViewReference.frame]; 
    [viewReference setBackgroundColor:tableViewReference.backgroundColor]; 
    viewReference.autoresizingMask = tableViewReference.autoresizingMask; 
    // add it as a subview 
    [viewReference addSubview:tableViewReference]; 

    /* remainder of viewDidLoad */ 

} 

Aunque pueda parecer extraño, UITableViewController está haciendo un montón de cosas peculiar con referencias detrás de las escenas. Debes esperar hasta viewDidLoad para realizar el intercambio. Después de este punto, los accesores apuntarán a la correcta UIView y UITableView.

Uso: Algo así como

[self.view addSubview:myView]; 

agregará un UIView myView frente a la vista de tabla, sin myView desplazándose con el contenido de la vista de tabla.

Nota: Esta respuesta se editó después de que se señaló que la solución contenía el código paradójico límite. UITableViewController hace cosas extrañas a las referencias que contiene. Algunas pruebas más cuidadosas derivaron esta respuesta más simple :)

+0

No entiendo cómo esto puede funcionar, cuando lo haces '- (UITableView *) tableView { return mainTableView; } 'y llamar después de 'mainTableView = self.tableView;' es como hacer 'mainTableView = mainTableView' ... – AncAinu

+0

@AncAinu Si lee la nota que puse justo debajo del código, verá que es necesario detener perdiendo una referencia a eso. No veo por qué eso merecía un voto negativo. –

+0

@ThomasVerbeek porque lo que haces es totalmente inutilizable. '- (UITableView *) tableView' esto reemplaza al' self.tableView' original, por lo que cuando llamas 'mainTableView = self.tableView;' es como llamar a 'mainTableView = mainTableView' y porque nunca lo asignaste antes, es como ' nil = nil'. Su 'mainTableView' nunca se llena con algo en este código. – AncAinu

4

Agregué una imagen sobre la mesa. He utilizado este código:

self.tableView.tableHeaderView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"header.png"]]; 
0

tuve un problema similar donde quería añadir un indicador de carga en la parte superior de mi UITableViewController. Para resolver esto, agregué mi UIView como una subvista de la ventana. Eso resolvió el problema. Así es como lo hice.

-(void)viewDidLoad{ 
    [super viewDidLoad]; 
    //get the app delegate 
    XYAppDelegate *delegate = [[UIApplication sharedApplication] delegate]; 

    //define the position of the rect based on the screen bounds 
    CGRect loadingViewRect = CGRectMake(self.view.bounds.size.width/2, self.view.bounds.size.height/2, 50, 50); 
    //create the custom view. The custom view is a property of the VIewController 
    self.loadingView = [[XYLoadingView alloc] initWithFrame:loadingViewRect]; 
    //use the delegate's window object to add the custom view on top of the view controller 
    [delegate.window addSubview: loadingView]; 
} 
0

Puede haber razones para no hacer esto, pero esto funciona para mí hasta ahora. Si utiliza un punto de acceso

Dentro viewDidLayoutSubviews puede ejecutar esto, pero asegúrese de que sólo a ejecutar una vez, obviamente,

self.searchTableView = [[UITableView alloc] initWithFrame:self.tableView.frame style:UITableViewStylePlain]; 
self.searchTableView.backgroundColor = [UIColor purpleColor]; 
[self.view.superview addSubview:self.searchTableView]; 
8

puede aumentar el zPosition de la capa de la vista.

Esto hará que sea mostrar por encima de los otros puntos de vista (que tiene un zPosition igual a 0, por defecto)

self.progView.layer.zPosition++; 
[self.view addSubview:self.progView]; 
+0

Esto funcionó para mí. Solo estoy usando un UIViewController normal que tiene una UITableView y quería colocar una vista de pie de página que se encuentra en la parte superior de la vista de tabla. Por alguna razón, si traje el visor de pies al frente a través de una llamada 'bringSubviewToFront' o a través del guión gráfico, la UITableView se empujará hacia abajo. Esto dejó una gran brecha en la parte superior. No estoy seguro de por qué el UITableView no puede tener nada sobre él en la jerarquía de vistas. El cambio de la propiedad 'zPosition' de la capa de la vista de pie de página lo colocó con éxito sin cambiar la posición de UITableView. – Sid

+0

Esto funciona, pero las capas no manejan la interacción del usuario (es por eso que tenemos UIView). Solo señalando eso. – Chris

0

intentar algo como esto:

[self.tableView addSubview:overlayView]; 
overlayView.layer.zPosition = self.tableView.backgroundView.layer.zPosition + 1; 
2

tuve un problema similar y tengo lo resolvió usando el siguiente código:

 [self.navigationController.view insertSubview:<subview> 
     belowSubview:self.navigationController.navigationBar]; 

Esto inserta la vista en el lugar correcto usando los controladores presentes en la pila .

2

Como UITableViewController es una subclase de UIViewController, debe agregar la vista que desee a su supervista.

Swift: 
self.view.superview?.addSubview(viewTobeAdded) 

Objective C: 
[self.view.superview addSubview: viewTobeAdded]; 
+0

self.view.superview es nulo para mi UITableViewController (en viewDidLoad) – Jovan

0

Usted puede simplemente poner el siguiente código en viewDidAppear:

[self.tableView.superview addSubview:<your header view>]; 
1

Solución rápida (equivalente a Daniel Saidi):

Si el controlador es un UITableViewController en un guión gráfico o XI ter y desea reasignar self.view a una UIView estándar conservando su vista de tabla existente:

@IBOutlet var tableViewReference: UITableView! 
var viewReference: UIView! 

A continuación, en el archivo de aplicación:

Añadir estas variables de instancia a su tabla de archivos controlador de vista:

override var tableView: UITableView! { 
    get { return tableViewReference } 
    set { super.tableView = newValue } 
} 

override var view: UIView! { 
    get { return viewReference } 
    set { super.view = newValue } 
} 

override func viewDidLoad() { 
    super.viewDidLoad() 
    self.edgesForExtendedLayout = UIRectEdge.None 
    self.extendedLayoutIncludesOpaqueBars = false 
    self.automaticallyAdjustsScrollViewInsets = false 

    //rewiring views due to add tableView as subview to superview 
    viewReference = UIView.init(frame: tableViewReference.frame) 
    viewReference.backgroundColor = tableViewReference.backgroundColor 
    viewReference.autoresizingMask = tableViewReference.autoresizingMask 
    viewReference.addSubview(tableViewReference) 
} 

En el archivo de guión gráfico o XI ter: Conectar el tableView en el UITableViewController a la variable tableViewReference.

Entonces usted será capaz de añadir vistas secundarias de la siguiente manera:

self.view.addSubView(someView) 
1

Para mantener UIView superior ver tabla en la UITableViewController estoy usando una (o más) de los métodos de delegado (UITableViewDelegate).

override func viewDidLoad() { 
    super.viewDidLoad() 
    self.tableView.addSubview(headerView) 
} 

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) { 
    tableView.addSubview(overlayView) // adds view always on top 
} 
// if using footers in table view 
tableView(_ tableView: UITableView, willDisplayFooterView view: UIView, forSection section: Int) { ... } 

Como las vistas solo pueden tener una supervista que también es una buena solución, corríjame si me equivoco. Aún obtengo 60 fps, así que está bien para mí.

+0

¿Cómo diseñó 'overlayView' y' headerVew'? – LShi

0

actualización de IOS 11:

Ahora es posible añadir una vista secundaria a UITableView cuando se utilizan restricciones de diseño automático a la zona segura. Estas vistas no se desplazarán por TableView.

En este ejemplo se coloca una vista por debajo de la navigationbar en la parte superior de la UITableView de un UITableViewController

[self.tableView addSubview:self.topBarView]; 
[NSLayoutConstraint activateConstraints:@[ 
    [self.topBarView.topAnchor constraintEqualToAnchor:self.tableView.safeAreaLayoutGuide.topAnchor], 
    [self.topBarView.leadingAnchor constraintEqualToAnchor:self.tableView.safeAreaLayoutGuide.leadingAnchor], 
    [self.topBarView.trailingAnchor constraintEqualToAnchor:self.tableView.safeAreaLayoutGuide.trailingAnchor], 
    [self.topBarView.heightAnchor constraintEqualToConstant:40.0] 
]]; 
+0

¿Podría explicar qué es 'viewController' y cuál es la relación entre él y' UITableViewController'? – LShi

+0

Debería ser el 'UITableViewController' o más bien su' tableView'. Copié el código de mi subclase UINavigationController que tiene una referencia al ViewController que se muestra (que en mi caso ES el UITableViewController). Arreglé el ejemplo. – cornr

Cuestiones relacionadas