J'ai une application qui a parfois besoin de la barre de navigation pour se fondre dans le contenu.
Est-ce que quelqu'un sait comment se débarrasser de cette petite barre ennuyante ou en changer de couleur?
Sur l'image ci-dessous la situation que j'ai - je parle de cette ligne de hauteur 1px en dessous de "Root View Controller"
Pour ce faire, vous devez définir une image d'ombre personnalisée. Mais pour que l'image de l'ombre soit affichée, vous devez également définir une image d'arrière-plan personnalisée, citez-le dans la documentation d'Apple:
Pour qu'une image d'ombre personnalisée soit affichée, une image d'arrière-plan personnalisée doit également être définie avec la méthode setBackgroundImage (_: for :). Si l'image d'arrière-plan par défaut est utilisée, elle sera utilisée quelle que soit la valeur de cette propriété.
Alors:
let navigationBar = navigationController!.navigationBar
navigationBar.setBackgroundImage(#imageLiteral(resourceName: "BarBackground"),
for: .default)
navigationBar.shadowImage = UIImage()
Ci-dessus, le seul moyen "officiel" de le cacher. Malheureusement, cela supprime la translucidité de la barre.
Vous avez ces options:
Couleur unie, pas de translucidité:
navigationBar.barTintColor = UIColor.redColor()
navigationBar.isTranslucent = false
navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationBar.shadowImage = UIImage()
Créez une petite image d'arrière-plan remplie de couleur et utilisez-la.
Utilisez la méthode 'hacky' décrite ci-dessous. Il gardera également la barre translucide.
Pour conserver la transparence, vous avez besoin d'une autre approche. Cela ressemble à un hack mais fonctionne bien. L'ombre que nous essayons de supprimer est une ligne de cheveux UIImageView
quelque part sous UINavigationBar
. Nous pouvons le trouver et le masquer/le montrer en cas de besoin.
Les instructions ci-dessous supposent que vous avez besoin de cheveux fins cachés dans un seul contrôleur de votre hiérarchie UINavigationController
.
Déclarer une variable d'instance:
private var shadowImageView: UIImageView?
Ajouter une méthode qui trouve cette ombre (délié) UIImageView:
private func findShadowImage(under view: UIView) -> UIImageView? {
if view is UIImageView && view.bounds.size.height <= 1 {
return (view as! UIImageView)
}
for subview in view.subviews {
if let imageView = findShadowImage(under: subview) {
return imageView
}
}
return nil
}
Ajouter/modifier viewWillAppear/viewWillDisappear
méthodes:
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
if shadowImageView == nil {
shadowImageView = findShadowImage(under: navigationController!.navigationBar)
}
shadowImageView?.isHidden = true
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
shadowImageView?.isHidden = false
}
La même méthode devrait également fonctionner pour UISearchBar
délié, et (presque) tout ce que vous devez cacher.
Merci beaucoup à @Leo Natan pour l'idée originale!
Ci-dessous peut aider simplement!
Swift:
self.navigationController?.navigationBar.setValue(true, forKey: "hidesShadow")
Objectif C:
[self.navigationController.navigationBar setValue:@(YES) forKeyPath:@"hidesShadow"];
Si vous souhaitez simplement utiliser une couleur de barre de navigation solide et que vous l'avez configurée dans votre storyboard, utilisez ce code dans votre classe AppDelegate
pour supprimer la bordure de 1 pixel via le proxy d'apparence:
[[UINavigationBar appearance] setBackgroundImage:[[UIImage alloc] init]
forBarPosition:UIBarPositionAny
barMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]];
Essaye ça:
[[UINavigationBar appearance] setBackgroundImage: [UIImage new]
forBarMetrics: UIBarMetricsDefault];
[UINavigationBar appearance].shadowImage = [UIImage new];
L'image ci-dessous contient l'explication (iOS7 NavigationBar):
Et vérifiez cette SO question: iOS7 - Modifier la couleur de la bordure de UINavigationBar
Voulait ajouter la version Swift de la réponse de Serhii. J'ai créé un UIBarExtension.Swift
avec les éléments suivants:
import Foundation
import UIKit
extension UINavigationBar {
func hideBottomHairline() {
self.hairlineImageView?.isHidden = true
}
func showBottomHairline() {
self.hairlineImageView?.isHidden = false
}
}
extension UIToolbar {
func hideBottomHairline() {
self.hairlineImageView?.isHidden = true
}
func showBottomHairline() {
self.hairlineImageView?.isHidden = false
}
}
extension UIView {
fileprivate var hairlineImageView: UIImageView? {
return hairlineImageView(in: self)
}
fileprivate func hairlineImageView(in view: UIView) -> UIImageView? {
if let imageView = view as? UIImageView, imageView.bounds.height <= 1.0 {
return imageView
}
for subview in view.subviews {
if let imageView = self.hairlineImageView(in: subview) { return imageView }
}
return nil
}
}
La Swift manière de le faire:
UINavigationBar.appearance().setBackgroundImage(
UIImage(),
forBarPosition: .Any,
barMetrics: .Default)
UINavigationBar.appearance().shadowImage = UIImage()
Solution simple à Swift
let navigationBar = self.navigationController?.navigationBar
navigationBar?.setBackgroundImage(UIImage(), forBarPosition: UIBarPosition.Any, barMetrics: UIBarMetrics.Default)
navigationBar?.shadowImage = UIImage()
Après avoir étudié la réponse de Serhil, j'ai créé un module INavigationBar + Addition qui peut facilement masquer la ligne des cheveux.
#import "UINavigationBar+Addition.h"
- (void)viewDidLoad {
[super viewDidLoad];
UINavigationBar *navigationBar = self.navigationController.navigationBar;
[navigationBar hideBottomHairline];
}
Dans Swift 3.0
Modifiez votre AppDelegate.Swift
en ajoutant le code suivant à la fonction de votre application:
// Override point for customization after application launch.
// Remove border in navigationBar
UINavigationBar.appearance().shadowImage = UIImage()
UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default)
solution de pxpgraphics mis à jour pour Swift 2.0
extension UINavigationBar {
func hideBottomHairline()
{
hairlineImageViewInNavigationBar(self)?.hidden = true
}
func showBottomHairline()
{
hairlineImageViewInNavigationBar(self)?.hidden = false
}
private func hairlineImageViewInNavigationBar(view: UIView) -> UIImageView?
{
if let imageView = view as? UIImageView where imageView.bounds.height <= 1
{
return imageView
}
for subview: UIView in view.subviews
{
if let imageView = hairlineImageViewInNavigationBar(subview)
{
return imageView
}
}
return nil
}
}
extension UIToolbar
{
func hideHairline()
{
let navigationBarImageView = hairlineImageViewInToolbar(self)?.hidden = true
}
func showHairline()
{
let navigationBarImageView = hairlineImageViewInToolbar(self)?.hidden = false
}
private func hairlineImageViewInToolbar(view: UIView) -> UIImageView?
{
if let imageView = view as? UIImageView where imageView.bounds.height <= 1
{
return imageView
}
for subview: UIView in view.subviews
{
if let imageView = hairlineImageViewInToolbar(subview)
{
return imageView
}
}
return nil
}
}
Swift 4 // pour masquer la ligne d'ombre de la barre de navigation
navigationController?.navigationBar.shadowImage = UIImage()
J'utilise une extension UINavigationBar qui me permet de masquer/afficher cette ombre à l'aide de l'API UIAppearance ou de sélectionner la barre de navigation qui doit masquer/afficher cette ombre à l'aide de Storyboard (ou du code source). Voici l'extension:
import UIKit
private var flatAssociatedObjectKey: UInt8 = 0
/*
An extension that adds a "flat" field to UINavigationBar. This flag, when
enabled, removes the shadow under the navigation bar.
*/
@IBDesignable extension UINavigationBar {
@IBInspectable var flat: Bool {
get {
guard let obj = objc_getAssociatedObject(self, &flatAssociatedObjectKey) as? NSNumber else {
return false
}
return obj.boolValue;
}
set {
if (newValue) {
let void = UIImage()
setBackgroundImage(void, forBarPosition: .Any, barMetrics: .Default)
shadowImage = void
} else {
setBackgroundImage(nil, forBarPosition: .Any, barMetrics: .Default)
shadowImage = nil
}
objc_setAssociatedObject(self, &flatAssociatedObjectKey, NSNumber(bool: newValue),
objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
}
Maintenant, pour désactiver l'ombre sur toutes les barres de navigation, vous devez utiliser:
UINavigationBar.appearance().flat = true
Ou vous pouvez activer/désactiver ce comportement à l'aide de storyboards:
Swift 4 testé UNE SOLUTION D'UNE LIGNE
Dans Viewdidload()
Définissez la valeur par défaut de l'utilisateur du contrôleur de navigation sur true pour la clé "hidesShadow"
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.setValue(true, forKey: "hidesShadow")
}
Une autre option si vous souhaitez préserver la transparence et ne pas sous-classer tous les UINavigationController
de votre application:
#import <objc/runtime.h>
@implementation UINavigationController (NoShadow)
+ (void)load {
Method original = class_getInstanceMethod(self, @selector(viewWillAppear:));
Method swizzled = class_getInstanceMethod(self, @selector(swizzled_viewWillAppear:));
method_exchangeImplementations(original, swizzled);
}
+ (UIImageView *)findHairlineImageViewUnder:(UIView *)view {
if ([view isKindOfClass:UIImageView.class] && view.bounds.size.height <= 1.0) {
return (UIImageView *)view;
}
for (UIView *subview in view.subviews) {
UIImageView *imageView = [self findHairlineImageViewUnder:subview];
if (imageView) {
return imageView;
}
}
return nil;
}
- (void)swizzled_viewWillAppear:(BOOL)animated {
UIImageView *shadow = [UINavigationController findHairlineImageViewUnder:self.navigationBar];
shadow.hidden = YES;
[self swizzled_viewWillAppear:animated];
}
@end
Swift a mis ceci
UINavigationBar.appearance().setBackgroundImage(UIImage(), forBarPosition: .Any, barMetrics: .Default)
UINavigationBar.appearance().shadowImage = UIImage()
dans
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
Solution dans Swift 4.2:
private func removeHairlineFromNavbar() {
UINavigationBar.appearance().setBackgroundImage(
UIImage(),
for: .any,
barMetrics: .default)
UINavigationBar.appearance().shadowImage = UIImage()
}
Il suffit de mettre cette fonction au premier contrôleur de vue et de l’appeler dans viewdidload
Slightly Swift Solution
func setGlobalAppearanceCharacteristics () {
let navigationBarAppearace = UINavigationBar.appearance()
navigationBarAppearace.tintColor = UIColor.white
navigationBarAppearace.barTintColor = UIColor.blue
navigationBarAppearace.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
navigationBarAppearace.shadowImage = UIImage()
}
Sous iOS8, si vous définissez UINavigationBar.barStyle
sur .Black
, vous pouvez définir l'arrière-plan de la barre comme couleur unie sans bordure.
En rapide:
UINavigationBar.appearance().translucent = false
UINavigationBar.appearance().barStyle = UIBarStyle.Black
UINavigationBar.appearance().barTintColor = UIColor.redColor()
Depuis iOS 13, une API système permet de définir ou de supprimer l'ombre.
UIKit utilise shadowImage et la propriété shadowColor pour déterminer l'apparence de l'ombre. Lorsque shadowImage a la valeur nil, la barre affiche une ombre par défaut teintée en fonction de la valeur de la propriété shadowColor. Si shadowColor a la valeur nil ou contient la couleur clearColor, la barre n’affiche aucune ombre.
let appearance = UINavigationBarAppearance()
appearance.shadowImage = nil
appearance.shadowColor = nil
navigationController.navigationBar.standardAppearance = appearance
Voici une solution très simple:
self.navigationController.navigationBar.clipsToBounds = YES;
Le problème avec la définition d'une image d'arrière-plan est que cela supprime le flou. Vous pouvez l'enlever sans définir une image d'arrière-plan. Voir ma réponse ici .
Vous devez ajouter une vue au bas de la barre UISearchBar.
let rect = searchController.searchBar.frame;
let lineView : UIView = UIView.init(frame: CGRect.init(x: 0, y: rect.size.height-1, width: rect.size.width, height: 1))
lineView.backgroundColor = UIColor.init(hexString: "8CC73E")
searchController.searchBar.addSubview(lineView)
Pour les utilisateurs d'iOS 9, cela a fonctionné pour moi. ajoutez simplement ceci:
UINavigationBar.appearance().shadowImage = UIImage()
Dans AppDelegate, le format de la barre de navigation a globalement changé:
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
UINavigationBar.appearance().setBackgroundImage(UIImage(), forBarPosition: UIBarPosition.Any, barMetrics: UIBarMetrics.Default)
UINavigationBar.appearance().shadowImage = UIImage()
UINavigationBar.appearance().tintColor = UIColor.whiteColor()
UINavigationBar.appearance().barTintColor = UIColor.redColor()
UINavigationBar.appearance().translucent = false
UINavigationBar.appearance().clipsToBounds = false
UINavigationBar.appearance().backgroundColor = UIColor.redColor()
UINavigationBar.appearance().titleTextAttributes = [NSFontAttributeName : (UIFont(name: "FONT NAME", size: 18))!, NSForegroundColorAttributeName: UIColor.whiteColor()] }
N'a pas réussi à mettre en œuvre quelque chose de différent sur un VC spécifique, mais cela aidera 90% des gens
la réponse de pxpgraphics pour Swift 3.0.
import Foundation
import UIKit
extension UINavigationBar {
func hideBottomHairline() {
let navigationBarImageView = hairlineImageViewInNavigationBar(view: self)
navigationBarImageView!.isHidden = true
}
func showBottomHairline() {
let navigationBarImageView = hairlineImageViewInNavigationBar(view: self)
navigationBarImageView!.isHidden = false
}
private func hairlineImageViewInNavigationBar(view: UIView) -> UIImageView? {
if view is UIImageView && view.bounds.height <= 1.0 {
return (view as! UIImageView)
}
let subviews = (view.subviews as [UIView])
for subview: UIView in subviews {
if let imageView: UIImageView = hairlineImageViewInNavigationBar(view: subview) {
return imageView
}
}
return nil
}
}
extension UIToolbar {
func hideHairline() {
let navigationBarImageView = hairlineImageViewInToolbar(view: self)
navigationBarImageView!.isHidden = true
}
func showHairline() {
let navigationBarImageView = hairlineImageViewInToolbar(view: self)
navigationBarImageView!.isHidden = false
}
private func hairlineImageViewInToolbar(view: UIView) -> UIImageView? {
if view is UIImageView && view.bounds.height <= 1.0 {
return (view as! UIImageView)
}
let subviews = (view.subviews as [UIView])
for subview: UIView in subviews {
if let imageView: UIImageView = hairlineImageViewInToolbar(view: subview) {
return imageView
}
}
return nil
}
}
Créer une extension:
extension UIImage {
class func hideNavBarLine(color: UIColor) -> UIImage? {
let rect = CGRect(x: 0, y: 0, width: 1, height: 1)
UIGraphicsBeginImageContext(rect.size)
let context = UIGraphicsGetCurrentContext()
context?.setFillColor(color.cgColor)
context?.fill(rect)
let navBarLine = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return navBarLine
}
}
Ajoutez ceci à viewDidLoad()
:
self.navigationController?.navigationBar.shadowImage = UIImage.hideNavBarLine(color: UIColor.clear)
Je sais que c'est un vieux fil, mais j'ai trouvé une solution qui fonctionne vraiment bien:
Sous-classe UINavigationBar. Dans votre sous-classe UINavigationBar, remplacez didAddSubview par le code suivant:
- (void)didAddSubview:(UIView *)subview
{
[super didAddSubview:subview];
if ([subview isKindOfClass:[UIImageView class]]) {
[subview setClipsToBounds:YES];
}
}
Je viens de créer une extension pour cela ... Désolé pour le formatage (c'est ma première réponse).
Usage:
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.hideShadow = true
}
Extension:
UINavigationController.Swift
// Created by Ricardo López Rey on 16/7/15.
import Foundation
struct UINavigationControllerExtension {
static var hideShadowKey : String = "HideShadow"
static let backColor = UIColor(red: 247/255, green: 247/255, blue: 248/255, alpha: 1.0)
}
extension UINavigationController {
var hideShadow : Bool {
get {
if let ret = objc_getAssociatedObject(self, &UINavigationControllerExtension.hideShadowKey) as? Bool {
return ret
} else {
return false
}
}
set {
objc_setAssociatedObject(self,&UINavigationControllerExtension.hideShadowKey,newValue, objc_AssociationPolicy(OBJC_ASSOCIATION_RETAIN_NONATOMIC))
if newValue {
self.navigationBar.setBackgroundImage(solidImage(UINavigationControllerExtension.backColor), forBarMetrics: UIBarMetrics.Default)
self.navigationBar.shadowImage = solidImage(UIColor.clearColor())
} else {
self.navigationBar.setBackgroundImage(nil, forBarMetrics: UIBarMetrics.Default)
}
}
}
private func solidImage(color: UIColor, size: CGSize = CGSize(width: 1,height: 1)) -> UIImage {
var rect = CGRectMake(0, 0, size.width, size.height)
UIGraphicsBeginImageContextWithOptions(size, false, 0)
color.setFill()
UIRectFill(rect)
var image: UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}
}
Voici une façon de le faire sans utiliser d'images, c'est la seule façon qui a fonctionné pour moi:
self.navigationController.navigationBar.layer.shadowOpacity = 0;
Malheureusement, vous devez le faire sur tous les fichiers où vous souhaitez que la ligne n'apparaisse pas. Il n'y a aucun moyen de le faire de cette façon dans appDelegate
.
Edit:
Régler la variable shadowColor
sur nil
n’est pas nécessaire, c’est la seule ligne dont vous aurez besoin.
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
UIImage *emptyImage = [UIImage new];
self.navigationController.navigationBar.shadowImage = emptyImage;
[self.navigationController.navigationBar setBackgroundImage:emptyImage forBarMetrics:UIBarMetricsDefault];
}
Réponse de l’objectif C à la question ci-dessus
// suppression de la barre de navigation 1px
[[UINavigationBar appearance] setBackgroundImage:[[UIImage alloc]init] forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]];
[[UINavigationBar appearance] setTranslucent:NO];
[[UINavigationBar appearance] setTintColor:[UIColor yourColor]];
Dans Swift nous faisons de cette façon
Pour tout contrôleur de vue:
navigationBar.shadowImage = UIImage()
setBackgroundImage(UIImage(), for: .default)
Pour une application entière:
UINavigationBar.appearance().setBackgroundImage(UIImage(),barMetrics: .Default)
UINavigationBar.appearance().shadowImage = UIImage()
J'ai rencontré le même problème et aucune des réponses n'a été vraiment satisfaisante. Voici ma prise pour Swift3:
func hideNavigationBarLine() {
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationController?.navigationBar.shadowImage = UIImage()
}
Appelez simplement cela de l'intérieur viewDidLoad ().
Bonjour, cela fonctionne pour Swift 4.
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.isTranslucent = false
}
vous devez mettre ceci dans viewDidLayoutSubviews au lieu de viewDidLoad
Voici une autre option - je pense que cela ne fonctionne que si vous n’avez pas besoin de translucidité sur votre barre de navigation (ce n’était pas le cas). Je viens d'ajouter un UIView de 1 pixel au bas de la barre de navigation (1 pixel sous la barre de navigation) avec la même couleur que ma barre de navigation:
UIView *view = [[UIView alloc] init];
[view setBackgroundColor:self.navigationController.navigationBar.barTintColor];
[self.navigationController.navigationBar addSubview:view];
[view mas_makeConstraints:^(MASConstraintMaker *make) {
make.height.equalTo(@(1.0f));
make.leading.trailing.equalTo(self.navigationController.navigationBar);
make.bottom.equalTo(self.navigationController.navigationBar).offset(1.0f);
}];
J'ajoute les contraintes en utilisant la maçonnerie.
[tabviewController.view setBackgroundColor:[UIColor blackColor]];
Est-ce que c'est pour moi [UIColor blackColor]
pourrait être votre couleur d'arrière-plan, et tabviewController
est votre UITabBarController
si vous l'utilisez!
Le style bar noir l'a fait pour moi.
[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];
Toutes les propriétés que j'ai (juste au cas où):
[[UINavigationBar appearance] setBarTintColor:color];
[[UINavigationBar appearance] setTranslucent:NO];
[[UINavigationBar appearance] setShadowImage:[UIImage new]];
[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];
Une jolie fonction Swift permettant de trouver le contour des cheveux dans les sous-vues est la suivante:
func findHairLineInImageViewUnder(view view: UIView) -> UIImageView? {
if let hairLineView = view as? UIImageView where hairLineView.bounds.size.height <= 1.0 {
return hairLineView
}
if let hairLineView = view.subviews.flatMap({self.findHairLineInImageViewUnder(view: $0)}).first {
return hairLineView
}
return nil
}
Ce qui a fonctionné pour moi, et était le plus simple, a été de créer un png (il ne doit s'agir que de dimensions d'un pixel sur un pixel) avec la couleur requise, puis de définir les propriétés backgroundImage et shadowImage sur:
let greenPixel = UIImage(named: "TheNameOfYourPng")
navigationBar.setBackgroundImage(greenPixel, forBarMetrics: UIBarMetrics.Default)
navigationBar.shadowImage = greenPixel
Deux lignes solution qui fonctionne pour moi. Essayez d’ajouter ceci à la méthode ViewDidLoad:
navigationController?.navigationBar.setValue(true, forKey: "hidesShadow")
self.extendedLayoutIncludesOpaqueBars = true
Mon approche:
UINavigationBar.appearance().setBackgroundImage(
UIImage(),
forBarPosition: .Any,
barMetrics: .Default)
var _width:CGFloat! = self.navigationController?.navigationBar.layer.frame.width
var _height:CGFloat! = self.navigationController?.navigationBar.layer.frame.height
var navBarBg = UIView(frame:CGRectMake(0, 0, _width, _height))
//solid color for bg
navBarBg.backgroundColor = UIColor.orangeColor()
view.addSubview(navBarBg)
Dans Xamarin Forms cela a fonctionné pour moi. Ajoutez simplement ceci sur AppDelegate.cs:
UINavigationBar.Appearance.ShadowImage = new UIImage();
Cela peut sembler stupide, mais cette délimitation n'apparaît que lorsque la couleur d'arrière-plan de la vue de viewController est définie sur n'importe quelle couleur, à l'exception du blanc. J'ai été choqué d'apprendre ce fait.
Donc, si vous voulez qu'il disparaisse sans trop de peine, simplement définissez la couleur d'arrière-plan de la vue du contrôleur sur WHITE COLOR.