Comment append un UIView au-dessus de l’actuel UITableViewController

J’ai du mal à append une sous-vue (UIView) depuis la méthode viewDidLoad d’un UITableViewController

Cela marche:

[self.view addSubview:self.progView]; 

Mais vous pouvez voir que les lignes de cellules de la table se perdent à travers UIView progView.

J’ai essayé cette approche:

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

Ce qui est une tentative d’append le progView, UIView à la superview, au-dessus de la vue actuelle. Lorsque j’essaie ceci, UIView n’apparaît jamais.

— METTRE À JOUR —

Voici la dernière tentative:

 UIView *myProgView = (UIView *)self.progView; //progView is a method that returns a UIView [self.tableView insertSubview:myProgView aboveSubview:self.tableView]; [self.tableView bringSubviewToFront:myProgView]; 

Le résultat est le même que [self.view addSubview: self.progView]; L’UIView apparaît mais apparemment derrière la table.

J’ai essayé l’approche ci-dessus, mais je n’ai pas réussi à la faire fonctionner. Je l’ai également trouvé nécessitant trop de configuration et de code, car il faut configurer la vue de la table à partir de zéro (ce qui se fait facilement à partir du storyboard).

Au lieu de cela, j’ai ajouté la vue que je voulais append au-dessus de mon UITableView dans la vue UINavigationController de UITableViewController, en tant que telle:

 [self.navigationController.view addSubview:]; 

Cette approche nécessite que vous ayez intégré UITableViewController dans un UINavigationController, mais même si vous ne voulez pas de contrôleur de navigation, vous pouvez toujours utiliser cette approche et simplement masquer la barre de navigation.

C’est en fait tout à fait possible et facile – il faut juste un peu de recâblage. J’ai rencontré une situation similaire et l’ai codée pour me permettre d’append des écrans de chargement au-dessus de mes vues de table. Cette approche vous permet également d’utiliser des cellules de tableau statiques avec votre propre contenu.

Si votre contrôleur est un UITableViewController dans un Storyboard ou un XIB et que vous souhaitez réaffecter une auto-vue à un UIView standard tout en préservant votre vue de table existante:

Ajoutez ces variables d’instance à votre fichier d’en-tête :

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

Dans votre fichier Storyboard ou XIB: Connectez la tableView dans UITableViewController à la variable tableViewReference .

Ensuite, dans votre fichier d’implémentation :

 // 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 */ } 

Bien que cela puisse sembler étrange, UITableViewController fait beaucoup de choses bizarres avec des références en coulisse. Vous devez attendre viewDidLoad pour effectuer le swap. Après cela, les accesseurs pointeront sur UIView et UITableView .

Utilisation: quelque chose comme

  [self.view addSubview:myView]; 

appenda un UIView myView devant la vue de la table, sans myView défiler myView avec le contenu de la vue de la table.

Note: Cette réponse a été modifiée après avoir souligné que la solution contenait un code paradoxal limite. UITableViewController fait des choses étranges aux références qu’il contient. Des tests plus minutieux ont permis de tirer cette réponse plus simple 🙂

J’ai été en mesure d’append une sous-vue par-dessus un uviewviewcontroller en utilisant le confinement de uiviewcontroller.

UITableViewController est en fait très utile en ce qui concerne les cellules statiques et c’est probablement la seule fois où la réponse commune “juste utiliser uviewview” peut ne pas être viable.

Donc c’est comme ça que je le fais.

  1. donner à votre UITableViewController un identifiant StoryBoard, par exemple MyStaticTableView
  2. créer une toute nouvelle sous-classe UIViewController et l’appeler UITableViewControllerContainer
  3. placez ce contrôleur à la place de votre UITableViewController dans votre storyboard
  4. append une sous-vue au nouveau contrôleur et le lier à un sharepoint vente appelé ” view_container
  5. sur la méthode UITableViewControllerContainer viewDidLoad

append du code comme:

 - (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]; } 

Des problèmes que vous pourriez avoir:

  1. Si vous avez un espace supplémentaire, veillez à append le drapeau “Want fullscreen” à votre UITableViewController.
  2. s’il ne redimensionne pas correctement sur votre UITableViewControllerContainer

append du code:

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

à ce stade de votre UITableViewController, vous pouvez accéder directement à votre vue de conteneur avec

self.view.superview.superview

et tout ce que vous y ajoutez sera affiché sur votre contrôleur de vue de table

Vous pouvez augmenter le zPosition du calque de votre vue.

Cela l’affichera au-dessus des autres vues (qui ont une position z égale à 0, par défaut)

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

Le problème est que la propriété view de UITableViewController est identique à la propriété tableView . Cela signifie que la vue racine est toujours un contrôleur de vue de table et que tout élément ajouté en tant que sous-vue est soumis à la fonctionnalité de vue de table. Cela a d’autres effets secondaires indésirables, comme le défilement de vos sous-vues lorsque vous ne le souhaitez pas.

Il y a quelques options ici. Vous pouvez remplacer loadView et installer votre propre vue et vue de table:

 // 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]; } 

Et puis, lorsque vous devez append une sous-vue, ajoutez-la au-dessous ou au-dessus de self.tableView le cas échéant.

Une autre option consiste simplement à créer une sous-classe UIViewController qui fait ce dont vous avez besoin. UITableViewController n’ajoute pas vraiment cela, et la petite fonctionnalité qu’elle met en œuvre est facilement répliquée. Il existe des articles comme Recréer UITableViewController pour augmenter la réutilisation du code et expliquer comment faire cela assez facilement.

L’exemple Apple “iPhoneCoreDataRecipes” utilise un NIB pour charger un en-tête sur un UITableView. Voir ici :

J’ai ajouté une image au-dessus du tableau. J’ai utilisé ce code:

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

J’ai eu un problème similaire et l’ai résolu en utilisant le code ci-dessous:

  [self.navigationController.view insertSubview: belowSubview:self.navigationController.navigationBar]; 

Cette insertion insère la vue au bon endroit en utilisant les contrôleurs présents dans Stack.

Comme UITableViewController est une sous-classe de UIViewController, vous devez append la vue souhaitée à sa superview.

 Swift: self.view.superview?.addSubview(viewTobeAdded) Objective C: [self.view.superview addSubview: viewTobeAdded]; 

Vous pouvez simplement mettre le code suivant dans viewDidAppear:

 [self.tableView.superview addSubview:]; 

Solution pour swift (équivalent à Daniel Saidi):

Si votre contrôleur est un UITableViewController dans un Storyboard ou un XIB et que vous souhaitez réaffecter une auto-vue à un UIView standard tout en préservant votre vue de table existante:

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

Ensuite, dans votre fichier d’implémentation:

Ajoutez ces variables d’instance à votre fichier de contrôleur de vue de table:

 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) } 

Dans votre fichier Storyboard ou XIB: Connectez la tableView dans UITableViewController à la variable tableViewReference.

Vous pourrez ensuite append des vues enfants comme suit:

 self.view.addSubView(someView) 

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

Ou vous pouvez essayer d’append self.progView à la vue de votre table.

Pour conserver UIView au-dessus de la vue table dans UITableViewController, j’utilise une ou plusieurs méthodes déléguées (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) { ... } 

Comme les vues ne peuvent avoir qu’une seule vue qui soit une bonne solution, corrigez-moi si je me trompe. Je continue à avoir 60 images par seconde, alors ça me va.

Swift 2018

Voici ma façon avec le storyboard:

1) Ajouter une vue dans le storyboard.
entrer la description de l'image ici

2) Liez-le avec la classe UITableViewController:

 @IBOutlet weak var copyrightLabel: UILabel! 

3) Ajoutez-le dans le code

 self.navigationController?.view.addSubview(copyrightView) copyrightView.frame = CGRect(x: 0, y: self.view.bounds.size.height - copyrightView.bounds.size.height, width: self.view.bounds.size.width, height: copyrightView.bounds.size.height) 

4) Voilla!
entrer la description de l'image ici

La vue ne défile pas avec la vue tableau. Cela peut être facile à concevoir depuis le storyboard.

Il y a peut-être des raisons de ne pas le faire, mais cela fonctionne pour moi jusqu’à présent. Si vous utilisez un ap

À l’intérieur de viewDidLayoutSubviews vous pouvez l’exécuter, mais assurez-vous de ne l’exécuter qu’une fois bien évidemment

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

J’ai eu un problème similaire où je voulais append un indicateur de chargement sur mon UITableViewController. Pour résoudre ce problème, j’ai ajouté mon UIView en tant que sous-vue de la fenêtre. Cela a résolu le problème. C’est comme ça que je l’ai fait.

 -(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]; } 

essayez quelque chose comme ça:

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

Mise à jour pour iOS 11:

Il est maintenant possible d’append une sous-vue à UITableView lors de l’utilisation de contraintes de mise en forme automatique dans la zone sécurisée. Ces vues ne défileront pas le long de la table.

Cet exemple place une vue sous la UITableView de navigation au-dessus de UITableView d’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] ]];