首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >蒙面UIVisualEffectView在iOS 10上不起作用

蒙面UIVisualEffectView在iOS 10上不起作用
EN

Stack Overflow用户
提问于 2016-09-16 07:08:12
回答 5查看 5.2K关注 0票数 11

我开发了一款应用程序,它使用UIBlurEffectView在iOS 9和更低版本上工作得很好,但是当我升级我的设备(其中几个,而不仅仅是一个设备)时,模糊消失了,而不是模糊,因为某种原因出现了半透明的视图。

这门课有什么变化吗?有人知道为什么吗?

我的代码(视图是使用PocketSVG API获取的SVG文件中的一个形状):

代码语言:javascript
运行
复制
 let blur: UIBlurEffect = UIBlurEffect(style: .Light)
let ev: UIVisualEffectView = UIVisualEffectView(effect: blur)
ev.translatesAutoresizingMaskIntoConstraints = false
self.addSubview(ev)

ev.rightAnchor.constraintEqualToAnchor(self.rightAnchor).active = true
ev.bottomAnchor.constraintEqualToAnchor(self.bottomAnchor).active = true
ev.leftAnchor.constraintEqualToAnchor(self.leftAnchor).active = true
ev.heightAnchor.constraintEqualToAnchor(self.heightAnchor, multiplier: 1.5).active = true

let myPath: CGPathRef = PocketSVG.pathFromSVGFileNamed("CategoriesBar").takeUnretainedValue()

var transform: CGAffineTransform = CGAffineTransformMakeScale(self.frame.size.width / 754.0, self.frame.size.height / 220.0)

let transformedPath: CGPathRef = CGPathCreateMutableCopyByTransformingPath(myPath, &transform)!

let myShapeLayer = CAShapeLayer()
myShapeLayer.path = transformedPath
self.layer.mask = myShapeLayer

Leo的答案代码:

你的建议不起作用,下面是代码

代码语言:javascript
运行
复制
 override func layoutSubviews() {

        let blur: UIBlurEffect = UIBlurEffect(style: .Light)
        let ev: UIVisualEffectView = UIVisualEffectView(effect: blur)
        ev.translatesAutoresizingMaskIntoConstraints = false
        self.addSubview(ev)

        ev.rightAnchor.constraintEqualToAnchor(self.rightAnchor).active = true
        ev.bottomAnchor.constraintEqualToAnchor(self.bottomAnchor).active = true
        ev.leftAnchor.constraintEqualToAnchor(self.leftAnchor).active = true
        ev.heightAnchor.constraintEqualToAnchor(self.heightAnchor, multiplier: 1.5).active = true

        let myPath: CGPathRef = PocketSVG.pathFromSVGFileNamed("CategoriesBar").takeUnretainedValue()

        var transform: CGAffineTransform = CGAffineTransformMakeScale(self.frame.size.width / 754.0, self.frame.size.height / 220.0)

        let transformedPath: CGPathRef = CGPathCreateMutableCopyByTransformingPath(myPath, &transform)!

        let myShapeLayer = CAShapeLayer()
        myShapeLayer.path = transformedPath
        self.layer.mask = myShapeLayer

        let myMaskedView = UIView(frame: ev.frame)
        myMaskedView.layer.mask = myShapeLayer
        ev.maskView = myMaskedView
}

Konrad Siemczyk应答代码

代码语言:javascript
运行
复制
override func layoutSubviews() {

        let blur: UIBlurEffect = UIBlurEffect(style: .Light)
        let ev: UIVisualEffectView = UIVisualEffectView(effect: blur)
        ev.frame = self.bounds
        ev.translatesAutoresizingMaskIntoConstraints = false
        self.addSubview(ev)

        ev.rightAnchor.constraintEqualToAnchor(self.rightAnchor).active = true
        ev.bottomAnchor.constraintEqualToAnchor(self.bottomAnchor).active = true
        ev.leftAnchor.constraintEqualToAnchor(self.leftAnchor).active = true
        ev.heightAnchor.constraintEqualToAnchor(self.heightAnchor, multiplier: 1.5).active = true

        let myPath: CGPathRef = PocketSVG.pathFromSVGFileNamed("CategoriesBar").takeUnretainedValue()
        var transform: CGAffineTransform = CGAffineTransformMakeScale(self.frame.size.width / 754.0, self.frame.size.height / 220.0)

        let transformedPath: CGPathRef = CGPathCreateMutableCopyByTransformingPath(myPath, &transform)!

        let myShapeLayer = CAShapeLayer()
        myShapeLayer.path = transformedPath
        //self.layer.mask = myShapeLayer
        myShapeLayer.fillRule = kCAFillRuleEvenOdd

        let myMaskedView = UIView(frame: self.frame)
        myMaskedView.backgroundColor = UIColor.blackColor()
        myMaskedView.layer.mask = myShapeLayer
        ev.maskView = myMaskedView
    }
EN

回答 5

Stack Overflow用户

发布于 2016-09-21 08:51:33

嘿在实施这个之前..。

TLDR:请先检查此解决方案:

https://stackoverflow.com/a/67939549/2829540

..。尽管这些示例适用于较早版本的iOS,看起来较新的版本需要一个层而不是一个视图,但这个答案可能不像预期的那样有效。您可能需要为旧版本实现此解决方案,对于较新版本则需要实现链接解决方案。

为ObjectiveC用户提供的.

下面是iOS 10的一个工作示例,最后我还附加了结果视图。稍后,我将在顶部添加白色边框。裁剪的圆圈掩蔽在代码中,如果您喜欢的话,可以按原样使用它。

代码语言:javascript
运行
复制
// "self" in here is an UIView that contains some images inside.
{
  UIBlurEffect *blurEffect = [UIBlurEffect effectWithStyle:UIBlurEffectStyleLight];
  UIVisualEffectView *blurredEffectView = [[UIVisualEffectView alloc] initWithEffect:blurEffect];

  CGRect frame = self.frame;
  frame.origin = CGPointMake (0, 0);

  blurredEffectView.frame = frame;
  [self addSubview:blurredEffectView];

  UIView *maskView = [[UIView alloc] initWithFrame:frame];
  maskView.backgroundColor = [UIColor blackColor];

  __weak UIView *weak = self;
  maskView.layer.mask = ({ // This mask draws a rectangle and crops a circle inside it.
    __strong UIView *strong = weak;

    CGRect roundedRect = CGRectMake (
      0,
      0,
      strong.frame.size.width * 0.8f,
      strong.frame.size.width * 0.8f
    );
    roundedRect.origin.x = strong.frame.size.width / 2 - roundedRect.size.width / 2;
    roundedRect.origin.y = strong.frame.size.height / 2 - roundedRect.size.height / 2;

    CGFloat cornerRadius = roundedRect.size.height / 2.0f;

    UIBezierPath *path        = [UIBezierPath bezierPathWithRect:self.bounds];
    UIBezierPath *croppedPath = [UIBezierPath bezierPathWithRoundedRect:roundedRect cornerRadius:cornerRadius];
    [path appendPath:croppedPath];
    [path setUsesEvenOddFillRule:YES];

    CAShapeLayer *mask = [CAShapeLayer layer];
    mask.path     = path.CGPath;
    mask.fillRule = kCAFillRuleEvenOdd;
    mask;
  });

  blurredEffectView.maskView = maskView;
}

因此,这与Swift 3在操场上进行测试的代码相同.

这是在下载url时使用一次尝试,所以它是同步的。

代码语言:javascript
运行
复制
import UIKit
import PlaygroundSupport

let generalFrame = CGRect(x: 0, y: 0, width: 500, height: 500)

let containerView = UIView(frame: generalFrame)
containerView.backgroundColor = UIColor.black;
PlaygroundPage.current.liveView = containerView

let parentView = UIView(frame: generalFrame)
containerView.addSubview(parentView)

let url = URL(string: "https://static.pexels.com/photos/168066/pexels-photo-168066-large.jpeg")
let data = try Data(contentsOf: url!);

let imageView = UIImageView(frame:parentView.bounds)
imageView.image = UIImage(data: data)
imageView.contentMode = .scaleAspectFill

let maskView = UIView(frame:parentView.bounds)
maskView.backgroundColor = UIColor.black
maskView.layer.mask = {() -> CALayer in
    var  roundedRect = CGRect (
        x: 0.0,
        y: 0.0,
        width: parentView.bounds.size.width * 0.5,
        height: parentView.bounds.size.width * 0.5
    );
    roundedRect.origin.x = parentView.frame.size.width / 2 - roundedRect.size.width / 2;
    roundedRect.origin.y = parentView.frame.size.height / 2 - roundedRect.size.height / 2;
    
    let cornerRadius = roundedRect.size.height / 2.0;
    
    let path = UIBezierPath(rect:parentView.bounds)
    let croppedPath = UIBezierPath(roundedRect: roundedRect, cornerRadius: cornerRadius)
    path.append(croppedPath)
    path.usesEvenOddFillRule = true
    
    let maskLayer = CAShapeLayer()
    maskLayer.path = path.cgPath;
    maskLayer.fillRule = kCAFillRuleEvenOdd
    return maskLayer
}()

let blurView = UIBlurEffect(style: .light)
let effectView = UIVisualEffectView(effect: blurView)
effectView.frame = generalFrame

effectView.mask = maskView
parentView.addSubview(imageView)
parentView.addSubview(effectView)

和视图控制器中的工作示例:

这个先下载一个图像,然后附加模糊效果。

代码语言:javascript
运行
复制
import UIKit

class ViewController: UIViewController {

  func addTheBlurView(data :Data) {

    let generalFrame = self.view.bounds;
    let parentView = UIView(frame: generalFrame)
    self.view.addSubview(parentView)

    let imageView = UIImageView(frame: parentView.bounds)
    imageView.image = UIImage(data: data)
    imageView.contentMode = .scaleAspectFill

    let maskView = UIView(frame: parentView.bounds)
    maskView.backgroundColor = UIColor.black
    maskView.layer.mask = {
      () -> CALayer in
      var roundedRect = CGRect(
          x: 0.0,
          y: 0.0,
          width: parentView.bounds.size.width * 0.5,
          height: parentView.bounds.size.width * 0.5
          );
      roundedRect.origin.x = parentView.frame.size.width / 2 - roundedRect.size.width / 2;
      roundedRect.origin.y = parentView.frame.size.height / 2 - roundedRect.size.height / 2;

      let cornerRadius = roundedRect.size.height / 2.0;

      let path = UIBezierPath(rect: parentView.bounds)
      let croppedPath = UIBezierPath(roundedRect: roundedRect, cornerRadius: cornerRadius)
      path.append(croppedPath)
      path.usesEvenOddFillRule = true

      let maskLayer = CAShapeLayer()
      maskLayer.path = path.cgPath;
      maskLayer.fillRule = kCAFillRuleEvenOdd
      return maskLayer
    }()

    let blurView = UIBlurEffect(style: .light)
    let effectView = UIVisualEffectView(effect: blurView)
    effectView.frame = generalFrame

    effectView.mask = maskView
    parentView.addSubview(imageView)
    parentView.addSubview(effectView)

  }

  override func viewDidLoad() {
    debugPrint("Running...")

    super.viewDidLayoutSubviews();

    // Lets load an image first, so blur looks cool
    let url = URL(string: "https://static.pexels.com/photos/168066/pexels-photo-168066-large.jpeg")

    URLSession.shared.dataTask(with: url!) {
      (data, response, error) in

      if error != nil {
        print(error)
        return
      }

      DispatchQueue.main.async(execute: {
        self.addTheBlurView(data: data!)
      })

    }.resume()

  }
}

OBJECTIVEC版本

游乐场版

VIEWCONTROLLER版本

票数 6
EN

Stack Overflow用户

发布于 2016-09-25 13:41:27

如果您正在寻找SWIFT3.0中的蒙面视图和模糊解决方案,请查看下面的代码:

代码语言:javascript
运行
复制
class func addBlurredView(_ forView: UIView, centeredElement: UIView) {
    let blur = UIVisualEffectView(effect: UIBlurEffect(style: .light))
    blur.frame = forView.frame
    blur.isUserInteractionEnabled = false
    forView.addSubview(blur)

    let radius = centeredElement.bounds.width / 2
    let path = UIBezierPath (
        roundedRect: blur.frame,
        cornerRadius: 0)
    let circle = UIBezierPath (
        roundedRect: CGRect(origin: CGPoint(x: centeredElement.frame.origin.x, y: centeredElement.frame.origin.y),
                             size: centeredElement.frame.size), cornerRadius: radius)
    path.append(circle)
    path.usesEvenOddFillRule = true

    let maskLayer = CAShapeLayer()
    maskLayer.path = path.cgPath
    maskLayer.fillRule = kCAFillRuleEvenOdd

    let maskView = UIView(frame: forView.frame)
    maskView.backgroundColor = UIColor.black
    maskView.layer.mask = maskLayer

    blur.mask = maskView
}
票数 2
EN

Stack Overflow用户

发布于 2021-06-11 15:18:49

由于@emrahgunduz的回答,我成功地将上面的代码更新为SWIFT5.2。

代码语言:javascript
运行
复制
import UIKit
import PlaygroundSupport

let generalFrame = CGRect(x: 0, y: 0, width: 500, height: 500)
let containerView = UIView(frame: generalFrame)
containerView.backgroundColor = UIColor.black;

PlaygroundPage.current.liveView = containerView

let parentView = UIView(frame: generalFrame)
containerView.addSubview(parentView)

let url = URL(string: "https://static.pexels.com/photos/168066/pexels-photo-168066-large.jpeg")
let data = try Data(contentsOf: url!);

let imageView = UIImageView(frame:parentView.bounds)
imageView.image = UIImage(data: data)
imageView.contentMode = .scaleAspectFill
var  roundedRect = CGRect (
    x: 0.0,
    y: 0.0,
    width: parentView.bounds.size.width * 0.5,
    height: parentView.bounds.size.width * 0.5
);
roundedRect.origin.x = parentView.frame.size.width / 2 - roundedRect.size.width / 2;
roundedRect.origin.y = parentView.frame.size.height / 2 - roundedRect.size.height / 2;
let cornerRadius = roundedRect.size.height / 2.0;
let path = UIBezierPath(rect:parentView.bounds)
let croppedPath = UIBezierPath(roundedRect: roundedRect, cornerRadius: cornerRadius)
path.append(croppedPath)
path.usesEvenOddFillRule = true

let maskLayer = CAShapeLayer()
maskLayer.path = path.cgPath;
maskLayer.fillRule = CAShapeLayerFillRule.evenOdd
let blurView = UIBlurEffect(style: .light)
let effectView = UIVisualEffectView(effect: blurView)

effectView.frame = generalFrame
effectView.layer.mask = maskLayer

parentView.addSubview(imageView)
parentView.addSubview(effectView)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39525645

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档