When my project was in Swift 2, I had this code that worked:
extension UINavigationController {
func hairLine(hide: Bool) {
//hides hairline at the bottom of the navigationbar
for subview in self.navigationBar.subviews {
if subview.isKind(of: UIImageView.self) {
for hairline in subview.subviews {
if hairline.isKind(of: UIImageView.self) && hairline.bounds.height <= 1.0 {
hairline.isHidden = hide
}
}
}
}
}
}
But now something changed and it doesn't work. Not sure if it because of Swift 3, or iOS10, or that I'm now testing with a 7plus vs a 6s, but it no longer works. I would call in it viewWillAppear of the view controller that is being shown. I saw an answer on here saying to use
UINavigationBar.appearance().shadowImage = UIImage()
UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default)
but that hasn't worked. I tried replacing the content of my old hairLine() with those 2 lines, tried putting them directly in viewWillAppear and viewDidAppear but still doesn't work for me.
Try this
self.navigationController?.navigationBar.setValue(true, forKey: "hidesShadow")
Before:
After:
Code:
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "Hello World"
let navbarColor = UIColor(colorLiteralRed: (247/255), green: (247/255), blue: (247/255), alpha: 1)
let image = UIImage()
navigationController?.navigationBar.setBackgroundImage(image, for: .default)
navigationController?.navigationBar.shadowImage = image
navigationController?.navigationBar.backgroundColor = navbarColor
let statusBarHeight = UIApplication.shared.statusBarFrame.height
let statusBarWidth = UIScreen.main.bounds.size.width
let statusBarView = UIView(frame: CGRect(x: 0, y: 0, width: statusBarWidth, height: statusBarHeight))
statusBarView.backgroundColor = navbarColor
view.addSubview(statusBarView)
}
Try:
self.navigationController?.navigationBar.setBackgroundImage(_:UIImage(),
for: .any,
barMetrics: .default)
self.navigationController?.navigationBar.shadowImage = UIImage()
in viewDidLoad()
Try this
UINavigationBar.appearance().setBackgroundImage(_:
nil,
for: .any,
barMetrics: .default)
UINavigationBar.appearance().shadowImage = nil
Related
I want to apply UINavigation custom background image and back button image also for iOS 14 everything is working fine but as I try to run the app on iOS 15 back button image not working instead it's showing the default back button which I want to replace with custom back button image I am using below code
if #available(iOS 15.0, *) {
let appearance = UINavigationBarAppearance()
appearance.configureWithTransparentBackground()
appearance.backgroundImage = image
appearance.setBackIndicatorImage(backButtonImage, transitionMaskImage: backButtonImage)
if Locale.current.languageCode == "fr" {
appearance.titleTextAttributes = [ NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 14), NSAttributedString.Key.foregroundColor: UIColor(hexString: "#231F20")]
} else {
appearance.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor(hexString: "#231F20")]
}
navigationItem.standardAppearance = appearance
navigationItem.scrollEdgeAppearance = appearance
} else {
self.navigationController?.navigationBar.setBackgroundImage(image, for: .default)
self.navigationController?.navigationBar.backIndicatorImage = backButtonImage
self.navigationController?.navigationBar.backIndicatorTransitionMaskImage = backButtonImage
if Locale.current.languageCode == "fr" {
self.navigationController?.navigationBar.titleTextAttributes = [ NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 14), NSAttributedString.Key.foregroundColor: UIColor(hexString: "#231F20")]
} else {
self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor(hexString: "#231F20")]
}
}
Sharing with you a common function I have made in a BaseViewController which is the superclass of all my View Controllers.
I Simply call the addBackButton function from viewDidLoad from any of the VC I want to add the back button.
It also handles the back navigation automatically. (takes care if you have presented or pushed a vc)
func addBackButton(tint : UIColor? = nil, backImage : UIImage? = Constants.Images.kImageForBackNavigation){
let buttonForBack = UIButton(type: .custom)
var tintColorForImage = UIColor.white
if tint != nil {
tintColorForImage = tint!
}
let image = backImage!.withRenderingMode(.alwaysTemplate)
buttonForBack.setImage(image, for: .normal)
buttonForBack.imageView?.tintColor = tintColorForImage
buttonForBack.frame = CGRect(x: 0, y: 0, width: 30, height: 30)
buttonForBack.addTarget(self, action: #selector(BaseViewController.closeViewController), for: .touchUpInside)
let barButtonItemForClose = UIBarButtonItem(customView: buttonForBack)
self.navigationItem.setLeftBarButton(barButtonItemForClose, animated: false)
}
#objc func closeViewController(){
if self == self.navigationController?.children.first {
DispatchQueue.main.async {
self.navigationController?.dismiss(animated: true, completion: nil);
}
}
else{
DispatchQueue.main.async {
self.navigationController?.popViewController(animated: true)
}
}
}
I want to customize UINavigationBar for some view controllers. For some reasons, I cannot just simply extend UIViewController. So I was trying to do it by a protocol.
What I have tried:
protocol TransparentNavigationBarProtocol {
func makeNavigationBarTransparent()
}
extension TransparentNavigationBarProtocol where Self: UIViewController {
func makeNavigationBarTransparent() {
if let navController = navigationController {
navController.navigationBar.setBackgroundImage(UIImage(), for: .default)
navController.navigationBar.shadowImage = UIImage()
navController.navigationBar.tintColor = UIColor.white
navController.navigationBar.barStyle = .blackTranslucent
navController.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
navController.navigationBar.backgroundColor = .clear
}
}
}
I added some breakpoints which show the function had been called successfully but the navigationBar didn't change. So I was wondering is it possible to achieve this by protocols?
For Xcode11, you need set a image, not nil
Also, in your viewcontroller's viewWillAppear, you need call makeNavigationBarTransparent()
func makeNavigationBarTransparent() {
if let navController = navigationController {
navController.navigationBar.setBackgroundImage(UIImage(), for: .default)
navController.navigationBar.shadowImage = UIImage()
navController.navigationBar.tintColor = UIColor.init(red: 74/255, green: 74/255, blue: 74/255, alpha: 1)
navController.navigationBar.barStyle = .default
navController.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor(red: 74/255, green: 74/255, blue: 74/255, alpha: 1)]
}
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
makeNavigationBarTransparent()
}
I know there are a lot of questions out there on this topic; however, none of those answers have helped me and I have tried so many ways of going about solving this. My problem is that my bar button will not show up, originaly, but when the viewcontroller is presented later on in the app it will show up then but the navigation title won't show up. I'm not sure why that is, but I believe it has something to do with the SwipeNavigationController framework that I'm using. My goal is to have the button show up as it's supposed to when the user swipes left to get to that view, and also when the view is later called and presented to look the same. The code for adding the navItem is below:
let cameraBarButton = UIBarButtonItem(image: #imageLiteral(resourceName: "cameraIcon"), style: .plain, target: self, action: #selector(goToCamera))
navigationItem.rightBarButtonItem = cameraBarButton
Please look at this other post to get a little better understanding of the framework. As well as here is the code on how I set up the navigation bar:
override func viewDidLoad() {
super.viewDidLoad()
setupView()
let barHeight: CGFloat = UIApplication.shared.statusBarFrame.size.height
let displayWidth: CGFloat = self.view.frame.width
let displayHeight: CGFloat = self.view.frame.height
messagesTableView = UITableView(frame: CGRect(x: 0, y: barHeight, width: displayWidth, height: displayHeight - barHeight))
messagesTableView.register(BlankCell.self, forCellReuseIdentifier: blankCellID)
messagesTableView.dataSource = self
messagesTableView.delegate = self
self.view.addSubview(messagesTableView)
view.backgroundColor = UIColor.white
setupNavButtons()
setupNavBar()
showNoMessagesLabel()
navigationController?.isNavigationBarHidden = false
if #available(iOS 11.0, *) {
navigationController?.navigationBar.prefersLargeTitles = true
self.navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
} else {
// Fallback on earlier versions
}
}
override func viewWillAppear(_ animated: Bool) {
if #available(iOS 11.0, *) {
navigationController?.navigationBar.prefersLargeTitles = true
self.navigationController?.navigationBar.largeTitleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
setupNavBar()
} else {
setupNavBar()
}
}
func setupNavBar() {
UIApplication.shared.statusBarStyle = .lightContent
self.navigationController?.isNavigationBarHidden = false
self.navigationController?.navigationBar.topItem?.title = "Messages"
self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
self.navigationController?.navigationBar.barTintColor = UIColor.pinkNeonColor
self.navigationController?.navigationBar.tintColor = UIColor.white
}
func setupNavButtons() {
let cameraButton = UIButton(type: .system)
cameraButton.setImage(#imageLiteral(resourceName: "cameraIcon").withRenderingMode(.alwaysOriginal), for: .normal)
cameraButton.frame = CGRect(x: 0, y: 0, width: 34, height: 34)
navigationItem.leftBarButtonItem = UIBarButtonItem(customView: cameraButton)
}
I am gating my problem in IOS 8 but my code working in IOS 9 . I have create one Transparent button and add subview in Tabbar method. The Problem is button event not working when tabar load second time and this is problem in IOS 8 , but its working good in ISO 9. Here is my code
Delegate
var button_ofTabbar = UIButton();
//var button_ofTabbar:UIButton!;
//UIButton();= UIButton(type: UIButtonType.System)
In Tabbar
class tabbar: UITabBarController,UITabBarControllerDelegate {
//let button_ofTabbar = UIButton();
var delegate1: AppDelegate!
let aDataBase : databaseinit = databaseinit()
override func viewDidLoad() {
super.viewDidLoad()
UITabBar.appearance().tintColor = UIColor(red: 242/255.0, green: 134/255.0, blue: 55/255.0, alpha: 1.0)
self.delegate=self;
delegate1 = UIApplication.sharedApplication().delegate as! AppDelegate
UITabBar.appearance().barTintColor = UIColor.whiteColor()
if(delegate1.tag_jive_channel_tab == 0)
{
// delegate1.button_ofTabbar.removeFromSuperview();
// delegate1.button_ofTabbar.setTitleColor(UIColor.blackColor(), forState: UIControlState.Normal)
delegate1.button_ofTabbar.hidden = false;
let widthofbtn:CGFloat = self.tabBar.frame.size.width/5;
delegate1.button_ofTabbar.frame = CGRectMake(0, self.tabBar.frame.origin.y, widthofbtn, self.tabBar.frame.size.height)
delegate1.button_ofTabbar.backgroundColor = UIColor.redColor()//clearColor()
//delegate1.button_ofTabbar = UIButton(type: UIButtonType.System)
delegate1.button_ofTabbar.tintColor = UIColor.redColor()//clearColor()
delegate1.button_ofTabbar.addTarget(self, action: "gotoShowChannel11", forControlEvents: UIControlEvents.TouchUpInside)
self.view.addSubview(delegate1.button_ofTabbar);
}
}
override func viewDidAppear(animated: Bool) {
}
func gotoShowChannel11() {
delegate1.button_ofTabbar.hidden = true;
//orangeColor tabbar
//self.tabBarController?.tabBar.tintColor = UIColor.redColor();
delegate1.tag_jive_channel_tab = 1;
NSNotificationCenter.defaultCenter().postNotificationName("update_tabbar", object: nil,
userInfo: nil);
//UIColor(red: 146/255.0, green: 146/255.0, blue: 146/255.0, alpha: 1.0)
}
When i use this line delegate1.button_ofTabbar = UIButton(type: UIButtonType.System) then my button is not show custom/System in both
i am also try this func gotoShowChannel11(sender: UIButton!)
Please help me . i am stuck in IOS 8 Problem . and Error is
ERROR- [__NSCFData gotoShowChannel11]
Please any one Help me .
Now I have found another solution . Thankyou .
My Custom Activity indicator is not overlapping Navigation controller.
Below is my code
func showActivityIndicator(uiView: UIView) {
container.frame = uiView.frame
container.center = uiView.center
container.backgroundColor = UIColorFromHex(0xffffff, alpha: 0.1)
var loadingView: UIView = UIView()
loadingView.frame = CGRectMake(0, 0, self.view.frame.width, self.view.frame.height)
loadingView.center = uiView.center
loadingView.backgroundColor = UIColorFromHex(0x444444, alpha: 0.5)
loadingView.clipsToBounds = true
loadingView.layer.cornerRadius = 10
var imageData = NSData(contentsOfURL: NSBundle.mainBundle()
.URLForResource("synch-loader", withExtension: "gif")!)
let try = UIImage.animatedImageWithData(imageData!)
var imageView = UIImageView(image: try)
imageView.center = uiView.center
imageView.frame = CGRect(x: uiView.frame.width/4, y: uiView.frame.height/2, width: 500, height: 15)
loadingView.addSubview(imageView)
container.addSubview(loadingView)
uiView.addSubview(container)
actInd.startAnimating()
}
func navigationHandling()
{
if self.navigationController != nil {
self.navigationController?.navigationBar.tintColor = utility.uicolorFromHex(0x70B420)
self.navigationController?.navigationBar.barTintColor = utility.uicolorFromHex(0x70B420)
self.navigationController?.navigationBarHidden = false
self.navigationItem.hidesBackButton = true
}
sortingBtn = UIBarButtonItem(image: sortingImg, style: UIBarButtonItemStyle.Done, target: self, action: Selector("sortingPressed:"))
menuBtn = UIBarButtonItem(image: menuImg, style: UIBarButtonItemStyle.Plain, target: self, action : nil)
sortingBtn.tintColor = UIColor.whiteColor()
menuBtn.tintColor = UIColor.whiteColor()
var buttons : NSArray = [menuBtn,sortingBtn]
self.navigationItem.rightBarButtonItems = buttons as [AnyObject]
self.navigationItem.setRightBarButtonItems([menuBtn,sortingBtn], animated: true)
networkLabel.hidden = true
}
I just want to overlap the view on navigation controller so that it don't looks ugly.
I appreciate help!
let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate
let window = appDelegate?.window
window.addSubview("yourActivityIndicator")
Here add the activity indicator to the window, or pass the window in as the view.
let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate
let window = appDelegate?.window
showActivityIndicator(window)
The uiView you're passing as parameter to this method
func showActivityIndicator(uiView: UIView)
is your ViewController's view or your UINavigationController's view?
Because if it's your UIViewController's view your custom loading will take it's size and origin, that is under your NavigationBar