때로는 콘텐츠와 혼합하기 위해 탐색 막대가 필요한 앱이 있습니다.
이 성가신 작은 막대의 제거 또는 색상 변경 방법을 아는 사람이 있습니까?
아래 이미지에서 나는 가지고있다-나는 "루트 뷰 컨트롤러"아래의 1px 높이 라인에 대해 이야기하고있다.
때로는 콘텐츠와 혼합하기 위해 탐색 막대가 필요한 앱이 있습니다.
이 성가신 작은 막대의 제거 또는 색상 변경 방법을 아는 사람이 있습니까?
아래 이미지에서 나는 가지고있다-나는 "루트 뷰 컨트롤러"아래의 1px 높이 라인에 대해 이야기하고있다.
답변:
.shadowColor
속성을 사용하십시오
이 속성이 nil이거나 선명한 색상을 포함하면 막대에 그림자가 표시되지 않습니다
예를 들어 :
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()
색으로 채워진 작은 배경 이미지를 만들어 사용하십시오.
아래 설명 된 'hacky'방법을 사용하십시오. 또한 막대를 반투명하게 유지합니다.
반 투명성을 유지하려면 다른 접근 방식이 필요합니다. 해킹처럼 보이지만 잘 작동합니다. 제거하려는 그림자는 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 버전을 추가하고 싶었습니다. 나는 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의 답변을 연구 한 후, 나는 헤어 라인을 쉽게 숨길 수 있는 포드 UINavigationBar + Addition 을 만들었습니다 .
#import "UINavigationBar+Addition.h"
- (void)viewDidLoad {
[super viewDidLoad];
UINavigationBar *navigationBar = self.navigationController.navigationBar;
[navigationBar hideBottomHairline];
}
iOS 13부터 그림자를 설정하거나 제거하는 시스템 API가 있습니다.
UIKit은 shadowImage 및 shadowColor 속성을 사용하여 그림자의 모양을 결정합니다. shadowImage가 nil 인 경우 막대는 shadowColor 속성의 값에 따라 색조가 지정된 기본 그림자를 표시합니다. shadowColor가 0이거나 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 % 해결했습니다.
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
}
}
UINavigationController().navigationBar/toolbar.hide/showBottomHairline()
합니까? 나는 이것을 시도하고 있지만 소용이 없다. 올바르게 이해하지 못합니까?
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
또는 스토리 보드를 사용하여이 동작을 활성화 / 비활성화 할 수 있습니다.
flatAssociatedObjectKey
연결된 객체를 식별하는 고유 한 int (포인터로 취급)로 생각할 수 있습니다 . 여기는 개인 변수의 메모리 주소로 정의됩니다. 이 var를 추가하기 위해 응답을 업데이트했습니다. 자세한 정보는 nshipster.com/related-objects 를 참조하십시오 .
translucent
false 로 설정된 경우에만 작동
스위프트 4 테스트 한 라인 솔루션
에서 Viewdidload()
키 "hidesShadow"에 대한 true로 설정 탐색 컨트롤러의 userdefault 값
override func viewDidLoad() {
super.viewDidLoad()
self.navigationController?.navigationBar.setValue(true, forKey: "hidesShadow")
}
스위프트는 이것을 넣어
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()
}
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)
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 %의 사람들에게 도움이됩니다.