Thêm một UIView trên tất cả, ngay cả thanh điều hướng


181

Tôi muốn hiển thị, trên bất kỳ chế độ xem nào khác, ngay cả thanh điều hướng, một loại chế độ xem "bật lên" trông như thế này:

  • toàn màn hình nền đen với 0,5 alpha để xem cái khác UIViewControllerbên dưới.
  • một UIViewcửa sổ ở giữa với một số thông tin, (lịch nếu bạn muốn biết mọi thứ).

Để làm điều đó, tôi đã tạo một UIViewControll chứa hai UIViews(nền và cửa sổ) và tôi đang cố gắng hiển thị nó. Tôi đã thử một cách đơn giản [mySuperVC addSubview:myPopUpVC.view], nhưng tôi vẫn có thanh điều hướng ở trên.

Tôi đã cố gắng trình bày nó như một phương thức, nhưng UIViewControllerbên dưới biến mất, và tôi mất hiệu ứng trong suốt của tôi.

Bất cứ ý tưởng nào để làm điều này, tôi chắc chắn rằng nó khá đơn giản ...

Cảm ơn!


Thêm một khung nhìn trên cửa sổ ứng dụng của bạn. Xử lý thay đổi hướng có thể khó khăn: stackoverflow.com/questions/8774495/
trộm

Câu trả lời:


197

Bạn có thể làm điều đó bằng cách thêm chế độ xem của bạn trực tiếp vào keyWindow:

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

CẬP NHẬT - Dành cho Swift 4.1 trở lên

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

2
Cảm ơn :) Thật không may nếu bạn đang ở chế độ nằm ngang, bạn cần xoay chế độ xem. Tôi không chắc tôi biết làm thế nào cho đúng.
Nicolas Roy

Có, tôi chỉ ở chế độ ngang và myView xuất hiện với góc xoay 90 độ. Có vẻ là những gì họ đang nói ở đây: stackoverflow.com/questions/8774495/ Kẻ
Nicolas Roy

Vấn đề định hướng xảy ra trên các thiết bị trước iOS8, mà giải pháp này đáng buồn là không hoạt động.
Junc

@NicolasRoy Autolayout sẽ giúp
Darmen Amanbayev

4
nó không bao gồm thanh tab. Bất kỳ giải pháp cho điều đó?
Manisha

134

[self.navigationController.view addSubview:overlayView]; là những gì bạn thực sự muốn


5
Bạn cần đặt khung
Gabriel Goncalves

1
Giải pháp rất tốt, đặc biệt, khi bạn thêm chế độ xem dưới dạng "trình điều khiển chế độ xem trẻ em"
Richard Topchii

2
Điều này không hoạt động với chế độ xem của trình điều khiển xem con. Việc thay đổi cấp độ z của thanh điều hướng (như Nam gợi ý) cũng hoạt động với các bộ điều khiển xem con.
Tapani

Có vẻ như giải pháp thanh lịch hơn là thêm chế độ xem vào cửa sổ Key. Vì điều này đảm bảo chế độ xem được thêm vào, di chuyển dọc theo hình động của chế độ xem cơ sở. Bởi vì nếu chế độ xem được thêm vào cửa sổ chính, nó không đi kèm với hình ảnh động và phải được loại bỏ riêng biệt nếu bạn muốn loại bỏ bộ điều khiển.
soan saini

Nó không quá cửa sổ bật lên nhưng nó chỉ đúng với trường hợp của tôi. Cảm ơn))
Dilshod Zopirov

112

Đây là một giải pháp thanh lịch đơn giản đang làm việc cho tôi. Bạn có thể đặt vị trí z của thanh điều hướng bên dưới chế độ xem:

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

Chỉ cần nhớ đặt lại về 0 khi hoàn tất.


1
Điều này hoạt động tốt hơn nhiều so với việc thêm chế độ xem lớp phủ dưới dạng chế độ xem phụ vào chế độ xem của bộ điều khiển điều hướng (do đó gây ra sự cố). Giải pháp vị trí z này có lẽ đáng tin cậy hơn nhiều và gây ra ít vấn đề hơn trong tương lai.
Tapani

Điều này hoạt động tuyệt vời khi làm việc với bảng phân cảnh. Bạn có thể thêm chế độ xem bên trong bảng phân cảnh!
Jos Koomen

Làm việc tuyệt vời cho tôi quá. Sẽ thật tuyệt khi đề cập rằng zPocation nên được đặt lại về giá trị 0 (bạn chỉ cần đề cập rằng nó nên được đặt lại khi hoàn thành). Và tôi cũng có tabBar (từ TabBarControll trong màn hình của mình. Tôi đã cố gắng đặt zPocation nhưng khi trở về 0 giá trị tabBar vẫn không hiển thị. Vì vậy, đối với tabBar, tốt hơn là sử dụng thuộc tính isHidden.
Libor Zapletal

1
Đừng làm việc với khả năng tiếp cận. Panning trên quan điểm sẽ không tập trung vào nó.
antonjn

Tôi mến bạn!! <3
chr0x

57

Phiên bản Swift cho phản hồi đã kiểm tra:

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)

6
Tôi có thể thực hiện điều này bao gồm tất cả chế độ xem hiện tại (trình điều khiển chế độ xem), nhưng để lại trình điều khiển chế độ xem mới xuất hiện phía trên nó không?
Michał Ziobro

24

Thêm bạn xem dưới dạng khung nhìn phụ của NavigationContoder.

[self.navigationController.navigationBar addSubview: overlayView)]

Bạn cũng có thể thêm nó qua cửa sổ:

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

Hi vọng điêu nay co ich.. :)


Chế độ xem đang đến nhưng khi thêm nút không thể nhận hành động nút hoặc đặt văn bản nhãn tùy chỉnh trên chế độ xem qua
Vineesh TP

Hoạt động tốt với tôi:let navigationBar = viewController.navigationController!.navigationBar navigationBar.addSubview(coverView)
Arthur Clemens

22

Giải pháp tuyệt vời của Dalef trong swift:

self.navigationController?.view.addSubview(view)

11

Câu trả lời của @ Nam hoạt động rất tốt nếu bạn chỉ muốn hiển thị chế độ xem tùy chỉnh của mình nhưng nếu chế độ xem tùy chỉnh của bạn cần tương tác với người dùng, bạn cần phải tắt tương tác chonavigationBar .

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

Giống như đã nói trong câu trả lời của Nam, đừng quên đảo ngược những thay đổi này:

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


Bạn có thể làm điều này theo cách tốt hơn với tiện ích mở rộng:

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

Và chỉ cần sử dụng nó như thế này:

self.navigationController.navigationBar.toggle()

1
Giải pháp hoàn hảo.. !! Đã thử rất nhiều thứ và dành rất nhiều thời gian .. nhưng điều này hoạt động tốt .. !!
Món ăn

8

Phiên bản Swift của câu trả lời của @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
}

Đừng quên rằng cửa sổ phải là một tài sản mạnh, bởi vì câu trả lời ban đầu dẫn đến sự sắp xếp ngay lập tức của cửa sổ


6

Tôi khuyên bạn nên tạo UIWindow mới:

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

Sau đó, bạn có thể quản lý chế độ xem của mình trong một UIViewControll khác. Để loại bỏ các cửa sổ:

[window removeFromSuperview];
window = nil;

Hy vọng rằng sẽ giúp!


3
Cảm ơn, nhưng tôi nghĩ thiếu một cái gì đó vì không có gì xuất hiện: /
Nicolas Roy

6

Có nhiều hơn một cách để làm điều đó:

1- Thêm bạn UIViewtrên UIWindowthay vì thêm nó vào UIViewController. Bằng cách này, nó sẽ ở trên tất cả mọi thứ.

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

2- Sử dụng chuyển đổi tùy chỉnh sẽ giữ cho UIViewContoder của bạn hiển thị ở phía sau với 0,5 alpha

Vì vậy, tôi khuyên bạn nên xem cái này: https://github.com/Citrrus/BlurryModalSegue


4
[[UIApplication sharedApplication].windows.lastObject addSubview:myView];

3

Trong Swift 4.2 và 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!)

Trong mục tiêu C

UIView * spinnerView; // Đây là chế độ xem của bạn

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

Điều này chỉ có thể hoạt động ở chế độ Chân dung HOẶC Cảnh.

Một mã đơn giản hơn là:

yourViewName.layer.zPosition = 1//Change you view name

2

Lưu ý nếu bạn muốn thêm chế độ xem trong Toàn màn hình thì chỉ sử dụng mã bên dưới

Thêm các phần mở rộng này của UIViewControll

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

Tiếp tục như quá trình thêm bình thường

Bây giờ sử dụng trong việc thêm viewDidAppear của UIViewContoder

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

     self.makeViewAsFullScreen()
}

1

Tôi sẽ sử dụng một lớp con UIViewContoder chứa "Chế độ xem Container" nhúng các bộ điều khiển xem khác của bạn. Sau đó, bạn sẽ có thể thêm bộ điều khiển điều hướng bên trong Chế độ xem Container (ví dụ sử dụng phân tách mối quan hệ nhúng).

Xem triển khai bộ điều khiển xem container


1
UIApplication.shared.keyWindow?.insertSubview(yourView, at: 1)

Phương pháp này hoạt động với xcode 9.4, iOS 11.4


0
[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];

nhập mô tả hình ảnh ở đây


0

Bạn cần thêm một khung nhìn vào cửa sổ đầu tiên với loại UITextEffectsWindow. Đầu tiên, vì bàn phím tùy chỉnh thêm UITextEffectsWindow của họ và nếu bạn thêm một khung nhìn vào nó, nó sẽ không hoạt động chính xác. Ngoài ra, bạn không thể thêm một khung nhìn phụ vào cửa sổ cuối cùng vì bàn phím chẳng hạn cũng là một cửa sổ và bạn không thể trình bày từ cửa sổ bàn phím. Vì vậy, giải pháp tốt nhất tôi tìm thấy là thêm chế độ xem phụ (hoặc thậm chí là bộ điều khiển chế độ xem đẩy) vào cửa sổ đầu tiên với loại UITextEffectsWindow, cửa sổ này bao gồm chế độ xem phụ kiện, thanh điều hướng - mọi thứ.

let myView = MyView()
myView.frame = UIScreen.main.bounds

guard let textEffectsWindow = NSClassFromString("UITextEffectsWindow") else { return }
let window = UIApplication.shared.windows.first { window in
    window.isKind(of: textEffectsWindow)
}
window?.rootViewController?.view.addSubview(myView)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.