我正在开发一款ios应用。我有一个主视图,在这个视图中 我试图提出一个模糊的视图控制器与暗灰色的背景(黑色与不透明度)。 问题是状态栏不受此颜色的影响并保持不变。
这是我呈现视图控制器的方式:
let shareViewController = self.storyboard?.instantiateViewControllerWithIdentifier("ShareViewController") as! ShareViewController
shareViewController.battle = battle
shareViewController.delegate = self
let animation = CATransition()
animation.duration = 1
animation.type = kCATransitionFade
self.view.window?.layer.addAnimation(animation, forKey: kCATransition)
presentViewController(shareViewController, animated: false) {
() in
// nothing here
}
以下是一些演示此问题的屏幕截图:
这是问题(状态栏颜色): Problem illustration 这是故事板中的模态视图: storyboard
答案 0 :(得分:8)
我无法重现您的问题,以下代码在我的单一视图应用中没有问题:
let viewController = UIViewController()
viewController.modalPresentationStyle = .overFullScreen
viewController.view.backgroundColor = UIColor.black.withAlphaComponent(0.5)
let animation = CATransition()
animation.duration = 1
animation.type = kCATransitionFade
self.view.window?.layer.add(animation, forKey: kCATransition)
self.present(viewController, animated: false, completion: nil)
但是请注意,您应该通过视图的根控制器进行演示。有时,当你从内部控制器出来时,你会得到奇怪的效果:
self.view.window?.rootViewController?.present(viewController, animated: false, completion: nil)
同时确保使用正确的modalPresentationStyle
。
答案 1 :(得分:1)
将视图控制器设置为UIWindow的根视图控制器,然后将窗口显示在UIWindowLevelAlert级别。
下面是一个 Swift 3 类,用于为所有其他UI元素(包括状态栏)设置模式弹出窗口的动画。稀松布视图用于遮蔽背景UI并拦截触摸以关闭视图。
import UIKit
class ModalViewController: UIViewController {
private let scrimView: UIView = {
let view = UIView()
view.translatesAutoresizingMaskIntoConstraints = false
view.backgroundColor = UIColor.black
view.alpha = 0.0
return view
}()
private var myWindow: UIWindow?
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.clear
// Setup scrim View
view.addSubview(scrimView)
view.topAnchor.constraint(equalTo: scrimView.topAnchor).isActive = true
view.leftAnchor.constraint(equalTo: scrimView.leftAnchor).isActive = true
view.rightAnchor.constraint(equalTo: scrimView.rightAnchor).isActive = true
view.bottomAnchor.constraint(equalTo: scrimView.bottomAnchor).isActive = true
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(dismiss as (Void) -> Void))
scrimView.addGestureRecognizer(tapGestureRecognizer)
// Layout custom popups or action sheets
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
UIView.animate(withDuration: 0.25) {
self.scrimView.alpha = 0.5
// Animate in custom popups or action sheets
}
}
func present() {
myWindow = UIWindow(frame: UIScreen.main.bounds)
myWindow?.windowLevel = UIWindowLevelAlert
myWindow?.backgroundColor = UIColor.clear
myWindow?.rootViewController = self
myWindow?.isHidden = false
}
func dismiss() {
UIView.animate(
withDuration: 0.25,
animations: {
self.scrimView.alpha = 0.0
// Animate out custom popups or action sheets
},
completion: { success in
self.myWindow = nil
}
)
}
}
展示视图:
let modalView = ModalViewController()
modalView.present()
要关闭视图,请点按稀松布上的任意位置。
答案 2 :(得分:0)
这个代码适用于我,当我用alpha表示[[1, 10], [13, 12]].map {|s, l| '[02/24/2016][03:37:27.996]'[s, l] }.join(' ') # => "02/24/2016 03:37:27.996"
'[02/24/2016][03:37:27.996]'.tr('[]', ' ').strip.squeeze(' ') # => "02/24/2016 03:37:27.996"
'[02/24/2016][03:37:27.996]'.gsub(/[\[\]]+/, ' ').strip # => "02/24/2016 03:37:27.996"
'[02/24/2016][03:37:27.996]'.scan(/[\d\/:.]+/).join(' ') # => "02/24/2016 03:37:27.996"
时!= 1.现在UIViewController
喜欢:
UIViewController
然后在let storyBoard = UIStoryboard(name: "Main", bundle: nil)
let destinationVC = storyBoard.instantiateViewController(withIdentifier: "AddComment") as! AddCommentViewController
destinationVC.modalPresentationStyle = .overCurrentContext //this line is important
destinationVC.delegate = self
destinationVC.restId = self.restaurant.id
self.present(destinationVC, animated: true, completion: nil)
视图控制器
destinationVC
并将其override func viewWillDisappear(_: Bool) {
UIView.animate(withDuration: 1, animations: { () in
self.view.backgroundColor = .clear
})
super.viewWillDisappear(true)
}
override func viewWillAppear(_: Bool) {
UIView.animate(withDuration: 1, animations: { () in
self.view.backgroundColor = UIColor.black.withAlphaComponent(0.5)
})
super.viewWillAppear(true)
}
设置为backgroundColor
或故事板中的.clear
。所以viewDidLoad
涵盖整个屏幕,包括状态栏。
答案 3 :(得分:0)
您可能非常实用,只需在模态视图控制器启动时隐藏状态栏:
override func prefersStatusBarHidden() -> Bool {
return true
}
答案 4 :(得分:0)
以下是您可能正在寻找的解决方案:
if let window = UIApplication.shared.keyWindow {
window.windowLevel = UIWindowLevelStatusBar + 1
}
此代码背后的主要思想是,您的应用程序的window
窗口级别低于状态栏窗口级别。这段代码的作用是,只需将窗口的窗口级别高于状态栏窗口级别,您的窗口现在可以覆盖状态栏。不要忘记,在呈现视图控制器之前,必须在主线程上调用此代码。祝你好运!
答案 5 :(得分:0)
应使用UIViewControllerAnimatedTransitioning执行自定义动画过渡。这是一个用于此目的的教程: https://www.raywenderlich.com/110536/custom-uiviewcontroller-transitions
如果你想要的只是一个淡入淡出动画,你可以通过改变你要显示的viewController的modalTransitionStyle
属性来获得它。
尝试以这种方式修复代码:
guard let shareViewController = self.storyboard?.instantiateViewControllerWithIdentifier("ShareViewController") as! ShareViewController else {
//Fallback in case of nil?
return
}
shareViewController.modalTransitionStyle = .crossDissolve
presentViewController(shareViewController, animated: true, completion: nil)
另请注意,presentViewController(shareViewController, animated: true, completion: nil)
适用于swift 2.等效的swift 3将为present(shareViewController, animated: true, completion: nil)
答案 6 :(得分:0)
您可以添加此代码以查看 Swift 3 :
的控制器let statusView: UIView = UIView(frame: CGRect(x: 0.0, y: -20.0, width: UIScreen.main.bounds.size.width, height: 20.0))
statusView.backgroundColor = UIColor.black
statusView.alpha = 0.8
self.addSubview(self.statusView)