Ios 如何将UIBlurEffect与模态视图控制器一起使用?
我有一个Ios 如何将UIBlurEffect与模态视图控制器一起使用?,ios,iphone,objective-c,user-interface,Ios,Iphone,Objective C,User Interface,我有一个UIViewController,它以模式显示另一个UIViewController。我希望模态视图控制器具有iOS 7引入的模糊/透明度。我尝试使用新的UIVisualEffect,但它似乎只适用于UIViews,而不适用于UIViewControllers 这是我写的代码,我作为子视图添加的所有视图都是我希望在用户界面中位于模糊视图上方的视图 在演示视图控制器中,我拍摄了一个屏幕截图,在应用模糊之前,我将其传递给模态视图控制器 在显示视图控制器时: - (UIImage *)view
UIViewController
,它以模式显示另一个UIViewController
。我希望模态视图控制器具有iOS 7引入的模糊/透明度。我尝试使用新的UIVisualEffect
,但它似乎只适用于UIViews
,而不适用于UIViewControllers
这是我写的代码,我作为子视图添加的所有视图都是我希望在用户界面中位于模糊视图上方的视图
在演示视图控制器中,我拍摄了一个屏幕截图,在应用模糊之前,我将其传递给模态视图控制器
在显示视图控制器时:
- (UIImage *)viewImage {
CGSize size = CGSizeMake(self.view.frame.size.width,self.view.frame.size.height);
UIGraphicsBeginImageContext(size);
[self.view drawViewHierarchyInRect:(CGRect){CGPointZero, self.view.frame.size.width, self.view.frame.size.height} afterScreenUpdates:YES];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:[[UIImageView alloc] initWithImage:self.backgroundImage]];
//self.backgroundImage is the image that the method above returns, it's a screenshot of the presenting view controller.
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
[blurEffectView setFrame:self.view.bounds];
[self.view addSubview:blurEffectView];
[self.view bringSubviewToFront:self.cancelButton];
[self.view bringSubviewToFront:self.titleLabel];
[self.view bringSubviewToFront:self.tableView];
}
import UIKit
let IMAGE_OVERLAY_NAME = "backgroundColorExample"
class YOUTransparentModalVC: UIViewController
{
private var backgroundImageOverlayIV:UIImageView!
override func viewDidLoad()
{
super.viewDidLoad()
self.setupTransparentView()
self.setupDissmissingVCOnTap()
self.setupBackgroudImage()
}
private func setupTransparentView()
{
self.view.backgroundColor = UIColor.clearColor()
let effect = UIBlurEffect(style: UIBlurEffectStyle.Light)
let blurView = UIVisualEffectView(effect: effect)
blurView.frame = self.view.bounds
self.view.addSubview(blurView)
}
private func setupBackgroudImage()
{
self.backgroundImageOverlayIV = UIImageView(frame: self.view.frame)
self.backgroundImageOverlayIV.image = UIImage(named: IMAGE_OVERLAY_NAME)
self.view.addSubview(self.backgroundImageOverlayIV)
}
private func setupDissmissingVCOnTap()
{
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "dismissVC")
view.addGestureRecognizer(tap)
}
func dismissVC()
{
self.dismissViewControllerAnimated(true, completion: nil)
}
}
在模态视图控制器中:
- (UIImage *)viewImage {
CGSize size = CGSizeMake(self.view.frame.size.width,self.view.frame.size.height);
UIGraphicsBeginImageContext(size);
[self.view drawViewHierarchyInRect:(CGRect){CGPointZero, self.view.frame.size.width, self.view.frame.size.height} afterScreenUpdates:YES];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:[[UIImageView alloc] initWithImage:self.backgroundImage]];
//self.backgroundImage is the image that the method above returns, it's a screenshot of the presenting view controller.
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
[blurEffectView setFrame:self.view.bounds];
[self.view addSubview:blurEffectView];
[self.view bringSubviewToFront:self.cancelButton];
[self.view bringSubviewToFront:self.titleLabel];
[self.view bringSubviewToFront:self.tableView];
}
import UIKit
let IMAGE_OVERLAY_NAME = "backgroundColorExample"
class YOUTransparentModalVC: UIViewController
{
private var backgroundImageOverlayIV:UIImageView!
override func viewDidLoad()
{
super.viewDidLoad()
self.setupTransparentView()
self.setupDissmissingVCOnTap()
self.setupBackgroudImage()
}
private func setupTransparentView()
{
self.view.backgroundColor = UIColor.clearColor()
let effect = UIBlurEffect(style: UIBlurEffectStyle.Light)
let blurView = UIVisualEffectView(effect: effect)
blurView.frame = self.view.bounds
self.view.addSubview(blurView)
}
private func setupBackgroudImage()
{
self.backgroundImageOverlayIV = UIImageView(frame: self.view.frame)
self.backgroundImageOverlayIV.image = UIImage(named: IMAGE_OVERLAY_NAME)
self.view.addSubview(self.backgroundImageOverlayIV)
}
private func setupDissmissingVCOnTap()
{
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "dismissVC")
view.addGestureRecognizer(tap)
}
func dismissVC()
{
self.dismissViewControllerAnimated(true, completion: nil)
}
}
使用UIVisualEffectView时,不需要生成快照。尝试删除“-(UIImage*)viewImage”,然后在模型视图控制器中添加大小与视图控制器视图匹配的UIVisualEffectView,并将所有“控制”视图添加到UIVisualEffectView的contentView中
- (void)viewDidLoad {
[super viewDidLoad];
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
[blurEffectView setFrame:self.view.bounds];
[self.view addSubview:blurEffectView];
[blurEffectView.contentView addSubview:self.cancelButton];
[blurEffectView.contentView addSubview:self.titleLabel];
[blurEffectView.contentView addSubview:self.tableView];
}
我还没有在故事板上尝试过,但这里有一个经过测试的工作片段。也许是个好的开始。翻译成objc应该很简单
这是演示视图控制器
import UIKit
class BaseViewController: UIViewController {
init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
override func viewDidLoad() {
super.viewDidLoad()
var backgroundImage = UIImageView(image: UIImage(named: "image"))
self.view.addSubview(backgroundImage)
var button = UIButton(frame: CGRectMake(0, 100, 320, 50))
button.setTitle("Lorem Ipsum", forState: UIControlState.Normal)
button.backgroundColor = UIColor.redColor()
button.addTarget(self, action: "onButtonTapped:", forControlEvents: UIControlEvents.TouchUpInside)
self.view.addSubview(button)
}
func onButtonTapped(sender: UIButton?) {
var modal = ModalViewController(nibName: nil, bundle: nil)
modal.modalPresentationStyle = UIModalPresentationStyle.OverCurrentContext
self.presentViewController(modal, animated: true, completion: {})
}
}
这是模态分析
import UIKit
class ModalViewController: UIViewController {
init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
}
override func viewDidLoad() {
super.viewDidLoad()
self.view.backgroundColor = UIColor.clearColor()
let effect = UIBlurEffect(style: UIBlurEffectStyle.Light)
let blurView = UIVisualEffectView(effect: effect)
blurView.frame = self.view.bounds
self.view.addSubview(blurView)
}
}
看看我的示例项目,其中我仅使用故事板和约束来演示模糊效果
GitHub演示:感谢@YarGnawh。这在iOS 8上进行了测试
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
[blurEffectView setFrame:self.view.bounds];
self.tableView.backgroundView = blurEffectView;
这是上述答案的组合 这适用于iOS 9.2.1的Xcode 7.2.1(Swift 2.1.)中的界面生成器 代码已经在模拟器和设备上进行了测试 在界面生成器中:
- (UIImage *)viewImage {
CGSize size = CGSizeMake(self.view.frame.size.width,self.view.frame.size.height);
UIGraphicsBeginImageContext(size);
[self.view drawViewHierarchyInRect:(CGRect){CGPointZero, self.view.frame.size.width, self.view.frame.size.height} afterScreenUpdates:YES];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:[[UIImageView alloc] initWithImage:self.backgroundImage]];
//self.backgroundImage is the image that the method above returns, it's a screenshot of the presenting view controller.
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
[blurEffectView setFrame:self.view.bounds];
[self.view addSubview:blurEffectView];
[self.view bringSubviewToFront:self.cancelButton];
[self.view bringSubviewToFront:self.titleLabel];
[self.view bringSubviewToFront:self.tableView];
}
import UIKit
let IMAGE_OVERLAY_NAME = "backgroundColorExample"
class YOUTransparentModalVC: UIViewController
{
private var backgroundImageOverlayIV:UIImageView!
override func viewDidLoad()
{
super.viewDidLoad()
self.setupTransparentView()
self.setupDissmissingVCOnTap()
self.setupBackgroudImage()
}
private func setupTransparentView()
{
self.view.backgroundColor = UIColor.clearColor()
let effect = UIBlurEffect(style: UIBlurEffectStyle.Light)
let blurView = UIVisualEffectView(effect: effect)
blurView.frame = self.view.bounds
self.view.addSubview(blurView)
}
private func setupBackgroudImage()
{
self.backgroundImageOverlayIV = UIImageView(frame: self.view.frame)
self.backgroundImageOverlayIV.image = UIImage(named: IMAGE_OVERLAY_NAME)
self.view.addSubview(self.backgroundImageOverlayIV)
}
private func setupDissmissingVCOnTap()
{
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "dismissVC")
view.addGestureRecognizer(tap)
}
func dismissVC()
{
self.dismissViewControllerAnimated(true, completion: nil)
}
}
UIViewController
的viewdiload
中设置第3步将不起作用UIViewController
,然后在Custom Class
“-Class
下为其命名YOUTransparentModalVC
(或任何您想要的名称)- (UIImage *)viewImage {
CGSize size = CGSizeMake(self.view.frame.size.width,self.view.frame.size.height);
UIGraphicsBeginImageContext(size);
[self.view drawViewHierarchyInRect:(CGRect){CGPointZero, self.view.frame.size.width, self.view.frame.size.height} afterScreenUpdates:YES];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.view addSubview:[[UIImageView alloc] initWithImage:self.backgroundImage]];
//self.backgroundImage is the image that the method above returns, it's a screenshot of the presenting view controller.
UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
UIVisualEffectView *blurEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];
[blurEffectView setFrame:self.view.bounds];
[self.view addSubview:blurEffectView];
[self.view bringSubviewToFront:self.cancelButton];
[self.view bringSubviewToFront:self.titleLabel];
[self.view bringSubviewToFront:self.tableView];
}
import UIKit
let IMAGE_OVERLAY_NAME = "backgroundColorExample"
class YOUTransparentModalVC: UIViewController
{
private var backgroundImageOverlayIV:UIImageView!
override func viewDidLoad()
{
super.viewDidLoad()
self.setupTransparentView()
self.setupDissmissingVCOnTap()
self.setupBackgroudImage()
}
private func setupTransparentView()
{
self.view.backgroundColor = UIColor.clearColor()
let effect = UIBlurEffect(style: UIBlurEffectStyle.Light)
let blurView = UIVisualEffectView(effect: effect)
blurView.frame = self.view.bounds
self.view.addSubview(blurView)
}
private func setupBackgroudImage()
{
self.backgroundImageOverlayIV = UIImageView(frame: self.view.frame)
self.backgroundImageOverlayIV.image = UIImage(named: IMAGE_OVERLAY_NAME)
self.view.addSubview(self.backgroundImageOverlayIV)
}
private func setupDissmissingVCOnTap()
{
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "dismissVC")
view.addGestureRecognizer(tap)
}
func dismissVC()
{
self.dismissViewControllerAnimated(true, completion: nil)
}
}
斯威夫特3
我发现,如果你正在做一个到新UIViewController的模式转换,并将其置于背景清晰的上下文中,这样你就可以看到最后一个VC。使用IB中设置的UIVisualEffect视图无法正常工作。你将得到的是在新视图演示结束时呈现的模糊
在界面生成器中:
建立一个模态序列到另一个视图,使种类:模态呈现,过渡:交叉淡入。然后给它一个标识符,如“showMainMenu”
在目标VC中,将其设置为第一个视图为UIImageView,并设置AspectToFit,将约束的每侧边设置为0-0-0-0。第二个子视图为UIImageView,将VC的每侧边设置为0-0-0-0。
然后将元素放在视图的顶部,就像漂亮的对比文本一样
为背景创建一个变量,将其设置为将要连接到的VC的UIImageView
变量背景:UIImage!=UIImage()
现在运行segue,你会注意到模糊突然出现,看起来很糟糕
要解决此问题,请编写一些代码,使用此UIImage扩展代码拍摄快照
extension UIImage {
class func takeScreenshot(view: UIView) -> UIImage? {
// Create screenshot
UIGraphicsBeginImageContext(view.bounds.size)
view.layer.render(in: UIGraphicsGetCurrentContext()!)
let screenshot:UIImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()
print("Taking Screenshot")
UIGraphicsEndImageContext()
return screenshot
}
}
然后在我的序列中,我执行以下操作:
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showMainMenu" {
let vc = segue.destination as! MainViewController
// I am using a VERY long scroll view so self.view.window! ensures that you only take a picture of your actual view instead of a view that is longer than your screen size.
let screenshot: UIImage = UIImage.takeScreenshot(view: self.view.window!)!
vc.background = screenshot
}
}
一旦分段,请在新的视图控制器中确保运行此命令
// set the image over to the background image.
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
self.backgroundImage.image = background
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// prevent the blurView for just popping in due to the segue
UIView.animate(withDuration: 0.3, delay: 0.0, options: .curveEaseInOut, animations: {
// make the background transparent so you can now see what is beneath that layer.
self.backgroundImage.alpha = 0
})
}
这样你就可以在没有太多代码的情况下获得甜美的模式IB淡入!另外,如果你在当前VC下的最后一个VC上有移动元素,你可以在模糊下看到它
希望这有帮助
请随意在我的git中签出一个演示项目
最简单的方法就是在viewDidLoad中复制并粘贴此代码:)
ios-7-style-blur-view,它给了我一个空白的背景,下面没有模糊的东西。我希望显示它的视图控制器在下面可见但模糊。你如何显示模式?@ProgramGuy检查上面更新的代码。注意!
modal.modalPresentationStyle=UIModalPresentationStyle.OverCurrentContext
Good调用OverCurrentContext
,在情节提要中甚至没有看到该选项!界面生成器方式:在IB中,选择segue,在属性检查器中,有一个名为Presentation
的选项,您可以在当前上下文中选择。