ios - custom - uinavigationitem




So blenden Sie die untere Zeile der UINavigationBar 1px aus (20)

Bar Style Black hat es für mich getan.

[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];

Alle Eigenschaften, die ich habe (nur für den Fall):

    [[UINavigationBar appearance] setBarTintColor:color];
    [[UINavigationBar appearance] setTranslucent:NO];
    [[UINavigationBar appearance] setShadowImage:[UIImage new]];
    [[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];

Ich habe eine App, die manchmal ihre Navigationsleiste benötigt, um sich in den Inhalt einzufügen.

Weiß jemand, wie man diese nervige kleine Bar los wird oder die Farbe ändert?

Auf dem Bild unten habe ich Situation - ich spreche über diese 1px Höhe Linie unter "Root View Controller"


Das Problem mit dem Setzen eines Hintergrundbildes ist das Entfernen von Unschärfe. Sie können es entfernen, ohne ein Hintergrundbild zu setzen. Siehe meine Antwort here .


Der schnelle Weg, es zu tun:

UINavigationBar.appearance().setBackgroundImage(
    UIImage(),
    forBarPosition: .Any,
    barMetrics: .Default)

UINavigationBar.appearance().shadowImage = UIImage()

Eine weitere Option, wenn Sie die Transluzenz erhalten und nicht alle UINavigationController in Ihrer App UINavigationController möchten:

#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

Für iOS 9-Nutzer funktionierte das für mich. füge einfach folgendes hinzu:

UINavigationBar.appearance().shadowImage = UIImage()

Hier ist eine andere Option - ich denke, das funktioniert nur, wenn Sie Transluzenz in Ihrer Navigationsleiste nicht benötigen (ich nicht). Ich habe gerade eine 1 Pixel hohe UIView am unteren Rand der Navigationsleiste (1 Pixel unter der Navigationsleiste) mit der gleichen Farbe wie meine Navigationsleiste hinzugefügt:

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);
}];

Ich füge die Einschränkungen mit Mauerwerk hinzu.


Ich benutze eine UINavigationBar-Erweiterung, die es mir ermöglicht, diesen Schatten mithilfe der UIAppearance-API zu verbergen oder anzuzeigen oder auszuwählen, welche Navigationsleiste diesen Schatten mit Storyboard (oder Quellcode) ein- und ausblenden soll. Hier ist die Erweiterung:

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)
        }
    }
}

Um den Schatten über alle Navigationsleisten hinweg zu deaktivieren, müssen Sie Folgendes verwenden:

UINavigationBar.appearance().flat = true

Oder Sie können dieses Verhalten mithilfe von Storyboards aktivieren / deaktivieren:


Ich habe gerade eine Erweiterung dafür erstellt ... Sorry wegen Formatierung (das ist meine erste Antwort).

Verwendung:

  override func viewDidLoad() {
    super.viewDidLoad()
    self.navigationController?.hideShadow = true
}

Erweiterung:

 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
    }


}

In Swift 3.0

Bearbeiten Sie Ihre AppDelegate.swift indem Sie Ihrer Anwendungsfunktion den folgenden Code hinzufügen:

// Override point for customization after application launch.

// Remove border in navigationBar
UINavigationBar.appearance().shadowImage = UIImage()
UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default)

Mein Ansatz:

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)

Nachdem ich die Antwort von Serhil studiert hatte, erstellte ich eine Pod UINavigationBar+Addition , die die Haarlinie leicht verbergen kann.

#import "UINavigationBar+Addition.h"

- (void)viewDidLoad {
    [super viewDidLoad];

    UINavigationBar *navigationBar = self.navigationController.navigationBar;
    [navigationBar hideBottomHairline];
}

Objective C Antwort auf obige Frage

// Entfernen der 1px Zeile der Navigationsleiste

[[UINavigationBar appearance] setBackgroundImage:[[UIImage alloc]init] forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]];
[[UINavigationBar appearance] setTranslucent:NO];
[[UINavigationBar appearance] setTintColor:[UIColor yourColor]];

Swift legte das vor

UINavigationBar.appearance().setBackgroundImage(UIImage(), forBarPosition: .Any, barMetrics: .Default)
UINavigationBar.appearance().shadowImage = UIImage()

im

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool

Um dies zu tun, sollten Sie ein benutzerdefiniertes Schattenbild festlegen. Damit das Schattenbild jedoch angezeigt wird, müssen Sie auch ein benutzerdefiniertes Hintergrundbild festlegen, wie in der Apple-Dokumentation angegeben:

Damit ein benutzerdefiniertes Schattenbild angezeigt wird, muss auch ein benutzerdefiniertes Hintergrundbild mit der Methode setBackgroundImage (_: for :) festgelegt werden. Wenn das Standardhintergrundbild verwendet wird, wird das Standardschattenbild unabhängig vom Wert dieser Eigenschaft verwendet.

Damit:

let navigationBar = navigationController!.navigationBar
navigationBar.setBackgroundImage(#imageLiteral(resourceName: "BarBackground"),
                                                        for: .default)
navigationBar.shadowImage = UIImage()

Oben ist der einzige "offizielle" Weg, es zu verstecken. Leider entfernt es die Transluzenz des Balkens.

Ich will kein Hintergrundbild, nur Farbe

Sie haben diese Optionen:

  1. Einfarbig, keine Transluzenz:

    navigationBar.barTintColor = UIColor.redColor()
    navigationBar.isTranslucent = false
    navigationBar.setBackgroundImage(UIImage(), for: .default)
    navigationBar.shadowImage = UIImage()
    
  2. Erstelle ein kleines, mit Farbe gefülltes Hintergrundbild und benutze es.

  3. Verwenden Sie die unten beschriebene "Hacky" -Methode. Es wird auch Bar durchsichtig halten.

Wie hält man den Balken durchsichtig?

Um Transluzenz zu erhalten, braucht man einen anderen Ansatz, es sieht wie ein Hack aus, funktioniert aber gut. Der Schatten, den wir entfernen wollen, ist ein UIImageView irgendwo unter UINavigationBar . Wir können es finden und es bei Bedarf verstecken / zeigen.

Die folgenden Anweisungen gehen davon aus, dass Sie die Haarlinie nur in einem Controller Ihrer UINavigationController Hierarchie UINavigationController .

  1. Instanzvariable deklarieren:

    private var shadowImageView: UIImageView?
    
  2. UIImageView: Methode hinzu, die diesen Schatten findet (Haarlinie) 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
    }
    
  3. Hinzufügen / Bearbeiten viewWillAppear/viewWillDisappear Methoden:

    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
    }
    

Die gleiche Methode sollte auch für die UISearchBar Haarlinie UISearchBar und (fast) alles andere, was du verstecken musst :)

Vielen Dank an @Leo Natan für die ursprüngliche Idee!


Wenn Sie in UINavigationBar.barStyle den UINavigationBar.barStyle auf .Black , können Sie den Hintergrund der Leiste als einfache Farbe ohne den Rahmen .Black .

In Swift:

UINavigationBar.appearance().translucent = false
UINavigationBar.appearance().barStyle = UIBarStyle.Black
UINavigationBar.appearance().barTintColor = UIColor.redColor()

Wenn Sie nur eine solide Navigationsleistenfarbe verwenden möchten und dies in Ihrem Storyboard eingerichtet haben, verwenden Sie diesen Code in Ihrer AppDelegate Klasse, um den 1-Pixel-Rahmen über den Darstellungs-Proxy zu entfernen:

[[UINavigationBar appearance] setBackgroundImage:[[UIImage alloc] init]
                                  forBarPosition:UIBarPositionAny
                                      barMetrics:UIBarMetricsDefault];

[[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]];

pxpgraphics 'Antwort für 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
  }
}

Swift 4 // zum Verbergen der Navigationsleiste

navigationController?.navigationBar.shadowImage = UIImage()

-(void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    UIImage *emptyImage = [UIImage new];
    self.navigationController.navigationBar.shadowImage = emptyImage;
    [self.navigationController.navigationBar setBackgroundImage:emptyImage forBarMetrics:UIBarMetricsDefault];
}

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()

}




uinavigationbar