I want to reuse header section all view controller scene .header section mean green view and label ("AMAR LIFE")
Here is my may 1st view controller scene
Here is my 1st view controller document outline
Subclass UITabBarController. Make the green view a subview of the tab bar controller's main view. Whenever the selected view controller changes (or anything else happens), keep bringing the green view to the front. (Even better, make the green view a layer, not a view, and give it a higher z-position so that it automatically floats in front of all subviews.)
Try the following steps to achieve your header visible on all views.
Step 1: Drag a navigationController into your storyBoard and delete tableView rootViewcontroller comes with the naviagtionController.Connect your NavigationController to your tabBarController.Now,NavigationController available to all your view.
Note: Your storyBoard layout should be look like a below image..
Step 2: Implement following code to your FirstTabBarController.
override func viewDidLoad() {
super.viewDidLoad()
// Apply transparency to NavigationBar.
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationController?.navigationBar.shadowImage = UIImage()
//Setting up scanView background
let barView = UIView(frame: CGRect(x:0, y:0, width:view.frame.width,height: (navigationController?.navigationBar.frame.height)! + UIApplication.shared.statusBarFrame.height))
barView.backgroundColor=UIColor.green // set any colour you want..
barView.layer.borderColor = UIColor.black.cgColor
barView.layer.borderWidth = 3
navigationController?.navigationBar.addSubview(barView)
//Setting up labelView
let label = UILabel()
label.frame = CGRect(x:25, y:5, width:view.frame.width - 50 , height:((navigationController?.navigationBar.frame.height)! + UIApplication.shared.statusBarFrame.height) - 10)
label.text = "AMAR LIFE"
label.textAlignment = .center
label.textColor = .black
label.font = UIFont(name: "HelveticaNeue-medium", size: CGFloat(40))
label.layer.borderColor = UIColor.black.cgColor
label.layer.borderWidth = 3
barView.addSubview(label)
}
Output:
you need to add the following method in every view controller
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(true)
self.navigationController?.isNavigationBarHidden = false
self.navigationController?.navigationBar.setBackgroundImage(#imageLiteral(resourceName: "123"), for: .default)
self.title = "Hi I am tittle"
}
Also if you want to avoid code duplication and do more good just create one parent UIview and write this method in it and then inherit it in all the other views. However both solutions work fine.
you can change the title and image according to your needs.
Thanks
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 have this view hierarchy on a view embedded in a UINavigationController:
When I scroll the UITableView the navigation bar is not moving up (the title is not becoming smaller) it stays like this:
If I remove the image view as background view everything works well.
My navigation is configured like this:
navigationItem.title = "Title here"
navigationItem.largeTitleDisplayMode = .always
navigationController?.navigationBar.prefersLargeTitles = true
navigationController?.navigationBar.shadowImage = UIImage()
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationController?.navigationBar.isTranslucent = true
navigationController?.navigationBar.tintColor = .white
navigationController?.navigationBar.barStyle = UIBarStyle.blackTranslucent
navigationController?.navigationBar.backgroundColor = .clear
A project demonstrating the problem is available here:
https://drive.google.com/file/d/181Aggala2ZfGN0lDjEtHWg0vobkM0iJc/view?usp=sharing
I already tried to change the insets of the tableview but it didn't work.
tableView.contentInset = UIEdgeInsets(top: navigationController?.navigationBar.height, left: 0, bottom: 0, right: 0)
Thanks!
As you discovered, to make large title fonts work as you want them to, the UIScrollView or any of its subclass needs to be the first element in the view hierarchy.
To fix your problem, you can try setting the background image to be the background of the UITableView directly.
Edit: Okay soo according to your comment you want a background behind everything including navigation bar. There is one way of achieving this and that is to subclass your UINavigationController and inside viewDidLoad:
override func viewDidLoad() {
super.viewDidLoad()
let image = UIImage(named: "wallpaper")
let imageView = UIImageView(image: image)
imageView.contentMode = .scaleAspectFill
imageView.frame = UIScreen.main.bounds
//this below part is important. Make sure to set it to 0 otherwise it will cover everything else
view.insertSubview(imageView, at: 0)
}
And then make sure your UIViewController containing the UITableView has a clear color for the UIView and remove the background image from that UIViewController
I have added a tabBarController and hooked it up to viewControllers and given the tabBarController its own class. It works, but I would like to customize it by changing the constraints so that it's not right at the bottom. From what I can see there's no way to add constraints in auto layout as it's all grayed out. I gave a shot at adding it programmatically, but nothing happens.
final class TabBarViewController: UITabBarController {
#IBOutlet var customTabBar: UITabBar!
override func viewDidLoad() {
self.selectedIndex = 2
let fontAttributes = [NSAttributedString.Key.font: UIFont.systemFont(ofSize: 20.0)]
UITabBarItem.appearance().setTitleTextAttributes(fontAttributes, for: .normal)
//This doesn't work
customTabBar.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
//Neither does this
self.tabBar.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
//Or this
if let tabC = self.tabBarController {
tabC.tabBar.bottomAnchor.constraint(equalTo: self.view.bottomAnchor).isActive = true
}
}
So how do I do this? I want the tabBar to be about 50p from the bottom.
You can create a container view controller to hold you UITabBarController.
Then, when you set the constraints on your container view, you can add 'padding' to the bottom, to have it go upwards. Below are two screenshots explaining the layout.
I have a UIViewController (named Friends) with a tableview and I want to display views above the Controller's view when the user is offline. This is how I create my views
class func showOffline(host: UIViewController) {
// showOffline image
var disconnectedImage = UIImage(named: "offlineIconGrey")
disconnectedImage = disconnectedImage?.imageWithRenderingMode(.AlwaysOriginal)
let imageView = UIImageView(image: disconnectedImage)
imageView.center = CGPoint(x: host.view.center.x,
y: host.view.center.y - imageView.frame.height/2)
// showOffline Label
let Label = UILabel(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
let labelText = "You appear to be offline \n Please connect to the internet"
Label.center = CGPoint(x: host.view.center.x,
y: imageView.center.y + 3*imageView.frame.height/4)
Label.numberOfLines = 0
Label.text = labelText
Label.textAlignment = .Center
Label.font = UIFont(name: (Label.font?.fontName)!, size: 14.0)
Label.sizeToFit()
Label.textColor = UIColor.whiteColor()
Label.lineBreakMode = .ByCharWrapping
Label.frame.offsetInPlace(dx: -Label.frame.size.width/2, dy: 0)
host.view.insertSubview(imageView, aboveSubview: host.view)
host.view.insertSubview(Label, aboveSubview: host.view)
}
Now it is my understanding, that the host view (host.view) should be the topmost view as that is shown on my storyboard; however, when I call my showOffline function like so
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
if !Reachability.isConnected() {
state = .Offline
} else {
state = .Default
}
}
where offline state calls,
General.showOffline(self)
like so
var state: State = .Default {
didSet {
switch (state) {
case .Default:
print("ViewMode = Default")
//query = ParseHelper.allUsers(updateList)
case .Search:
let searchText = searchBar?.text ?? ""
print(searchText)
//query = ParseHelper.searchUsers(searchText, completionBlock:updateList)
case .Offline:
General.showOffline(self)
searchBar.userInteractionEnabled = false
query = nil
users = [PFUser]() ?? []
print("ViewMode = Offline")
}
}
}
the views do not appear as the topmost views unless I am returning to the view controller (Friends) from a show segue. Otherwise, navigating to that view controller does not show the labels when it should? Am I missing something? I have tried to fix the problem by placing the views above the tableview but in that case the math for centering the views is off, probably because I am not loading any cells and I have a footer view as a UIView. I also tried adding the views to the tableview's footer view, but that didn't work either. What I DON'T want is to add the views to the navigation controller's view as I do not want that behavior, though I will do that if I have no other option.
This is what I want
Can someone please tell me what I am doing wrong or refer me to information that may help me fix my problem? Thanks!
host.view.insertSubview(imageView, aboveSubview: host.view)
This cannot work. You add a subview to host.view. The "aboveSubview" must be a subview of host.view. There are other methods for g
adding a subview.
When you call insertSubview:aboveSubview:, the view you give as second parameter must be a subview of the view you're inserting in. Here, it's the same view, so obviously it won't work.
Unless there are other views that should remain above the ones you're inserting, the easiest way is to just use addSubview:, which will make the new view topmost among the child of the target view.
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