프로그래밍 방식으로 탐색 막대의 높이를 얻습니다.


131

더 많은 뷰 컨트롤러 (탐색 표시 줄)가 있으면 UIView가 높이로 내려갑니다. 또한이 높이 = 44px임을 알고 있습니다. 나는 또한이 푸시 다운이를 유지한다는 것을 발견했다 [self.view].frame.origin.y = 0.

그렇다면이 탐색 막대의 높이를 상수로 설정하는 것 외에 어떻게 결정합니까?

또는 더 짧은 버전의 경우 내 UIView가 탐색 막대와 함께 표시되는지 어떻게 알 수 있습니까?


전구가 켜지 기 시작했습니다. 불행히도 아래 설명과 같이 문제를 해결하는 획일적 인 방법을 찾지 못했습니다.

나는 내 모든 문제가 내 자동 크기 조정 마스크에 집중되어 있다고 생각합니다. 그리고 UIWebView의 유무에 관계없이 동일한 증상이 있다고 결론 내린 이유. 그리고 그 증상은 모든 것이 초상화에 복숭아 색이라는 것입니다. Landscape의 경우 맨 아래 UIButton이 TabBar 뒤에 나타납니다.

예를 들어 하나의 UIView에서 위에서 아래로 있습니다.

UIView – 스프링 설정 (기본 경우) 및 스트럿 없음

UIScrollView-두 개의 스프링을 설정하고 UIView와 같은 다른 모든 항목을 지우면 UIButton이 바로 위에있는 객체에 침입합니다. 모든 것을 지우면 UIButton은 정상이지만 맨 위에있는 것은 StatusBar 뒤에 숨겨지고 UI 스트럿은 Tab Bar 뒤에 나타납니다.

UILabel과 UIImage는 다음 수직 방향 – 상단 스트럿 세트, 다른 곳에서도 유연

UIWebView가있는 몇 가지 그림을 완성하십시오.

UIWebView-스트럿 : 위, 왼쪽, 오른쪽 스프링 : 둘 다

UIButton – 아무것도 설정되지 않음, 즉 어디에서나 유연

전구가 희미하지만 희망이있는 것 같습니다.


짧은 답글 코멘트에 제공된 것보다 더 많은 공간이 필요했기 때문에 저와 함께 해주십시오.

내가 정말로 낚시하는 것을 이해하려고 노력해 주셔서 감사합니다 ... 그래서 여기에갑니다.

1) 각 UIViewController (TabBar 앱)에는 UIImage, 일부 텍스트 및 그 밖의 모든 것이 있습니다. 또 다른 공통 분모는 맨 아래에있는 UIButton입니다. 일부 UIViewController에서 UIButton 위에 UIWebView가 있습니다.

따라서 UIImage, 텍스트 등 UIWebView (일부) UIButton

위의 모든 것은 UIScrollView입니다.

2) UIWebView가있는 사람들의 경우 autoresizingMask는 다음과 같습니다.

   
   |
   

   ^
   |
   |

| — | ← ---- → | — | | | V UIButton의 마스크는 아무것도 설정되어 있지 않습니다.

내 -viewDidLoad 내에서 -repositionSubViews를 호출하여 다음을 수행합니다.

UIWebView가 없으면 IB로 배치 한 UIButton을 중앙에 두는 것 외에는 아무것도하지 않습니다.

UIWebView가 있으면 * content * Height를 결정하고 전체 내용을 포함하도록 프레임을 설정합니다.

UIScrollView *scrollViewInsideWebView = [[webView_ subviews] lastObject];
webViewContentHeight = scrollViewInsideWebView.contentSize.height;
[webView_ setFrame:CGRectMake(webViewOriginX, webViewOriginY,
                          sameWholeViewScrollerWidth, webViewContentHeight)]

일단 그렇게하면 프로그래밍 방식으로 UIButton을 아래로 밀어 UIWebView 아래에 배치됩니다.

세로에서 가로로 회전 할 때까지 모든 것이 작동합니다.

내 -didRotateFromInterfaceOrientation 내에서 -repositionSubViews를 호출합니다.

UIWebView의 컨텐츠 높이가 회전과 함께 변경되지 않는 이유는 무엇입니까?

세로에서 가로로 콘텐츠 너비가 확장되고 콘텐츠 높이가 줄어 듭니다. NSLog에 따르면 시각적으로 정상적으로 수행됩니다.

어쨌든 UIWebView의 유무에 관계없이, 내가 이야기 한 버튼은 가로 모드에있을 때 TabBar 아래로 이동하지만 화면이 위로 스크롤되지는 않습니다. "강력하게"스크롤하면 TabBar 뒤에서 볼 수 있지만 TabBar 뒤에서 "뒤로"떨어집니다.

결론적으로, 이것은 마지막으로 TabBar와 NavigationBar의 높이에 대해 물었습니다. TabBar 자체가 UIView의 맨 아래에 배치되고 NavigationBar가 UIView를 아래로 밀기 때문입니다.

이제 여기에 이해가되지 않았기 때문에 여기에 의견을 추가하겠습니다.

UIWebView가 없으면 IB에서 보는 것처럼 모든 것을 그대로 둡니다.

UIWebView를 사용하면 UIWebView의 frame.height를 contentHeight로 늘리고 모든 하위 뷰를 둘러싸는 주변 UIScrollView의 높이를 위로 조정합니다.

잘 있어요.

답변:


258

이런 식으로합니까?

    NSLog(@"Navframe Height=%f",
        self.navigationController.navigationBar.frame.size.height);

빠른 버전은 여기에 있습니다


최신 정보

iOS 13

는 다음과 같이 statusBarFrame사용되지 않습니다 iOS13당신이 사용할 수 있습니다 :

extension UIViewController {

    /**
     *  Height of status bar + navigation bar (if navigation bar exist)
     */

    var topbarHeight: CGFloat {
        return (view.window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0.0) +
            (self.navigationController?.navigationBar.frame.height ?? 0.0)
    }
}

고마워 고마워 그러나이 문제를 해결 했으므로 MoreViewController라고 불리는 NavigationController가 내 탭 표시 줄 앱에 표시되는지 어떻게 알 수 있습니까?

나는 당신이 말하려는 것을 얻지 못합니다. MoreViewController가 표시되는지 확인하려고합니까? (그렇다면 무엇을하고 싶습니까?) 그렇지 않은 경우 정확히 무엇을 의미하는지 명확히 할 수 있습니까?
Sum

나는 당신의 질문을 다시 읽었지만 아직도 당신이하고 싶은 것을 이해하지 못했습니까? 뷰가 나타날 때 무언가를하려면 코드를 viewDidAppear에 삽입해야합니다. 조금 설명하면 원하는 것을 쉽게 파악할 수 있습니다.
Sum

2
나는 이것이 그가 요구 한 질문을 다루지 않는다는 것을 알고 있지만, navigationBar가 숨겨져 있는지 여부를보고있는 것 같습니다. 그렇다면 그는 self.navigationController.navigationBarHidden 희망을 사용할 수 있습니다. 이것은 완전히 누군가에게 도움이됩니다 :)
taylorcressy

2
아이폰 OS에서 7+ 당신은 또한 20 픽셀 상태 표시 줄 응용 프로그램에 따라 고려해야 할
Slayter

94

iPhone-X에서는 상단 표시 줄 (탐색 표시 줄 + 상태 표시 줄)의 높이가 변경됩니다 (증가).

상단 막대 (탐색 막대 + 상태 표시 줄)의 정확한 높이를 원하면이 방법을 사용하십시오.

최신 정보

iOS 13

는 다음과 같이 statusBarFrame사용되지 않습니다 iOS13당신이 사용할 수 있습니다 :

extension UIViewController {

    /**
     *  Height of status bar + navigation bar (if navigation bar exist)
     */

    var topbarHeight: CGFloat {
        return (view.window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0.0) +
            (self.navigationController?.navigationBar.frame.height ?? 0.0)
    }
}

목표 -C

CGFloat topbarHeight = ([UIApplication sharedApplication].statusBarFrame.size.height +
       (self.navigationController.navigationBar.frame.size.height ?: 0.0));

스위프트 4

let topBarHeight = UIApplication.shared.statusBarFrame.size.height +
        (self.navigationController?.navigationBar.frame.height ?? 0.0)

쉽게 UIViewController 확장을 시도하십시오

extension UIViewController {

    /**
     *  Height of status bar + navigation bar (if navigation bar exist)
     */

    var topbarHeight: CGFloat {
        return UIApplication.shared.statusBarFrame.size.height +
            (self.navigationController?.navigationBar.frame.height ?? 0.0)
    }
}

스위프트 3

let topBarHeight = UIApplication.sharedApplication().statusBarFrame.size.height +
(self.navigationController?.navigationBar.frame.height ?? 0.0)


3
Swift 4 답변은 나를 위해 0 높이를 반환합니다.
Chewie The Chorkie

61

스위프트 버전 :

let navigationBarHeight: CGFloat = self.navigationController!.navigationBar.frame.height

항상 44를 반환합니다. 축소 된 크기 (44) 또는 확장 된 크기 (큰 제목)를 아는 방법 ??? 물론 동적으로. (나는 그것이 무엇을 측정하는지 안다)
Markus

6

이것을 시도 했습니까?

let barHeight = self.navigationController?.navigationBar.frame.height ?? 0

5

iOS 13 이하 지원 :

extension UIViewController {

    var topbarHeight: CGFloat {
        if #available(iOS 13.0, *) {
            return (view.window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0.0) +
                (self.navigationController?.navigationBar.frame.height ?? 0.0)
        } else {
            let topBarHeight = UIApplication.shared.statusBarFrame.size.height +
            (self.navigationController?.navigationBar.frame.height ?? 0.0)
            return topBarHeight
        }
    }
}

4
UIImage*image = [UIImage imageNamed:@"logo"];

float targetHeight = self.navigationController.navigationBar.frame.size.height;
float logoRatio = image.size.width / image.size.height;
float targetWidth = targetHeight * logoRatio;

UIImageView*logoView = [[UIImageView alloc] initWithImage:image];
// X or Y position can not be manipulated because autolayout handles positions.
//[logoView setFrame:CGRectMake((self.navigationController.navigationBar.frame.size.width - targetWidth) / 2 , (self.navigationController.navigationBar.frame.size.height - targetHeight) / 2 , targetWidth, targetHeight)];
[logoView setFrame:CGRectMake(0, 0, targetWidth, targetHeight)];
self.navigationItem.titleView = logoView;

// How much you pull out the strings and struts, with autolayout, your image will fill the width on navigation bar. So setting only height and content mode is enough/
[logoView setContentMode:UIViewContentModeScaleAspectFit];

/* Autolayout constraints also can not be manipulated since navigation bar has  immutable constraints
self.navigationItem.titleView.translatesAutoresizingMaskIntoConstraints = false;

NSDictionary*metricsArray = @{@"width":[NSNumber numberWithFloat:targetWidth],@"height":[NSNumber numberWithFloat:targetHeight],@"margin":[NSNumber numberWithFloat:20]};
NSDictionary*viewsArray = @{@"titleView":self.navigationItem.titleView};

[self.navigationItem.titleView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-(>margin=)-H:[titleView(width)]-(>margin=)-|" options:NSLayoutFormatAlignAllCenterX metrics:metricsArray views:viewsArray]];
[self.navigationItem.titleView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[titleView(height)]" options:0 metrics:metricsArray views:viewsArray]];

NSLog(@"%f", self.navigationItem.titleView.width );
*/

우리가 실제로 필요한 것은

UIImage*image = [UIImage imageNamed:@"logo"];
UIImageView*logoView = [[UIImageView alloc] initWithImage:image];
float targetHeight = self.navigationController.navigationBar.frame.size.height;
[logoView setFrame:CGRectMake(0, 0, 0, targetHeight)];
[logoView setContentMode:UIViewContentModeScaleAspectFit];

self.navigationItem.titleView = logoView;

2

내 응용 프로그램에는 탐색 컨트롤러가없는 모양과 느낌을 위해 UI에 사용자 정의 된 탐색 모음이 필요한 몇 가지보기가 있습니다. 그리고 응용 프로그램은 iOS 11 이전의 iOS 버전을 지원해야하므로 편리한 안전 영역 레이아웃 가이드를 사용할 수 없으며 탐색 막대의 위치와 높이를 프로그래밍 방식으로 조정해야합니다.

위에서 언급 한대로 안전 영역 레이아웃 안내를 건너 뛰고 내비게이션 바를 슈퍼 뷰에 직접 연결했습니다. 상태 막대 높이는 UIApplication에서 쉽게 검색 할 수 있지만 기본 탐색 막대 높이는 정말 고통 스럽습니다 ...

거의 다른 밤 (나에게 작동하지는 않지만)에서 힌트를 얻을 때까지 거의 반나절 동안 많은 검색과 테스트를 통해 나를 놀라게했습니다 .UIView.sizeThatFits ()에서 실제로 높이를 얻을 수 있습니다. :

- (void)viewWillLayoutSubviews {
    self.topBarHeightConstraint.constant = [UIApplication sharedApplication].statusBarFrame.size.height;
    self.navBarHeightConstraint.constant = [self.navigationBar sizeThatFits:CGSizeZero].height;

    [super viewWillLayoutSubviews];    
}

마지막으로 내장 된 것과 완전히 동일한 완벽한 탐색 표시 줄!


2

navigationBar높이 만 얻으려면 간단합니다.

extension UIViewController{
   var navigationBarHeight: CGFloat {
       return self.navigationController?.navigationBar.frame.height ?? 0.0
   }
}

그러나 iPhone의 최고 수준의 높이가 필요한 경우 높이를 가져 와서 navigationBar높이를 추가 할 필요가 없으므로 statusBar간단히 전화 할 수 safeAreaInsets있습니다.

self.view.safeAreaInsets.top

1

전구가 켜지 기 시작했습니다. 불행히도 아래 설명과 같이 문제를 해결하는 획일적 인 방법을 찾지 못했습니다.

나는 내 모든 문제가 내 자동 크기 조정 마스크에 집중되어 있다고 생각합니다. 그리고 UIWebView의 유무에 관계없이 동일한 증상이 있다고 결론 내린 이유. 그리고 그 증상은 모든 것이 초상화에 복숭아 색이라는 것입니다. Landscape의 경우 맨 아래 UIButton이 TabBar 뒤에 나타납니다.

예를 들어 하나의 UIView에서 위에서 아래로 있습니다.

UIView – 스프링 설정 (기본 경우) 및 스트럿 없음

UIScrollView- 두 개의 스프링을 설정하고 UIView와 같은 다른 모든 항목을 지우면 UIButton이 바로 위에있는 객체에 침입합니다. 모든 것을 지우면 UIButton은 정상이지만 맨 위에있는 것은 StatusBar 뒤에 숨겨져 있으며 UI 스트럿은 맨 위 스트럿 만 숨기고 UIButton은 Tab Bar 뒤에 나타납니다.

UILabel과 UIImage는 다음 수직 방향 – 상단 스트럿 세트, 다른 곳에서도 유연

UIWebView가있는 몇 가지 그림을 완성하십시오.

UIWebView- 스트럿 : 위, 왼쪽, 오른쪽 스프링 : 둘 다

UIButton – 아무것도 설정되지 않음, 즉 어디에서나 유연

전구가 희미하지만 희망이있는 것 같습니다.


상단 스트럿을 설정하고 UIWebView의 두 가지 스프링을 설정하십시오-문제가 해결되고 감사합니다. 사실 저의 유일한 문제는 저주받은 @ 2X 등의 그래픽을 디자인하는 것입니다. 나는 매우 간단한 방법으로 GraphicConverter를 사용하며 웹 페이지 디자인에 매우 적합합니다. 그러나이 모든 30px, 57px 물건-나는 적어도 나에게 미지의 영역으로 가고 있습니다.

1

다음은 귀하의 업데이트에 대한 답변의 시작입니다.

UIWebView의 컨텐츠 높이가 회전과 함께 변경되지 않는 이유는 무엇입니까?

자동 크기 조정에 모든 방향에 대한 자동 크기 조정 마스크가 없기 때문일 수 있습니까?

내가 다시 돌아 오기 전에 또 다른 제안, 당신은 당신의 요구에 툴바를 사용할 수 있습니다. 조금 더 간단하고 항상 맨 아래에 있으며 자동 회전 / 위치입니다. 다음과 같은 종류로 숨길 수 있습니다. http://cdn.artoftheiphone.com/wp-content/uploads/2009/01/yellow-pages-iphone-app-2.jpg

그 옵션을 보았을 수도 있지만 그냥 버릴 수도 있습니다.

또 다른 아이디어는 회전 방향을 감지하고 버튼을 프로그래밍 방식으로 배치하여 탭 막대에 맞게 조정하는 것입니다. (이것은 코드로 가능합니다)


이 문제를 해결하는 데 약 2 주가 지난 후 UIWebView 하위 뷰 아래에 UIButton을 배치하여 "문제"가 더 어려워 졌다고 판단했습니다. 그래서 나는 위에 버튼을 넣었습니다. 솔직히 말해서, 그것은 "그렇지 않은"것처럼 보이지만 ... 이제는 SORT OF로 작동합니다. 아래 또는 위에 UIWebView는 상단 스트럿과 수평 스프링 만 설정했습니다. BTW, UIWebView의 contentHeight는 회전과 함께 변경되지 않습니다.

0

나는 사용했다 :

let originY: CGFloat = self.navigationController!.navigationBar.frame.maxY

탐색 막대 높이와 ​​Y 원점을 얻으려면 훌륭하게 작동합니다.



0

다른 사람에게 도움이 될 경우를 대비하여 Handy Swift 4 확장 프로그램입니다. 현재보기 컨트롤러에 탐색 모음이 표시되지 않더라도 작동합니다.

import UIKit

extension UINavigationController {
  static public func navBarHeight() -> CGFloat {
    let nVc = UINavigationController(rootViewController: UIViewController(nibName: nil, bundle: nil))
    let navBarHeight = nVc.navigationBar.frame.size.height
    return navBarHeight
  }
}

용법:

UINavigationController.navBarHeight()
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.