ios - UINavigationBar 1px नीचे पंक्ति को कैसे छिपाना है




objective-c swift (20)

मेरे पास एक ऐप है जिसे सामग्री के साथ मिश्रण करने के लिए कभी-कभी इसकी नेविगेशन बार की आवश्यकता होती है।

क्या कोई इस कष्टप्रद छोटी बार के रंग से छुटकारा पाने या बदलने के बारे में जानता है?

नीचे दी गई छवि की छवि पर मेरे पास है - मैं "रूट व्यू कंट्रोलर" के नीचे इस 1px ऊंचाई रेखा के बारे में बात कर रहा हूं


आईओएस 8 में, यदि आप UINavigationBar.barStyle को सेट करते हैं .Black आप बार की पृष्ठभूमि को सीमा के बिना सादे रंग के रूप में सेट कर सकते हैं।

स्विफ्ट में:

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

आईओएस 9 उपयोगकर्ताओं के लिए, यह मेरे लिए काम किया। बस इसे जोड़ें:

UINavigationBar.appearance().shadowImage = UIImage()

इसे इस्तेमाल करे:

[[UINavigationBar appearance] setBackgroundImage: [UIImage new]  
                                   forBarMetrics: UIBarMetricsDefault];

[UINavigationBar appearance].shadowImage = [UIImage new];

छवि के नीचे स्पष्टीकरण (आईओएस 7 नेविगेशनबार) है:

और इस एसओ सवाल की जांच करें: आईओएस 7 - यूआईएनविगेशनबार सीमा रंग बदलें


इसे करने का तेज़ तरीका:

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

UINavigationBar.appearance().shadowImage = UIImage()

एक और विकल्प यदि आप पारदर्शिता को संरक्षित करना चाहते हैं और आप अपने ऐप में प्रत्येक UINavigationController को उप 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

ऐसा करने के लिए, आपको कस्टम छाया छवि सेट करनी चाहिए। लेकिन छाया छवि को दिखाने के लिए आपको कस्टम पृष्ठभूमि छवि सेट करने की भी आवश्यकता है, ऐप्पल के दस्तावेज़ से उद्धरण:

कस्टम छाया छवि को दिखाने के लिए, कस्टम पृष्ठभूमि छवि को सेटबैकग्राउंड छवि (_: :) :) विधि के साथ भी सेट किया जाना चाहिए। यदि डिफ़ॉल्ट पृष्ठभूमि छवि का उपयोग किया जाता है, तो डिफ़ॉल्ट संपत्ति छवि का उपयोग इस संपत्ति के मूल्य के बावजूद किया जाएगा।

इसलिए:

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

इसे छिपाने का एकमात्र "आधिकारिक" तरीका है। दुर्भाग्यवश, यह बार की पारदर्शिता को हटा देता है।

मुझे पृष्ठभूमि छवि नहीं चाहिए, सिर्फ रंग

आपके पास ये विकल्प हैं:

  1. ठोस रंग, कोई पारदर्शिता नहीं:

    navigationBar.barTintColor = UIColor.redColor()
    navigationBar.isTranslucent = false
    navigationBar.setBackgroundImage(UIImage(), for: .default)
    navigationBar.shadowImage = UIImage()
    
  2. रंग से भरा छोटी पृष्ठभूमि छवि बनाएं और इसका इस्तेमाल करें।

  3. नीचे वर्णित 'हैकी' विधि का प्रयोग करें। यह बार पारदर्शी भी रखेगा।

बार पारदर्शी कैसे रखें?

पारदर्शिता रखने के लिए आपको एक और दृष्टिकोण की आवश्यकता है, यह एक हैक की तरह दिखता है लेकिन अच्छी तरह से काम करता है। जिस छाया को हम हटाने की कोशिश कर रहे हैं वह UINavigationBar नीचे कहीं भी एक हेयरलाइन UIImageView है। आवश्यकता होने पर हम इसे पा सकते हैं और छुपा सकते हैं / दिखा सकते हैं।

नीचे दिए गए निर्देश मानते हैं कि आपको केवल अपने UINavigationController नियंत्रक पदानुक्रम के एक नियंत्रक में छुपा हेयरलाइन की आवश्यकता है।

  1. आवृत्ति चर घोषित करें:

    private var shadowImageView: UIImageView?
    
  2. विधि जोड़ें जो इस छाया को पाता है (हेयरलाइन) 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. 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 हेयरलाइन के लिए भी वही विधि काम करनी चाहिए, और (लगभग) कुछ भी जो आपको छिपाने की जरूरत है :)

मूल विचार के लिए @ लियो नतन के लिए बहुत धन्यवाद!


नेविगेशन बार छाया रेखा छिपाने के लिए स्विफ्ट 4 //

navigationController?.navigationBar.shadowImage = UIImage()

पृष्ठभूमि छवि सेट करने में समस्या यह धुंधला हो जाती है। आप पृष्ठभूमि छवि सेट किए बिना इसे हटा सकते हैं। मेरा जवाब here देखें।


मुझे पता है कि यह एक पुराना धागा है, लेकिन मुझे एक समाधान मिला जो वास्तव में अच्छा काम करता है:

Subclass UINavigationBar। आपके UINavigationBar उप-वर्ग में, निम्न कोड के साथ ADAddSubview ओवरराइड किया गया:

- (void)didAddSubview:(UIView *)subview
{
    [super didAddSubview:subview];

    if ([subview isKindOfClass:[UIImageView class]]) {
        [subview setClipsToBounds:YES];
    }
}

मेरा दृष्टिकोण:

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)

मैंने बस इसके लिए एक एक्सटेंशन बनाया है ... स्वरूपण के बारे में खेद है (यह मेरा पहला जवाब है)।

उपयोग:

  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
    }


}

यदि आप केवल एक ठोस नेविगेशन बार रंग का उपयोग करना चाहते हैं और इसे अपने स्टोरीबोर्ड में सेट अप करना चाहते हैं, तो उपस्थिति प्रॉक्सी के माध्यम से 1 पिक्सेल सीमा को हटाने के लिए इस कोड का उपयोग अपने AppDelegate क्लास में करें:

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

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

यहां एक और विकल्प है - मुझे लगता है कि यह केवल तभी काम करता है जब आपको अपने नेविगेशन बार पर पारदर्शिता की आवश्यकता नहीं है (मैंने नहीं किया)। मैंने एनवी बार के नीचे एक ही रंग के साथ नेविगेशन बार (एनवी बार के नीचे 1 पिक्सेल) के नीचे एक पिक्सेल उच्च UIView जोड़ा है:

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

मैं चिनाई का उपयोग कर बाधाओं को जोड़ रहा हूँ।


यहां एक बहुत ही सरल समाधान है:

self.navigationController.navigationBar.clipsToBounds = YES;

सेरिल से जवाब का अध्ययन करने के बाद, मैंने एक पॉड UINavigationBar+Addition जो आसानी से हेयरलाइन को छुपा सकता है।

#import "UINavigationBar+Addition.h"

- (void)viewDidLoad {
    [super viewDidLoad];

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

सेरी के जवाब के स्विफ्ट संस्करण को जोड़ना चाहता था। मैंने निम्नलिखित के साथ 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
    }
}

स्विफ्ट 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
  }
}

स्विफ्ट 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)

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