Title pretty much asks it all...
题目问的都是……
I'm playing with the iOS8 Visual Effect View with Blur
. It's over a UIImageView
that shows a user choosable background photo. The view placed in the contentView itself is my own custom view, shows a sort of graph/calendar. Most of said calendar graph is transparent. The blur it applies to the photo behind it is really heavy. I'd like to let more of the detail leak through. But Apple only seems to give three canned values:
我正在用模糊处理iOS8视觉效果视图。它通过一个UIImageView显示一个用户可选择的背景照片。放置在contentView中的视图是我自己的自定义视图,显示了一种图形/日历。大多数日历图是透明的。它对照片后面的模糊是非常重的。我想让更多的细节泄露出去。但苹果似乎只给出了三种固定价值:
typedef enum {
UIBlurEffectStyleExtraLight,
UIBlurEffectStyleLight,
UIBlurEffectStyleDark
} UIBlurEffectStyle;
I've monkied around with different alphas and background colors of the UIVisualEffectView
(even though the documentation warns against that), but that doesn't do anything but make it worse.
我使用了不同的alphas和UIVisualEffectView的背景颜色(尽管文档中警告了这一点),但这并没有起到任何作用,只会让事情变得更糟。
23
The reason you're getting heavy blur is that the blur effect style affects the brightness level of the image, not the amount of blur applied.
你得到重模糊的原因是模糊效果风格影响图像的亮度水平,而不是应用的模糊数量。
Unfortunately, although Apple clearly has the ability to control the amount of blur applied programmatically--try dragging down slowly on the launchpad to watch the Spotlight blurring transition--I don't see any public API to pass a blur amount to UIBlurEffect
.
不幸的是,尽管苹果显然有能力控制以编程方式应用的模糊数量——试着在launchpad上缓慢地拖下鼠标来观看Spotlight模糊转换——但我没有看到任何公共API将模糊数量传递给UIBlurEffect。
This post claims that adjusting the background color alpha will drive the blur amount. It's worth a try, but I don't see where that is documented: How to fade a UIVisualEffectView and/or UIBlurEffect in and out?
这篇文章声称调整背景色alpha将会驱动模糊量。它值得一试,但是我不知道它在哪里被记录:如何淡入一个UIVisualEffectView和/或UIBlurEffect ?
30
It's a pity that Apple did not provide any options for blur effect. But this workaround worked for me - animating the blur effect and pausing it before completion.
遗憾的是,苹果没有提供任何模糊效果的选择。但是这个变通方法对我起了作用——使模糊效果动画化,并在完成之前暂停它。
func blurEffectView(enable enable: Bool) {
let enabled = self.blurView.effect != nil
guard enable != enabled else { return }
switch enable {
case true:
let blurEffect = UIBlurEffect(style: .ExtraLight)
UIView.animateWithDuration(1.5) {
self.blurView.effect = blurEffect
}
self.blurView.pauseAnimation(delay: 0.3)
case false:
self.blurView.resumeAnimation()
UIView.animateWithDuration(0.1) {
self.blurView.effect = nil
}
}
}
and the UIView extensions for pausing (with a delay) and resuming view's animation
以及用于暂停(有延迟)和恢复视图动画的UIView扩展
extension UIView {
public func pauseAnimation(delay delay: Double) {
let time = delay + CFAbsoluteTimeGetCurrent()
let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, time, 0, 0, 0, { timer in
let layer = self.layer
let pausedTime = layer.convertTime(CACurrentMediaTime(), fromLayer: nil)
layer.speed = 0.0
layer.timeOffset = pausedTime
})
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, kCFRunLoopCommonModes)
}
public func resumeAnimation() {
let pausedTime = layer.timeOffset
layer.speed = 1.0
layer.timeOffset = 0.0
layer.beginTime = layer.convertTime(CACurrentMediaTime(), fromLayer: nil) - pausedTime
}
}
6
This works for me.
这适合我。
I put UIVisualEffectView
in an UIView
before add to my view.
我将UIVisualEffectView放在UIView中,然后添加到我的视图中。
I make this function to use easier. You can use this function to make blur any area in your view.
我使这个函数更容易使用。您可以使用这个函数使您的视图中的任何区域模糊。
func addBlurArea(area: CGRect, style: UIBlurEffectStyle) {
let effect = UIBlurEffect(style: style)
let blurView = UIVisualEffectView(effect: effect)
let cOntainer= UIView(frame: area)
blurView.frame = CGRect(x: 0, y: 0, width: area.width, height: area.height)
container.addSubview(blurView)
container.alpha = 0.8
self.view.insertSubview(container, atIndex: 1)
}
For example, you can make blur all of your view by calling:
例如,你可以通过调用:
addBlurArea(self.view.frame, style: UIBlurEffectStyle.Dark)
You can change Dark
to your desired blur style and 0.8
to your desired alpha value
你可以把暗调到你想要的模糊样式,0.8调到你想要的alpha值
4
Yes you can.
是的,你可以。
Here is an example of a UIImageView with blur effect on it. Remember to add a Image to the UIImageView.
这是一个使用模糊效果的UIImageView的例子。记住向UIImageView添加一个图像。
Adjust blur amount with blurEffectView.alpha = 0.8 (from 0 to 1)
使用blurEffectView调整模糊数量。= 0.8(从0到1)
import UIKit
class BlurEffectImageView: UIImageView {
override func awakeFromNib() {
addBlurEffect()
super.awakeFromNib()
}
private func addBlurEffect(){
let blurEffect = UIBlurEffect(style: .light)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.alpha = 0.8
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
blurEffectView.translatesAutoresizingMaskIntoCOnstraints= false
addSubview(blurEffectView)
NSLayoutConstraint(item: blurEffectView, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1.0, constant: 0).isActive = true
NSLayoutConstraint(item: blurEffectView, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1.0, constant: 0).isActive = true
NSLayoutConstraint(item: blurEffectView, attribute: .height, relatedBy: .equal, toItem: self, attribute: .height, multiplier: 1.0, constant: 0).isActive = true
NSLayoutConstraint(item: blurEffectView, attribute: .width, relatedBy: .equal, toItem: self, attribute: .width, multiplier: 1.0, constant: 0).isActive = true
}
}
1
Add a BlurEffectView to a view with view's alpha <1
向视图的alpha <1的视图中添加BlurEffectView
func addBlurEffectView() -> Void {
if !UIAccessibilityIsReduceTransparencyEnabled() {
let viewCOntainer= UIView()
viewContainer.frame = self.view.bounds
viewContainer.alpha = 0.5
let blurEffect = UIBlurEffect(style: .dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.layer.zPosition = -0.5;
blurEffectView.frame = self.view.bounds;
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
viewContainer.addSubview(blurEffectView)
self.view.addSubview(viewContainer)
self.view.sendSubview(toBack: viewContainer)
}
}
0
This answer is based on Mitja Semolic's excellent earlier answer. I've converted it to swift 3, added an explanation to what's happening in coments, made it an extension of a UIViewController so any VC can call it at will, added an unblurred view to show selective application, and added a completion block so that the calling view controller can do whatever it wants at the completion of the blur.
这个答案是基于Mitja Semolic早先出色的回答。我迅速转换到3,添加一个解释发生的事情的言论,使它的扩展ui所以任何VC可以称之为,添加一个横行无忌视图中显示选择应用程序,并添加一块完成,以便调用视图控制器可以做任何它想要完成的模糊。
import UIKit
//This extension implements a blur to the entire screen, puts up a HUD and then waits and dismisses the view.
extension UIViewController {
func blurAndShowHUD(duration: Double, message: String, completion: @escaping () -> Void) { //with completion block
//1. Create the blur effect & the view it will occupy
let blurEffect = UIBlurEffect(style: UIBlurEffectStyle.light)
let blurEffectView = UIVisualEffectView()//(effect: blurEffect)
blurEffectView.frame = self.view.bounds
blurEffectView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
//2. Add the effect view to the main view
self.view.addSubview(blurEffectView)
//3. Create the hud and add it to the main view
let hud = HudView.getHUD(view: self.view, withMessage: message)
self.view.addSubview(hud)
//4. Begin applying the blur effect to the effect view
UIView.animate(withDuration: 0.01, animations: {
blurEffectView.effect = blurEffect
})
//5. Halt the blur effects application to achieve the desired blur radius
self.view.pauseAnimationsInThisView(delay: 0.004)
//6. Remove the view (& the HUD) after the completion of the duration
DispatchQueue.main.asyncAfter(deadline: .now() + duration) {
blurEffectView.removeFromSuperview()
hud.removeFromSuperview()
self.view.resumeAnimationsInThisView()
completion()
}
}
}
extension UIView {
public func pauseAnimationsInThisView(delay: Double) {
let time = delay + CFAbsoluteTimeGetCurrent()
let timer = CFRunLoopTimerCreateWithHandler(kCFAllocatorDefault, time, 0, 0, 0, { timer in
let layer = self.layer
let pausedTime = layer.convertTime(CACurrentMediaTime(), from: nil)
layer.speed = 0.0
layer.timeOffset = pausedTime
})
CFRunLoopAddTimer(CFRunLoopGetCurrent(), timer, CFRunLoopMode.commonModes)
}
public func resumeAnimationsInThisView() {
let pausedTime = layer.timeOffset
layer.speed = 1.0
layer.timeOffset = 0.0
layer.beginTime = layer.convertTime(CACurrentMediaTime(), from: nil) - pausedTime
}
}
I've confirmed that it works with both iOS 10.3.1 and iOS 11
我已经确认它可以与ios10.3.1和ios11兼容
0
A solution similar to some here, but simpler, is to use a UIViewPropertyAnimator (iOS 10+) and set its fractionComplete
property to some value between 0 and 1.
一个类似于这里的解决方案,但更简单,就是使用UIViewPropertyAnimator (ios10 +)并将其fractionComplete属性设置为0到1之间的某个值。
// add blur view to image view
let imgBlur = UIVisualEffectView()
imgView.addSubview(imgBlur)
imgBlur.frame = imgView.bounds
// create animator to control blur strength
let imgBlurAnimator = UIViewPropertyAnimator()
imgBlurAnimator.addAnimations {
imgBlur.effect = UIBlurEffect(style: .dark)
}
// 50% blur
imgBlurAnimator.fractiOnComplete= 0.5
Note, if you plan to vary fractionComplete
based on a pan gesture, scroll view, slider, etc. you'll want to set pausesOnCompletion= true
(iOS 11+).
注意,如果您打算根据pan手势、滚动视图、滑动条等改变fractionComplete,您需要设置pausesOnCompletion= true (ios11 +)。