コンテンツに溶け込むためにナビゲーション バーが必要なアプリがあります。
この厄介な小さなバーを取り除く方法や色を変える方法を知っている人はいますか?
下の画像では、「ルートビューコントローラー」の下のこの1pxの高さの線について話している
コンテンツに溶け込むためにナビゲーション バーが必要なアプリがあります。
この厄介な小さなバーを取り除く方法や色を変える方法を知っている人はいますか?
下の画像では、「ルートビューコントローラー」の下のこの1pxの高さの線について話している
.shadowColor
プロパティを使用する
このプロパティが nil であるか、クリア カラーを含む場合、バーは影を表示しません
例えば:
let navigationBar = navigationController?.navigationBar
let navigationBarAppearance = UINavigationBarAppearance()
navigationBarAppearance.shadowColor = .clear
navigationBar?.scrollEdgeAppearance = navigationBarAppearance
これを行うには、カスタム シャドウ イメージを設定する必要があります。ただし、影の画像を表示するには、カスタム背景画像も設定する必要があります。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()
色で塗りつぶされた小さな背景画像を作成して使用します。
以下で説明する「ハッキー」メソッドを使用します。また、バーを半透明に保ちます。
半透明性を維持するには、別のアプローチが必要です。ハックのように見えますが、うまく機能します。削除しようとしている影は、 のUIImageView
下のどこかにあるヘアラインUINavigationBar
です。必要に応じて、それを見つけて表示/非表示にすることができます。
UINavigationController
以下の手順では、階層の 1 つのコントローラーでのみヘアラインを非表示にする必要があると想定しています。
インスタンス変数を宣言します。
private var shadowImageView: UIImageView?
この影(ヘアライン)を見つけるメソッドを追加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"];
これを試して:
[[UINavigationBar appearance] setBackgroundImage: [UIImage new]
forBarMetrics: UIBarMetricsDefault];
[UINavigationBar appearance].shadowImage = [UIImage new];
以下の画像に説明があります(iOS7 NavigationBar):
そして、この SO の質問を確認してください: iOS7 - UINavigationBar の境界線の色を変更する
それを行う迅速な方法:
UINavigationBar.appearance().setBackgroundImage(UIImage(), for: .any, barMetrics: .default)
UINavigationBar.appearance().shadowImage = UIImage()
迅速なシンプルなソリューション
let navigationBar = self.navigationController?.navigationBar
navigationBar?.setBackgroundImage(UIImage(), forBarPosition: UIBarPosition.Any, barMetrics: UIBarMetrics.Default)
navigationBar?.shadowImage = UIImage()
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
https://developer.apple.com/documentation/uikit/uibarappearance/3198009-shadowimage
Swift 2.0 用に更新されたpxpgraphics のソリューション
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
}
}
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
または、ストーリーボードを使用してこの動作を有効/無効にすることができます。
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()
}
私にとってはうまくいく2行のソリューション。これを ViewDidLoad メソッドに追加してみてください:
navigationController?.navigationBar.setValue(true, forKey: "hidesShadow")
self.extendedLayoutIncludesOpaqueBars = true
iOS8 では、 を に設定するUINavigationBar.barStyle
と.Black
、バーの背景を枠なしの無地に設定できます。
スウィフトの場合:
UINavigationBar.appearance().translucent = false
UINavigationBar.appearance().barStyle = UIBarStyle.Black
UINavigationBar.appearance().barTintColor = UIColor.redColor()
iOS 9 ユーザーの場合、これでうまくいきました。これを追加するだけです:
UINavigationBar.appearance().shadowImage = UIImage()
この拡張機能を作成しました...フォーマットについて申し訳ありません(これが私の最初の回答です)。
使用法:
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
}
}
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% の人々を助けるだろう
バースタイルの黒が私のためにそれをしました。
[[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
これが古いスレッドであることは知っていますが、非常にうまく機能する解決策を見つけました。
UINavigationBar をサブクラス化します。UINavigationBar サブクラスで、次のコードで didAddSubview をオーバーライドします。
- (void)didAddSubview:(UIView *)subview
{
[super didAddSubview:subview];
if ([subview isKindOfClass:[UIImageView class]]) {
[subview setClipsToBounds:YES];
}
}
[tabviewController.view setBackgroundColor:[UIColor blackColor]];
それはあなた[UIColor blackColor]
の背景色かもしれません。tabviewController
UITabBarController
独自のイニシャライザを作成してください:D
import Foundation
import UIKit
extension UINavigationController {
convenience init(rootViewController : UIViewController, hidesShadow : Bool) {
self.init(rootViewController : rootViewController)
self.navigationBar.setValue(hidesShadow, forKey: "hidesShadow")
if hidesShadow {
self.extendedLayoutIncludesOpaqueBars = true
self.navigationBar.isTranslucent = false
}
}
}
こんにちは、これは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に入れる必要があります