Добавьте UIView превыше всего, даже панель навигации
Я хочу отобразить поверх любых других видов, даже панели навигации, своего рода "всплывающее" представление, которое выглядит следующим образом:
- полноэкранный черный фон с 0,5 альфа, чтобы увидеть другой
UIViewController
под. UIView
окно посередине с некоторой информацией, (календарь, если вы хотите знать все).
Для этого я создал UIViewController, который содержит два UIViews
(фон и окно), и я пытаюсь отобразить его. Я попробовал простой [mySuperVC addSubview:myPopUpVC.view]
, но у меня все еще есть панель навигации выше.
Я пытался представить его как модальный, но UIViewController
под ним исчезает, и я теряю эффект прозрачности.
Любая идея сделать это, я уверен, что это довольно просто...
Спасибо!
16 ответов
Вы можете сделать это, добавив свой вид непосредственно в keyWindow:
UIView *myView = /* <- Your custom view */;
UIWindow *currentWindow = [UIApplication sharedApplication].keyWindow;
[currentWindow addSubview:myView];
[self.navigationController.view addSubview:overlayView];
это то, что вы действительно хотите
Вот простое элегантное решение, которое работает для меня. Вы можете установить z положение навигационной панели ниже вида:
self.navigationController.navigationBar.layer.zPosition = -1;
Просто не забудьте установить его обратно на 0, когда закончите.
Версии 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)
Далеф отличное решение в Свифте:
self.navigationController?.view.addSubview(view)
Добавьте свой вид как подпредставление NavigationController.
[self.navigationController.navigationBar addSubview: overlayView)]
Вы также можете добавить его через окно:
UIView *view = /* Your custom view */;
UIWindow *window = [UIApplication sharedApplication].keyWindow;
[window addSubview:view];
Надеюсь это поможет..:)
Ответ @Nam отлично работает, если вы просто хотите отобразить свой пользовательский вид, но если ваш пользовательский вид требует взаимодействия с пользователем, вам нужно отключить взаимодействие для navigationBar
,
self.navigationController.navigationBar.layer.zPosition = -1
self.navigationController.navigationBar.isUserInteractionEnabled = false
Как сказано в ответе Нэма, не забудьте отменить эти изменения:
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
}
}
}
И просто используйте это так:
self.navigationController.navigationBar.toggle()
Быстрая версия ответа @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
}
Не забывайте, что окно должно быть сильным свойством, потому что оригинальный ответ приводит к немедленному освобождению окна
Существует несколько способов сделать это:
1- Добавьте свой UIView
на UIWindow
вместо того, чтобы добавить его на UIViewController
, Таким образом, это будет поверх всего.
[[(AppDelegate *)[UIApplication sharedApplication].delegate window] addSubview:view];
2- Используйте пользовательский переход, который будет показывать ваш UIViewController сзади с альфа 0,5
Для этого я рекомендую вам взглянуть на это: https://github.com/Citrrus/BlurryModalSegue
Я рекомендую вам создать новое окно 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];
Затем вы можете управлять своим представлением в другом UIViewController. Чтобы удалить окна:
[window removeFromSuperview];
window = nil;
надеюсь, что это поможет!
[[UIApplication sharedApplication].windows.lastObject addSubview:myView];
В Swift 4.2 и 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!)
В цели C
UIView * spinnerView; // Это ваш взгляд
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];
Это может работать только в портретном или ландшафтном режиме.
Обратите внимание, если вы хотите добавить вид в полноэкранном режиме, используйте только приведенный ниже код
Добавьте эти расширения UIViewController
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
}
}
}
Продолжайте как обычно добавляя процесс subview
Теперь используйте при добавлении viewDidAppear UIViewController
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
self.makeViewAsFullScreen()
}
Я бы использовал подкласс UIViewController, содержащий "представление контейнера", которое встраивает ваши контроллеры представления других. После этого вы сможете добавить контроллер навигации в представление "Контейнер" (например, с помощью перехода в формате embed).
UIApplication.shared.keyWindow?.insertSubview(yourView, at: 1)
Этот метод работает с xcode 9.4, iOS 11.4
Вам нужно добавить подвид к первому окну с типом UITextEffectsWindow. К первому, потому что пользовательские клавиатуры добавляют свой UITextEffectsWindow, и если вы добавите к нему подпредставление, это не будет работать правильно. Кроме того, вы не можете добавить подпредставление к последнему окну, потому что клавиатура, например, также является окном, и вы не можете представлять из окна клавиатуры. Итак, лучшее решение, которое я нашел, - добавить subview (или даже push view controller) в первое окно с типом UITextEffectsWindow, это окно охватывает вспомогательный вид, панель навигации - все.
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)
[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];