UITableViewController Blur Background Not Showing With Scroll - ios

I have set a background image for my UITableViewController and then added a blur effect with the following code:
var blur = UIBlurEffect(style: UIBlurEffectStyle.Dark)
var blurView = UIVisualEffectView(effect: blur)
blurView.frame = self.view.bounds
self.view.insertSubview(blurView, atIndex: 0)
When I scroll down, the background image is still there but the blur effect is only there for the first few cells that fit into the view at a time. How can I make it so the blur effect is there as I scroll?
I tried adding the blur effect to each cell, but that makes it look really weird.

For UITableViewControllers self.view is the UITableView it self. That means any subview you add to self.view will scroll along with the content of the table view.
You could either make an own UIViewController, set up UITableView manually and place it in front of the blur view (instead of placing the blur view inside the table view) or you could move the blur view's location when the table view is scrolled.
To move the blur view to compensate for the table view's offset you can do something like this:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
var blurViewFrame = CGRect()
blurViewFrame.size = view.bounds.size
blurViewFrame.y = tableView.contentOffset.y
blurView.frame = blurViewFrame
}

Related

Blur effect does not fill the entire View

I have a View controller that features a full screen UIImageView. When the controller loads, I just set a blur effect over the whole screen. The content mode for the UIImageView is set to scaleAspectFill. I set the blur effect like this:
#IBOutlet weak var previewImage: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
previewImage.image = userPhoto
let blur = UIVisualEffectView(effect: UIBlurEffect(style: .Light))
blur.frame = self.view.bounds
previewImage.addSubview(blur)
}
when I test the app on an iPhone 6 I get this result:
There's an offset on the right an I can't figure out why. The picture underneath if is properly full screened but I can get the blur effect to fit over it...
****EDITED****
I applied the blur effect to the VC's view directly and now it works just fine, but I'd like to know why it doesn't work when I add the subview to the UIImage View...
I see two possible problems here:
Views are not laid out on the viewDidLoad stage. In this case you can force them to layout manualy:
override func viewDidLoad() {
super.viewDidLoad()
self.view.layoutIfNeeded()
...
}
You add subview to the previewImage, not to the root view. You must check your storyboard, or fix code:
override func viewDidLoad() {
super.viewDidLoad()
previewImage.image = userPhoto
let blur = UIVisualEffectView(effect: UIBlurEffect(style: .Light))
blur.frame = self.view.bounds
self.view.insertSubview(blur, aboveSubview: previewImage)
}
Based on #kelin answer. You can even add the blur effect above your image in the interface builder.Just search for Visual Effect View with Blur in the objects section in the interface builder. Then add the Visual Effect View view above your image. It is also fully customizable through Attributes inspector. That way you you make sure that the blur will occupy the entire screen. It is also cleaner from architecture perspective , you do not need to configure your view through code.

Adding Subview To UIViewController Makes UITablview Subview Disappear

This code is called inside of a function that is called programatically. The UITableView that it is inserted over has been put in the UIViewController in a storyboard. The UIViewController is embedded in a navigationController.
let containerView = UIView()
containerView.frame.size.width = self.view.frame.width / 2
containerView.frame.size.height = self.view.frame.width / 2
let blurEffect = UIBlurEffect(style: .Dark)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = containerView.bounds
containerView.center = self.view.center
containerView.addSubview(blurEffectView)
self.view.insertSubview(containerView, aboveSubview: matchTableView)
indicator?.startAnimation()
I'm just trying to add an activity indicator over the tableview. The actual activity indicator shows up just fine but I need to put a background behind it so it can be seen correctly. As soon as any type of subview is added to the UIViewController the table disappears.
Have you tried:
let containerView = UIView()
...
containerView.opaque = false
containerView.backgroundColor = UIColor.clearColor()
The tableView is disappearing because you are inserting the container view
above it .
You nedd to add your activity indictor above the table view , where the activity indicator view frame is less than the table view frame
matchTableView.addSubView(containerView)
Previously I had been adding the subview in a function long after the view rendered itself. The way to get this done was to add the view in viewDidAppear. After that I could manipulate it any way I needed. Any period after viewDidAppear in the life cycle and the tableView disappears. I don't know why or if this is the correct way to avoid that issue but this works as a solution.
Adding it in viewDidLoad does not add it to the render tree. It will be there but it will have been too early for it to display properly.

UIBlurEffectView smaller than autolayouted parentView although identical frame

I have an UIView for login purposes centered in the middle of the screen. It is constrained to a 0.25 height of the surrounding view (covering the whole window)
I noticed, that if I create an UIVisualEffectView (via the method blurBackgroundForView(_)as background for the UIView, that it is too small (check the code how I create the UIVisualEffectView) although it has the same frame.
You can see the effect, when you change the backgroundColor to .greenColor.
The View is higher than the Blureffect.
ViewController
override func viewWillAppear(animated: Bool) {
AnimationHelper.blurBackgroundForView(self.view)
view.backgroundColor = .greenColor()
}
blurBackgroundForView(_)
static func blurBackgroundForView(view: UIView!){
view.backgroundColor = .clearColor()
let blurEffect = UIBlurEffect(style: .Light)
let blurEffectView = UIVisualEffectView(effect: blurEffect)
blurEffectView.frame = view.bounds
view.insertSubview(blurEffectView, atIndex: 0)
}
Frames are not guaranteed to be set by auto layout in viewWillAppear.
Try setting the blur view's frame in viewDidLayoutSubviews instead. Alternatively, you can directly set the autoresizing mask on your blur view so that it resizes when its superview resizes:
blurView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
You should also call the super method in viewWillAppear.

Adding gradient to scrolling UITableView

I was able to add a gradient my UITableView, but I have the issue of when I have to scroll through my cells, the gradient background scrolls along also. I want the background to stay consistent as I scroll up or down. How can I achieve this? Do I have to create a custom UITableView in order to do this?
The pictures below show what it currently looks like.
Here is my code for adding the gradient to the UITableView:
func addGradientToBackground(){
var gradient : CAGradientLayer = CAGradientLayer()
gradient.frame = self.tableView.bounds
gradient.colors = [UIColor.blueColor().CGColor, UIColor.redColor().CGColor]
self.tableView.layer.insertSublayer(gradient, atIndex: 0)
}
Messing around will setting the gradient doesn't work either, like setting:
self.view.layer.insertSublayer(gradient, atIndex: 0)
or changing the bounds:
gradient.frame = self.tableView.frame
Also, in cellForRowAtIndexPath I set the UITableViewCells background color to clear:
cell.backgroundColor = UIColor.clearColor()
I can't add images, but here is the link if you wish to see them: http://imgur.com/Vtka1tO,6faLMkr#0
The gradient needs to be behind the table view if you don't want it to scroll. If you're using a UITableViewController, the only thing behind is the window, so you could give it the gradient, and make the cells and the table view have a clear background color. If you're using a UIViewController with a table view as a subview, then you could give the controller's main view a gradient background color.
Have you thought to add a background image as follows?
var imageView = UIImageView(frame: CGRectMake(10, 10, cell.frame.width - 10, cell.frame.height - 10))
let image = UIImage(named: ImageNames[indexPath.row])
imageView.image = image
cell.backgroundView = UIView()
cell.backgroundView.addSubview(imageView)

Using UIScrollView with UIVisualEffectView (UIBlurEffect) in Swift

I'm using UIBlurEffect from UIVisualEffectView to produce the look introduced in iOS 7. To do so I programmatically add anything I want portrayed on top of the blur to the contentView, as described in the UIBlurEffect Class Reference:
A UIBlurEffect object applies a blurring effect to the content layered
behind a UIVisualEffectView. Views added to the contentView of a
UIVisualEffectView are not affected by the blur effect.
But now I need to add a UIScrollView into the mix, and the fact that I had to use the contentView has left me completely confused. I'm not very familiar with the UIScrollView, but the iOS 8 Swift Programming Cookbook gives this example:
I'm not in need of displaying an imageView, but instead a separate view with many views inside of it in the hierarchy. Where exactly do I add the scrollView? Do I set scrollView as a subview of contentView? Or the other way around, the contentView as a subview of scrollView? Here's my current code:
class InfoVC: UIViewController {
#IBOutlet weak var contentView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// blur
let blur = UIVisualEffectView(effect: UIBlurEffect(style: UIBlurEffectStyle.Light))
blur.frame = view.frame
view.addSubview(blur)
blur.contentView.addSubview(self.contentView)
}
You want to scroll something on top of the blur effect, correct?
In that case you need to add the scroll view to the content view of the blur view.
Assuming the contentView is the view you want to scroll it should work like this:
let blur = UIVisualEffectView(effect: UIBlurEffect(style: UIBlurEffectStyle.light))
blur.frame = view.bounds
view.addSubview(blur)
UIScrollView scrollView = UIScrollView(frame:blur.bounds)
blur.contentView.addSubview(scrollView)
scrollView.addSubview(contentView)
scrollView.contentSize = contentView.frame.size // or whatever other size you like

Resources