私は時々そのナビゲーションバーがコンテンツに溶け込む必要があるアプリを持っています。
誰もがこの迷惑な小さなバーの色を取り除くまたは変更する方法を知っていますか?
私が持っている状況の下の画像に - 私は "Root View Controller"の下のこの1pxの高さのラインについて話しているのです
これを行うには、カスタムシャドウイメージを設定する必要があります。影の画像を表示するには、カスタムの背景画像も設定する必要があります。Appleのドキュメントから引用してください。
カスタムシャドウイメージを表示するには、カスタム背景イメージもsetBackgroundImage(_:for :)メソッドで設定する必要があります。デフォルトの背景画像が使用されている場合は、このプロパティの値に関係なく、デフォルトの影の画像が使用されます。
そう:
let navigationBar = navigationController!.navigationBar
navigationBar.setBackgroundImage(#imageLiteral(resourceName: "BarBackground"),
for: .default)
navigationBar.shadowImage = UIImage()
それを隠す唯一の「公式の」方法は上記のとおりです。残念ながら、それは棒の半透明性を取り除きます。
あなたはそれらのオプションがあります:
無地、半透明:
navigationBar.barTintColor = UIColor.redColor()
navigationBar.isTranslucent = false
navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationBar.shadowImage = UIImage()
色でいっぱいの小さな背景画像を作成して使用します。
下記の 'hacky'メソッドを使ってください。それはまたバーを半透明に保ちます。
半透明を保つためには、別のアプローチが必要です。ハックのように見えますが、うまくいきます。削除しようとしている影は、UIImageView
の下のどこかにあるヘアラインUINavigationBar
です。それを見つけて、必要に応じて表示/非表示にすることができます。
以下の説明では、あなたのUINavigationController
階層の一つのコントローラにのみ生え際を隠す必要があると仮定しています。
インスタンス変数を宣言します。
private var shadowImageView: UIImageView?
この影を見つけるメソッドを追加しなさい(hairline)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
}
viewWillAppear/viewWillDisappear
メソッドを追加/編集します。
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
}
同じ方法がUISearchBar
の生え際、そして(ほとんど)あなたが隠す必要がある何か他のものに対してもうまくいくはずです:)
オリジナルのアイディアをくれた@ Leo Natanに感謝します!
以下が簡単に役立ちます!
スイフト:
self.navigationController?.navigationBar.setValue(true, forKey: "hidesShadow")
目標C:
[self.navigationController.navigationBar setValue:@(YES) forKeyPath:@"hidesShadow"];
単色のナビゲーションバーの色を使用してストーリーボードでこれを設定したい場合は、外観プロキシを介して1ピクセルの境界線を削除するためにAppDelegate
クラスで次のコードを使用します。
[[UINavigationBar appearance] setBackgroundImage:[[UIImage alloc] init]
forBarPosition:UIBarPositionAny
barMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]];
これを試して:
[[UINavigationBar appearance] setBackgroundImage: [UIImage new]
forBarMetrics: UIBarMetricsDefault];
[UINavigationBar appearance].shadowImage = [UIImage new];
以下の画像には説明があります(iOS7 NavigationBar):
そして、このSOの質問を確認してください。 iOS7-UINavigationBarの境界線の色を変更
Serhiiの答えのSwift版を追加したかった。次のようにしてUIBarExtension.Swift
を作成しました。
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
}
}
それをする迅速な方法:
UINavigationBar.appearance().setBackgroundImage(
UIImage(),
forBarPosition: .Any,
barMetrics: .Default)
UINavigationBar.appearance().shadowImage = UIImage()
Swiftでの簡単な解決策
let navigationBar = self.navigationController?.navigationBar
navigationBar?.setBackgroundImage(UIImage(), forBarPosition: UIBarPosition.Any, barMetrics: UIBarMetrics.Default)
navigationBar?.shadowImage = UIImage()
Serhilからの答えを検討した後、私は簡単に生え際を隠すことができるポッド UINavigationBar + Addition を作成しました。
#import "UINavigationBar+Addition.h"
- (void)viewDidLoad {
[super viewDidLoad];
UINavigationBar *navigationBar = self.navigationController.navigationBar;
[navigationBar hideBottomHairline];
}
Swift 3.0では
アプリケーション関数に次のコードを追加して、AppDelegate.Swift
を編集します。
// Override point for customization after application launch.
// Remove border in navigationBar
UINavigationBar.appearance().shadowImage = UIImage()
UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .default)
pxpgraphicsの解決策 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 //ナビゲーションバーの影の線を隠す
navigationController?.navigationBar.shadowImage = UIImage()
UIAppearance APIを使用するか、ストーリーボード(またはソースコード)を使用して影を隠す/表示するナビゲーションバーを選択することで、影を隠す/表示することができるUINavigationBar拡張を使用します。これが拡張子です。
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)
}
}
}
今、あなたが使用しなければならないすべてのナビゲーションバーの影を無効にするために:
UINavigationBar.appearance().flat = true
ストーリーボードを使用してこの動作を有効/無効にすることもできます。
Swift 4テスト済み ONE LINE SOLUTION
Viewdidload()
内ナビゲーションキーの "hidesShadow"に対してNavigation Controllerのユーザーデフォルト値をtrueに設定します
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.setValue(true, forKey: "hidesShadow")
}
半透明性を維持したいが、アプリ内のすべてのUINavigationController
をサブクラス化したくない場合は、別の選択肢があります。
#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
迅速にこれを置く
UINavigationBar.appearance().setBackgroundImage(UIImage(), forBarPosition: .Any, barMetrics: .Default)
UINavigationBar.appearance().shadowImage = UIImage()
に
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
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()
}
IOS8では、UINavigationBar.barStyle
を.Black
に設定すると、バーの背景を境界線なしの単色として設定できます。
Swiftでは:
UINavigationBar.appearance().translucent = false
UINavigationBar.appearance().barStyle = UIBarStyle.Black
UINavigationBar.appearance().barTintColor = UIColor.redColor()
Swift 4.2のソリューション:
private func removeHairlineFromNavbar() {
UINavigationBar.appearance().setBackgroundImage(
UIImage(),
for: .any,
barMetrics: .default)
UINavigationBar.appearance().shadowImage = UIImage()
}
この関数を最初のViewcontrollerに置いてviewdidload
で呼び出すだけです。
IOS 13現在、シャドウを設定または削除するシステムAPIがあります
UIKitは、shadowImageとshadowColorプロパティを使用して、影の外観を決定します。 shadowImageがnilの場合、バーには、shadowColorプロパティの値に応じて色付けされたデフォルトの影が表示されます。 shadowColorがnilまたはclearColor色を含む場合、バーには影が表示されません。
let appearance = UINavigationBarAppearance()
appearance.shadowImage = nil
appearance.shadowColor = nil
navigationController.navigationBar.standardAppearance = appearance
これは非常に簡単な解決策です:
self.navigationController.navigationBar.clipsToBounds = YES;
背景画像を設定することの問題は、それがぼけを取り除くことです。背景画像を設定せずに削除できます。私の答えを参照してください ここ 。
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)
IOS 9ユーザーにとって、これは私にとってはうまくいった。これを追加するだけです:
UINavigationBar.appearance().shadowImage = UIImage()
AppDelegate 内で、これはNavBarのフォーマットをグローバルに変更しました:
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()] }
特定のVCに何も変わって実装することはできませんでしたが、これは90%の人々に役立つでしょう
swift 3.0に対するpxpgraphicsの回答。
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
}
}
拡張機能を作成します。
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
}
}
これをviewDidLoad()
に追加します:
self.navigationController?.navigationBar.shadowImage = UIImage.hideNavBarLine(color: UIColor.clear)
私はこれが古いスレッドであることを知っています、しかし私は本当にうまくいく解決策を見つけました:
サブクラスUINavigationBar。 UINavigationBarサブクラスで、didAddSubviewを次のコードでオーバーライドします。
- (void)didAddSubview:(UIView *)subview
{
[super didAddSubview:subview];
if ([subview isKindOfClass:[UIImageView class]]) {
[subview setClipsToBounds:YES];
}
}
私はちょうどこのための拡張子を作成しました...フォーマットについて申し訳ありません(これが私の最初の答えです)。
使用法:
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.hideShadow = true
}
拡張:
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
}
}
これは、画像を使用せずにこれを実行する方法です。これが私にとって有効な唯一の方法です。
self.navigationController.navigationBar.layer.shadowOpacity = 0;
残念ながら、行を表示したくないすべてのファイルでこれを行う必要があります。 appDelegate
では、このようにすることはできません。
編集:
shadowColor
をnil
に設定する必要はありません、これがあなたが必要とする唯一の行です。
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
UIImage *emptyImage = [UIImage new];
self.navigationController.navigationBar.shadowImage = emptyImage;
[self.navigationController.navigationBar setBackgroundImage:emptyImage forBarMetrics:UIBarMetricsDefault];
}
目標C上記の質問に対する回答
//ナビゲーションバーの1px行を削除する
[[UINavigationBar appearance] setBackgroundImage:[[UIImage alloc]init] forBarMetrics:UIBarMetricsDefault];
[[UINavigationBar appearance] setShadowImage:[[UIImage alloc] init]];
[[UINavigationBar appearance] setTranslucent:NO];
[[UINavigationBar appearance] setTintColor:[UIColor yourColor]];
Swift 3 /このようにする
あらゆるView Controllerの場合:
navigationBar.shadowImage = UIImage()
setBackgroundImage(UIImage(), for: .default)
アプリ全体の場合:
UINavigationBar.appearance().setBackgroundImage(UIImage(),barMetrics: .Default)
UINavigationBar.appearance().shadowImage = UIImage()
こんにちはこれはSwift 4のために働く。
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
self.navigationController?.navigationBar.shadowImage = UIImage()
self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
self.navigationController?.navigationBar.isTranslucent = false
}
あなたはviewDidLoadの代わりにviewDidLayoutSubviewsにこれを置く必要があります
別の選択肢があります - これは、ナビゲーションバーに半透明性が必要ない場合にのみ有効であると思います(私はしていません)。ナビゲーションバーの下部に1ピクセルの高さのUIView(ナビゲーションバーの1ピクセル下)をナビゲーションバーと同じ色で追加しました。
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);
}];
Masonryを使って制約を追加しています。
[tabviewController.view setBackgroundColor:[UIColor blackColor]];
[UIColor blackColor]
はあなたの背景色かもしれませんし、あなたがそれを使っているならtabviewController
はあなたのUITabBarController
です!
バースタイル黒は私のためにそれをやった。
[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];
私が持っているすべてのプロパティ(念のため):
[[UINavigationBar appearance] setBarTintColor:color];
[[UINavigationBar appearance] setTranslucent:NO];
[[UINavigationBar appearance] setShadowImage:[UIImage new]];
[[UINavigationBar appearance] setBarStyle:UIBarStyleBlack];
サブビューで生え際を見つけるための素晴らしい短いSwift関数はこれです:
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
}
私にとって役に立ち、そして最も簡単だったのは、必要な色でpng(大きさが1ピクセルx 1ピクセルであればよい)を作成し、次にbackgroundImageとshadowImageをそれに設定することでした。
let greenPixel = UIImage(named: "TheNameOfYourPng")
navigationBar.setBackgroundImage(greenPixel, forBarMetrics: UIBarMetrics.Default)
navigationBar.shadowImage = greenPixel
私のために働く2行のソリューション。これをViewDidLoadメソッドに追加してみてください。
navigationController?.navigationBar.setValue(true, forKey: "hidesShadow")
self.extendedLayoutIncludesOpaqueBars = true
私のアプローチ:
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)
Xamarin Forms これは私のために働きました。 AppDelegate.csにこれを追加するだけです。
UINavigationBar.Appearance.ShadowImage = new UIImage();
私は同じ問題に遭遇し、答えのどれも本当に満足のいくものではありませんでした。これがSwift3の私の見解です。
func hideNavigationBarLine() {
navigationController?.navigationBar.setBackgroundImage(UIImage(), for: .default)
navigationController?.navigationBar.shadowImage = UIImage()
}
単に viewDidLoad() の中からこれを呼び出します。
これは愚かに聞こえるかもしれませんが、このヘアラインは、viewControllerのビューの背景色が任意の色に設定されているが白色である場合にのみ表示されます。私はこの事実を知ってショックを受けました。
それで、問題なくそれを消したい場合は、 コントローラのビューの背景色をWHITE COLORに設定してください。