I am trying to make a blurred background the UITabBar for my UITabViewController, and the idea is to have it be blurred and transparent so that the views underneath can be seen scrolling by.
Unfortunately I cannot for the life of me get the tab bar to be transparent. No matter what I do, there is always some black background to the tab bar that prevents the underlying view controllers from showing through.
If I change the alpha of the UITabBar to something low I can see that the tableview is indeed behind it, however you can see that the UITabBar has some sort of background to it that is preventing the tableview from fully showing through (and I don't want to bar button items to be invisible, just the tab bar background).
How can this be?
In the custom tab bar's view did load I have:
self.tabBar.translucent = true
self.tabBar.alpha = 0.3
self.tabBar.backgroundColor = UIColor.clearColor().colorWithAlphaComponent(0.0)
self.tabBar.layer.backgroundColor = UIColor.clearColor().colorWithAlphaComponent(0.0).CGColor
self.tabBar.backgroundImage = nil
self.tabBar.shadowImage = nil
and in the AppDelegate I have:
UITabBar.appearance().barTintColor = UIColor.clearColor()
UITabBar.appearance().tintColor = kColorAccent
UITabBar.appearance().translucent = true
UITabBar.appearance().translucent = true
UITabBar.appearance().backgroundColor = UIColor.clearColor()
UITabBar.appearance().backgroundImage = nil
UITabBar.appearance().layer.backgroundColor = UIColor.clearColor().CGColor
UITabBar.appearance().shadowImage = nil
...yeah It's excessive but I want to try everything.
Any ideas on what to do?
Make a UITabBar transparent
Assign a clear image to its backgroundImage. You can use a 1x1 clear.png, or create one programmatically:
self.backgroundImage = UIImage.imageWithColor(UIColor.clearColor())
This will make the UITabBar transparent:
Add a blur effect
Insert a UIVisualEffectView as the rearmost subview.
let frost = UIVisualEffectView(effect: UIBlurEffect(style: .Light))
frost.frame = self.bounds
self.insertSubview(frost, atIndex: 0)
This will insert a UIBlurEffect (frost):
Example
Set the Custom Class for the UITabBar of the Tab Bar Controller to FrostyTabBar.
You have a few options to supply a clearColor image. You can create a clear.png image with an alpha of 0. A programmatic elegant solution is described here.
If using a clear.png, assign it to the Background Image in the Attribute Inspector:
In Interface Builder, pick Style: Default & Translucent.
Once you take control of the background blur with a UIVisualEffectView, you can in turn supply any UIVisualEffect you so desire.
The entire FrostyTabBar class looks like this:
import UIKit
class FrostyTabBar: UITabBar {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
let frost = UIVisualEffectView(effect: UIBlurEffect(style: .light))
frost.frame = bounds
frost.autoresizingMask = .flexibleWidth
insertSubview(frost, at: 0)
}
}
► Find this solution on GitHub and additional details including a 1x1 clear.png on Swift Recipes.
I found a prefect solution, you only need to subclass UITabBar and then do the following actions to clean that annoying views
class MainTabBar: UITabBar {
var cleanDone = false
override func layoutSubviews() {
super.layoutSubviews()
self.deleteUnusedViews()
}
func deleteUnusedViews() {
if !self.cleanDone {
var removeCount = 0
for (_, eachView) in (self.subviews.enumerate()) {
if NSStringFromClass(eachView.classForCoder).rangeOfString("_UITabBarBackgroundView") != nil {
eachView.removeFromSuperview()
removeCount += 1
}
if NSStringFromClass(eachView.classForCoder).rangeOfString("UIImageView") != nil {
eachView.removeFromSuperview()
removeCount += 1
}
if removeCount == 2 {
self.cleanDone = true
break
}
}
}
}
}
the only solution that worked for me was this:
UITabBar.appearance().shadowImage = UIImage()
UITabBar.appearance().backgroundImage = UIImage()
and set: (you can do this in storyboard as well)
UITabBar.appearance().barTintColor = UIColor.clear
but what i have to set in storyboard is:
tabbar : translucent -> true
Related
After seeking a lot and trying many solutions, nope fixed my problem.
In my app I customized the UINavigationController in order to have blur effect:
import UIKit
class CustomNavigationController: UINavigationController {
override func viewDidLoad() {
super.viewDidLoad()
let visualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .regular))
visualEffectView.frame = (self.navigationBar.bounds.insetBy(dx: 0, dy: -40).offsetBy(dx: 0, dy: -40))
self.navigationBar.isTranslucent = true
self.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationBar.addSubview(visualEffectView)
self.navigationBar.sendSubviewToBack(visualEffectView)
}
}
Then in Main.storyboard I selected the customized class for the navigation controller item.
The blur effect works properly, the status icons are correctly visible, but not the standard navigation bar items: left button, title and right button.
For a moment they appears but soon after the customized navigation bar covers them.
I'm using Xcode 12.4 and I'm running the app on iPhone Xr.
How can I show the navigation bar elements again?
Thanks a lot in advance.
Translucent navigation bars in iOS already blur the content behind the bar, so you shouldn't need to add a UIVisualEffectView nor set a backgroundImage.
If you modify your code to just:
override func viewDidLoad()
{
super.viewDidLoad()
self.navigationBar.isTranslucent = true
}
does this not achieve the visual effect you're looking for?
If not, please try the following adjustment to your methodology:
override func viewDidLoad()
{
super.viewDidLoad()
self.navigationBar.isTranslucent = true
// create a UIImageView
let backgroundImage: UIImageView = UIImageView()
backgroundImage.autoresizingMask = [.flexibleWidth, .flexibleHeight]
backgroundImage.image = UIImage()
// add a blur effect to the ImageView
let visualEffectView: UIVisualEffectView = UIVisualEffectView(effect: UIBlurEffect(style: .regular))
visualEffectView.frame = (self.navigationBar.bounds.insetBy(dx: 0, dy: -40).offsetBy(dx: 0, dy: -40))
backgroundImage.addSubview (visualEffectView)
// and set that as your backgroundImage on the navigationBar
self.navigationBar.setBackgroundImage(backgroundImage.image, for: .default)
}
this adds the blur effect to the backgroundImage. This seems to work for me, but the visual effect is no different than just using my first suggestion, likely because backgroundImage.image == nil.
This is certainly an improved approach in that it doesn't add unexpected subviews into the UINavigationBar view hierarchy, and I observed both methods did not affect the visibility of the bar controls.
I'm implementing a custom Tab bar for my iOS app. Im using the following code to display a background image:
class TabNavigationMenu: UIView {
// ...
// ...
UIGraphicsBeginImageContext(self.frame.size)
UIImage(named: "tabBarbg.png")?.draw(in: self.bounds)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
if let image = image {
self.backgroundColor = UIColor(patternImage: image)
}
}
However, the tab bar is presented like this:
Also, when i make a view and present it anywhere else in the screen, it displays correctly. I'm using the same code there as well. Heres an example:
Any idea what the problem could be? I'm guessing the solution would also solve the faint blue line on top of the view...
You can try this to customize tab bar in ios
//Set the background color
UITabBar.appearance().backgroundColor = .red
tabBar.backgroundImage = UIImage(named: "tabBarbg.png")
//Set the item tint colors
tabBar.tintColor = .white
tabBar.unselectedItemTintColor = .lightGray
How do I set a transparent background for the sections index bar in a UITableView?
I've tried:
tableView.sectionIndexBackgroundColor = .clearColor()
but the bar gets a light grey background
EDIT
I've tried to change background color of the tableview but it doesn't seem to influence.
tableView.backgroundView = UIView.init()
tableView.backgroundColor = .blackColor() // tried .clearColor() too.
EDIT2
tableView.sectionIndexBackgroundColor = UIColor(white: CGFloat(1.0), alpha: CGFloat(0.5)) // change the alpha and check once
I've also tried a color with alpha values. I can make the background semi-transparent (see line code above). But if I set alpha to 0.0 to make it completely transparent, I get again the light grey background.
tableView.sectionIndexBackgroundColor = .clear works perfect
For swift 4.2 you must set viewBackground for your section and for that view set background color.
class CommonSection: UITableViewHeaderFooterView { static let
lightSectionColor = UIColor.gray.withAlphaComponent(0.005)
func setup(title: String, sectionColor: UIColor? = nil) {
textLabel?.text = title
textLabel?.font = UIFont.preferredFont(forTextStyle: .largeTitle)
guard let color = sectionColor else { return }
self.backgroundView = Init(value: UIView()) {
$0.backgroundColor = color
} } }
Note: Init just shortcut for initializing elements.
So in Xcode I'm trying to create a seamless search bar. So I'm trying to replicate something like this
Note how the status bar is the same color as the search bar. Now here's the result to my approach.
What I did was add a View to cover up the default status bar with the blue background. Then I added a search bar and changed it's background to blue. For some reason I end up getting a black border between the two, which ruins the "seamless" design. Any ideas on how I can remove the black border in Swift?
For iOS 7+:
searchBar.backgroundImage = UIImage()
Otherwise this will work on all iOS versions:
searchBar.layer.borderWidth = 1
searchBar.layer.borderColor = thatBlueColor.CGColor
Swift 4
searchBar.barTintColor = UIColor.white
searchBar.setBackgroundImage(UIImage.init(), for: UIBarPosition.any, barMetrics: UIBarMetrics.default)
Sample image
Upate Sample code for navigation bar and search bar background color:
Navigation bar color
self.navigationController?.navigationBar.barTintColor = .blue
Search bar color
searchBarProperty.backgroundColor = self.navigationController?.navigationBar.barTintColor
Note : Navigation bar and search bar color must be same.
Sample image with blue navigation bar and blue search bar
In Xcode 8.3 and Swift 3
Create an outlet from your search bar to your ViewController (I called mine searchBarOutlet for this example).
Below viewDidLoad insert the following.
self.searchBarOutlet.backgroundImage = UIImage()
You should have the following:
override func viewDidLoad() {
super.viewDidLoad()
self.searchBarOutlet.backgroundImage = UIImage()
When you run your app the lines will be gone (they will still be visible on storyboard).
In my case, beyond the edge of search bar needed to take the edge off also the navigation bar.
C# code:
NavigationController.NavigationBar.ShadowImage = new UIImage();
NavigationController.NavigationBar.SetBackgroundImage (new UIImage (), UIBarMetrics.Default);
Swift code:
self.navigationController.navigationBar.shadowImage = UIImage()
self.navigationController.navigationBar.setBackgroundImage(UIImage(), forBarMetrics: .Default)
The best solution to remove top and bottom default borders is:
To set a new empty searchBar background layout in viewDidLoad for example:
searchBar.backgroundImage = UIImage()
I found these answers to be more complicated than they needed to be. You can just modify the constraint that is binding the searchBar view and the other view to -1pts so that it overlaps exactly by the height of the searchBar's margin.
I encountered the same situation when I set the statusBar and searchBar translucent.
In this situation, I couldn't resolve with the answers written here however I could solve by the following approach.
put UIVisualEffectView on self.view (view of your VC)
make custom class of searchBar, which background is transparent
(also let statusBar transparent)
(swift4 code)
class TransparentSearchBar: UISearchBar {
override init(frame: CGRect) {
super.init(frame: frame)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
makeTransparentBackground()
}
private func makeTransparentBackground() {
for view in self.subviews {
view.backgroundColor = UIColor.clear
for subview in view.subviews {
if let imageview = subview as? UIImageView {
imageview.image = nil
}
}
}
}
}
somewhere in viewDidLoad (statusBar)
let statusWindow = UIApplication.shared.value(forKey:"statusBarWindow") as! UIView
let statusBar = statusWindow.subviews[0] as UIView
statusBar.backgroundColor = UIColor.clear
in Xcode 13
select the search bar and change the search Style to Minimal
How to change navigation controller's height without adding a toolbar ?
Here is an example of apple's iBooks app that I want to build.
I've a solution but isn't perfect( adding a toolbar below the nav controller but it is very ugly)
I think this is what you want,
screenshot
You can not change navbar height,but you can put a view under it,and use autolayout and shadow to make it looks like part of navbar.Set it to the class you made
Write a view to act as the extendbar
class ExtendNavView:UIView{
override func willMoveToWindow(newWindow: UIWindow?) {
let scale = UIScreen.mainScreen().scale
self.layer.shadowOffset = CGSizeMake(0, 1.0/scale)
self.layer.shadowRadius = 0;
self.layer.shadowColor = UIColor.blackColor().CGColor
self.layer.shadowOpacity = 0.25
}
}
Drag a UIView and put it under the navBar,then set autolayout to make it always under the nav
Change the navBar property in your viewController
class ViewController: UIViewController {
override func viewDidLoad() {
self.navigationController?.navigationBar.translucent = false
self.navigationController?.navigationBar.shadowImage = UIImage(named: "TransparentPixel")
self.navigationController?.navigationBar.setBackgroundImage(UIImage(named:"Pixel"), forBarMetrics:UIBarMetrics.Default)
}
}
The two image used here(Note:they are Translucent)
Pixel
url= "http://i.stack.imgur.com/gFwyN.png"
TransparentPixel
url = "http://i.stack.imgur.com/zpQw4.png "
You can also look at the Apple example project,you can also find the two images there
https://developer.apple.com/library/ios/samplecode/NavBar/Introduction/Intro.html