ฉันมีแอพที่บางครั้งต้องการแถบการนำทางเพื่อให้เข้ากับเนื้อหา
ไม่มีใครรู้วิธีกำจัดหรือเปลี่ยนสีของแถบเล็ก ๆ ที่น่ารำคาญนี้หรือไม่?
ในภาพด้านล่างสถานการณ์ฉันมี - ฉันกำลังพูดถึงบรรทัดความสูง 1px ด้านล่าง "ผู้ควบคุมมุมมองรูท"
ฉันมีแอพที่บางครั้งต้องการแถบการนำทางเพื่อให้เข้ากับเนื้อหา
ไม่มีใครรู้วิธีกำจัดหรือเปลี่ยนสีของแถบเล็ก ๆ ที่น่ารำคาญนี้หรือไม่?
ในภาพด้านล่างสถานการณ์ฉันมี - ฉันกำลังพูดถึงบรรทัดความสูง 1px ด้านล่าง "ผู้ควบคุมมุมมองรูท"
คำตอบ:
ใช้.shadowColor
คุณสมบัติ
หากคุณสมบัตินี้เป็นศูนย์หรือมีสีที่ชัดเจนบาร์จะไม่แสดงเงา
ตัวอย่างเช่น
let navigationBar = navigationController?.navigationBar
let navigationBarAppearence = UINavigationBarAppearance()
navigationBarAppearence.shadowColor = .clear
navigationBar?.scrollEdgeAppearance = navigationBarAppearence
ในการทำเช่นนี้คุณควรกำหนดภาพเงาที่กำหนดเอง แต่สำหรับภาพเงาที่จะแสดงคุณต้องตั้งภาพพื้นหลังที่กำหนดเองอ้างจากเอกสารของ 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
ลำดับชั้นของคุณเท่านั้น
ประกาศตัวแปรอินสแตนซ์:
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 สำหรับแนวคิดดั้งเดิม!
UINavigationBar
คุณสมบัติ:clipsToBounds = YES
clipsToBounds = YES
ทำงานเหมือนจับใจ! ขอบคุณ!
viewWillAppear
ถูกเรียกว่าเราไม่สามารถรับได้shadowImageView
ด้านล่างนี้สามารถช่วยได้ง่ายๆ!
สวิฟท์:
self.navigationController?.navigationBar.setValue(true, forKey: "hidesShadow")
วัตถุประสงค์ C:
[self.navigationController.navigationBar setValue:@(YES) forKeyPath:@"hidesShadow"];
หากคุณต้องการใช้สีแถบนำทางที่มั่นคงและตั้งค่านี้ในกระดานเรื่องราวของคุณให้ใช้รหัสนี้ในAppDelegate
ชั้นเรียนของคุณเพื่อลบขอบ 1 พิกเซลผ่านพร็อกซีลักษณะที่ปรากฏ:
[[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 ฉันสร้าง a 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()
ทางออกที่ง่ายในรวดเร็ว
let navigationBar = self.navigationController?.navigationBar
navigationBar?.setBackgroundImage(UIImage(), forBarPosition: UIBarPosition.Any, barMetrics: UIBarMetrics.Default)
navigationBar?.shadowImage = UIImage()
หลังจากศึกษาคำตอบจาก Serhil ฉันสร้าง pod 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)
ตั้งแต่ iOS 13 จะมี API ของระบบสำหรับตั้งค่าหรือลบเงา
UIKit ใช้ shadowImage และคุณสมบัติ shadowColor เพื่อกำหนดลักษณะที่ปรากฏของเงา เมื่อ shadowImage เป็นศูนย์แถบจะแสดงเงาเริ่มต้นที่ย้อมสีตามค่าในคุณสมบัติ shadowColor หาก shadowColor เป็นศูนย์หรือมีสี clearColor แถบจะไม่แสดงเงา
let appearance = UINavigationBarAppearance()
appearance.shadowImage = nil
appearance.shadowColor = nil
navigationController.navigationBar.standardAppearance = appearance
https://developer.apple.com/documentation/uikit/uibarappearance/3198009-shadowimage
UINavigationBarAppearance
ส่วนหัว !! ฉันไม่เคยพบมัน ขอบคุณสิ่งนี้แก้ปัญหาของฉันได้ 100%
สามารถซ่อนจาก Storyboard ได้ (ทำงานกับ Xcode 10.1)
โดยการเพิ่มคุณสมบัติ runtime: hidesShadow - Boolean - True
โซลูชันของ 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
}
}
UINavigationController().navigationBar/toolbar.hide/showBottomHairline()
ไม่ได้ ฉันพยายามทำอย่างนี้ แต่ก็ไม่มีประโยชน์ ฉันไม่เข้าใจอย่างถูกต้องหรือไม่
Swift 4 // สำหรับการซ่อนเส้นเงาของแถบนำทาง
navigationController?.navigationBar.shadowImage = UIImage()
ฉันใช้ส่วนขยาย UINavigationBar ที่ทำให้ฉันสามารถซ่อน / แสดงเงานั้นโดยใช้ UIAppearance API หรือเลือกแถบนำทางที่มีเพื่อซ่อน / แสดงเงานั้นโดยใช้ Storyboard (หรือซอร์สโค้ด) นี่คือส่วนขยาย:
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
หรือคุณสามารถเปิด / ปิดการทำงานนี้โดยใช้กระดานเรื่องราว:
flatAssociatedObjectKey
เป็น int ที่ไม่ซ้ำกัน (ถือว่าเป็นตัวชี้) เพื่อระบุวัตถุที่เกี่ยวข้องของคุณ ที่นี่ถูกกำหนดโดยที่อยู่หน่วยความจำของ var ส่วนตัว ฉันอัปเดตการตอบสนองเพื่อเพิ่ม var นี้ ดูnshipster.com/associated-objectsสำหรับข้อมูลเพิ่มเติม
translucent
เป็นเท็จ
Swift 4 ผ่านการทดสอบ ONE LINE SOLUTION
ในการViewdidload()
ตั้งค่าเริ่มต้นของผู้ใช้ตัวควบคุมค่าเริ่มต้นจริงสำหรับคีย์ "hidesShadow"
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.setValue(true, forKey: "hidesShadow")
}
Swift ใส่สิ่งนี้
UINavigationBar.appearance().setBackgroundImage(UIImage(), forBarPosition: .Any, barMetrics: .Default)
UINavigationBar.appearance().shadowImage = UIImage()
ใน
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool
ตัวเลือกอื่นหากคุณต้องการรักษาความโปร่งแสงและไม่ต้องการซับคลาสทุก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
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()
}
โซลูชันในSwift 4.2:
private func removeHairlineFromNavbar() {
UINavigationBar.appearance().setBackgroundImage(
UIImage(),
for: .any,
barMetrics: .default)
UINavigationBar.appearance().shadowImage = UIImage()
}
เพียงแค่วางฟังก์ชั่นนี้ไว้ที่ Viewcontroller ตัวแรกและเรียกมันว่า viewdidload
ใน iOS8 ถ้าคุณตั้งค่าUINavigationBar.barStyle
การ.Black
คุณสามารถตั้งค่าพื้นหลังของแถบเป็นสีธรรมดาโดยไม่มีขอบ
ในสวิฟต์:
UINavigationBar.appearance().translucent = false
UINavigationBar.appearance().barStyle = UIBarStyle.Black
UINavigationBar.appearance().barTintColor = UIColor.redColor()
โซลูชันสองบรรทัดที่เหมาะกับฉัน ลองเพิ่มสิ่งนี้ในวิธีการ ViewDidLoad:
navigationController?.navigationBar.setValue(true, forKey: "hidesShadow")
self.extendedLayoutIncludesOpaqueBars = true
นี่เป็นวิธีแก้ปัญหาที่ง่ายมาก:
self.navigationController.navigationBar.clipsToBounds = YES;
สร้างส่วนขยาย:
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)
สำหรับผู้ใช้ iOS 9 สิ่งนี้ใช้ได้สำหรับฉัน เพียงเพิ่มสิ่งนี้:
UINavigationBar.appearance().shadowImage = UIImage()
คุณควรเพิ่มมุมมองที่ด้านล่างของ 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)
ฉันรู้ว่านี่เป็นเธรดเก่า แต่ฉันพบวิธีแก้ปัญหาที่ใช้งานได้ดีจริง ๆ :
คลาสย่อย 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
}
}
ภายใน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% ของผู้คน
-(void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
UIImage *emptyImage = [UIImage new];
self.navigationController.navigationBar.shadowImage = emptyImage;
[self.navigationController.navigationBar setBackgroundImage:emptyImage forBarMetrics:UIBarMetricsDefault];
}