While creating my own app I faced to a similar problem. I do not use IB at all, so everything is done programatically. I looked into the UIVisualEffectView.h and it does not provide any effect change on the fly (hopefully this will change in the future).
So here is my solution (I'm using the latest Swift version, so there is an as! operator):
class CustomVisualEffectView : UIVisualEffectView
{
deinit
{
println("UIVisualEffectView will be destroyed.")
}
}
class ViewController: UIViewController
{
var _blurEffect = UIBlurEffect() // global so you can use it for vibrancy effect view as well
var _blurredEffectView = CustomVisualEffectView()
let _someSubView = UIView()
let _someOtherSubView = UIView()
let _effectChanger = UIButton.buttonWithType(.System) as! UIButton
override func viewDidLoad()
{
super.viewDidLoad()
self.view.backgroundColor = UIColor.orangeColor()
/* create a button to change the effect */
_effectChanger.setTitle("Change effect!", forState: UIControlState.Normal)
_effectChanger.frame.size = CGSize(width: 100, height: 20)
_effectChanger.center = self.view.center
_effectChanger.addTarget(self, action: Selector("buttonClicked"), forControlEvents: UIControlEvents.TouchUpInside)
self.view.addSubview(_effectChanger)
/* here is our effect view */
_blurEffect = UIBlurEffect(style: self.randomBlurEfffectStyle())
_blurredEffectView = CustomVisualEffectView(effect: _blurEffect)
self.layoutEffectView()
self.view.addSubview(_blurredEffectView)
/* create two subviews and put them on the effect view */
_someSubView.frame = CGRectMake(10, 10, 10, 10)
_someSubView.backgroundColor = UIColor.redColor()
_blurredEffectView.contentView.addSubview(_someSubView)
_someOtherSubView.frame = CGRectMake(30, 30, 10, 10)
_someOtherSubView.backgroundColor = UIColor.greenColor()
_blurredEffectView.contentView.addSubview(_someOtherSubView)
}
func layoutEffectView()
{
_blurredEffectView.frame.size = CGSize(width: 100, height: 80)
_blurredEffectView.center = CGPointMake(_effectChanger.center.x, _effectChanger.center.y - 50)
}
func buttonClicked()
{
var tempArray = [AnyObject]()
/* get all subviews from the effect view */
for view in _blurredEffectView.contentView.subviews
{
tempArray.append(view)
view.removeFromSuperview()
}
/* modify your effect view */
_blurEffect = UIBlurEffect(style: self.randomBlurEfffectStyle())
/* IMPORTANT: so the old effect view can be destroyed by arc */
_blurredEffectView.removeFromSuperview()
_blurredEffectView = CustomVisualEffectView(effect: _blurEffect)
/* I think this will be really tricky if you will use auto layout */
self.layoutEffectView()
self.view.addSubview(_blurredEffectView)
/* put all subviews back to the effect view*/
for view in tempArray
{
_blurredEffectView.contentView.addSubview(view as! UIView)
}
}
func randomBlurEfffectStyle() -> UIBlurEffectStyle
{
let randomBlurEffectStyle : UIBlurEffectStyle
switch Int(arc4random_uniform(3)) // [0,1,2]
{
case 0:
randomBlurEffectStyle = .ExtraLight
case 1:
randomBlurEffectStyle = .Light
default:
randomBlurEffectStyle = .Dark
}
return randomBlurEffectStyle
}
}