web-dev-qa-db-fra.com

Ajoutez un UIView avant tout, même la barre de navigation

Je souhaite afficher, au-dessus de toute autre vue, même la barre de navigation, une sorte de vue "contextuelle" ressemblant à ceci:

  • fond noir plein écran avec une valeur alpha 0.5 pour voir l’autre UIViewController dessous.
  • une fenêtre UIView au milieu avec quelques informations (un calendrier si vous voulez tout savoir).

Pour ce faire, j'ai créé un UIViewController contenant les deux UIViews (arrière-plan et fenêtre) et j'essaie de l'afficher. J'ai essayé un simple [mySuperVC addSubview:myPopUpVC.view], mais j'ai toujours la barre de navigation ci-dessus.

J'ai essayé de le présenter comme un modal, mais la UIViewController ci-dessous disparaît et je perds mon effet de transparence.

Toute idée de faire ça, je suis sûre que c'est assez simple ...

Merci!

171
Nicolas Roy

Vous pouvez le faire en ajoutant votre vue directement à la fenêtre keyWindow:

UIView *myView = /* <- Your custom view */;
UIWindow *currentWindow = [UIApplication sharedApplication].keyWindow;
[currentWindow addSubview:myView];

PDATE - For Swift 4.1 et versions ultérieures

let currentWindow: UIWindow? = UIApplication.shared.keyWindow
currentWindow?.addSubview(myView)
186
Rom.

[self.navigationController.view addSubview:overlayView]; c'est ce que vous voulez vraiment

126
dalef

Voici une solution simple et élégante qui fonctionne pour moi. Vous pouvez définir la position z de la barre de navigation en dessous de la vue:

self.navigationController.navigationBar.layer.zPosition = -1;

Rappelez-vous simplement de le remettre à 0 lorsque vous avez terminé.

100
Nam

Versions rapides pour la réponse cochée:

Swift 4:

let view = UIView()
view.frame = UIApplication.shared.keyWindow!.frame
UIApplication.shared.keyWindow!.addSubview(view)

Swift 3.1:

let view = UIView()
view.frame = UIApplication.sharedApplication().keyWindow!.frame 
UIApplication.sharedApplication().keyWindow!.addSubview(view)
57
Kevin ABRIOUX

Ajoutez votre vue en tant que sous-vue de NavigationController.

[self.navigationController.navigationBar addSubview: overlayView)]

Vous pouvez également l'ajouter sur la fenêtre:

UIView *view = /* Your custom view */;
UIWindow *window = [UIApplication sharedApplication].keyWindow;
[window addSubview:view];

J'espère que cela t'aides.. :)

22
Rashad

Dalef excellente solution dans Swift:

self.navigationController?.view.addSubview(view)
19
Allreadyhome

Version rapide de la réponse de @Nicolas Bonnet:

    var popupWindow: UIWindow?

func showViewController(controller: UIViewController) {
    self.popupWindow = UIWindow(frame: UIScreen.mainScreen().bounds)
    controller.view.frame = self.popupWindow!.bounds
    self.popupWindow!.rootViewController = controller
    self.popupWindow!.makeKeyAndVisible()
}

func viewControllerDidRemove() {
    self.popupWindow?.removeFromSuperview()
    self.popupWindow = nil
}

N'oubliez pas que la fenêtre doit être une propriété forte, car la réponse d'origine entraîne une désallocation immédiate de la fenêtre.

8
iOS Unit

Il y a plus d'une façon de le faire:

1- Ajoutez votre UIView sur UIWindow au lieu de l'ajouter sur UIViewController. De cette façon, ce sera au-dessus de tout.

   [[(AppDelegate *)[UIApplication sharedApplication].delegate window] addSubview:view];

2- Utilisez une transition personnalisée qui gardera votre UIViewController visible à l'arrière avec une valeur de 0,5 alpha

Pour cela, je vous recommande de regarder ceci: https://github.com/Citrrus/BlurryModalSegue

6
Dani A

Je vous recommande de créer une nouvelle UIWindow:

UIWindow *window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
window.rootViewController = viewController;
window.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
window.opaque = NO;
window.windowLevel = UIWindowLevelCFShareCircle;
window.backgroundColor = [UIColor clearColor];

[window makeKeyAndVisible];

Ensuite, vous pouvez gérer votre vue dans un autre UIViewController. Pour enlever les fenêtres:

[window removeFromSuperview];
window = nil;

espérons que cela aidera!

6
Nicolas Bonnet

La réponse de @ Nam fonctionne très bien si vous souhaitez simplement afficher votre vue personnalisée mais si votre vue personnalisée nécessite une interaction de l'utilisateur, vous devez désactiver cette interaction pour le navigationBar.

self.navigationController.navigationBar.layer.zPosition = -1
self.navigationController.navigationBar.isUserInteractionEnabled = false

Comme dit dans la réponse de Nam, n'oubliez pas d'inverser ces changements:

self.navigationController.navigationBar.layer.zPosition = 0
self.navigationController.navigationBar.isUserInteractionEnabled = true

extension UINavigationBar {
    func toggle() {
        if self.layer.zPosition == -1 {
            self.layer.zPosition = 0
            self.isUserInteractionEnabled = true
        } else {
            self.layer.zPosition = -1
            self.isUserInteractionEnabled = false
        }
    }
}

Et utilisez-le simplement comme ceci:

self.navigationController.navigationBar.toggle()
5
Hemang
[[UIApplication sharedApplication].windows.lastObject addSubview:myView];
4
jold
UIApplication.shared.keyWindow?.insertSubview(yourView, at: 1)

Cette méthode fonctionne avec xcode 9.4, iOS 11.4

2
Ahmed R.

Remarque: si vous souhaitez ajouter une vue en plein écran, utilisez uniquement le code ci-dessous

Ajoutez ces extension de IViewController

public extension UIViewController {
   internal func makeViewAsFullScreen() {
      var viewFrame:CGRect = self.view.frame
      if viewFrame.Origin.y > 0 || viewFrame.Origin.x > 0 {
        self.view.frame = UIScreen.main.bounds
      }
   }
}

Continuer comme d'habitude en ajoutant le processus de sous-vue

Maintenant, utilisez en ajoutant viewDidAppear de UIViewController

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

     self.makeViewAsFullScreen()
}
2
Paresh Navadiya

J'utiliserais une sous-classe UIViewController contenant une "vue conteneur" qui intègre les autres contrôleurs de vue. Vous pourrez ensuite ajouter le contrôleur de navigation dans la vue Conteneur (à l'aide de la séquence de relation intégrée, par exemple).

Voir Implémentation d'un contrôleur de vue conteneur

1
dulgan

Dans Swift 4.2 et Xcode 10

var spinnerView: UIView? //This is your view

spinnerView = UIView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width, height: UIScreen.main.bounds.size.height))
//Based on your requirement change width and height like self.view.bounds.size.width
spinnerView?.backgroundColor = UIColor.black.withAlphaComponent(0.6)
//        self.view.addSubview(spinnerView)
let currentWindow: UIWindow? = UIApplication.shared.keyWindow
currentWindow?.addSubview(spinnerView!)

Dans Objectif C

UIView * spinnerView; // ceci est votre point de vue

self.spinnerView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, UIScreen.mainScreen.bounds.size.width, UIScreen.mainScreen.bounds.size.height)];  
//Based on your requirement change width and height like self.view.bounds.size.width
self.spinnerView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.6];
// [self.view addSubview:self.spinnerView];
UIWindow *currentWindow = [UIApplication sharedApplication].keyWindow;
[currentWindow addSubview:self.spinnerView];

Cela fonctionne uniquement en mode Portrait OR Paysage.

Un autre code simple est:

yourViewName.layer.zPosition = 1//Change you view name
1
iOS
[self.navigationController.navigationBar.layer setZPosition:-0.1];
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(10, 20, 35, 35)];
[view setBackgroundColor:[UIColor redColor]];
[self.navigationController.view addSubview:view];
[self.navigationController.view bringSubviewToFront:view];
self.navigationController.view.clipsToBounds = NO;
[self.navigationController.navigationBar.layer setZPosition:0.0];

enter image description here

0
Fadi Abuzant