UIStatusBarStyle PreferredStatusBarStyle은 iOS 7에서 작동하지 않습니다.


110

아이폰 OS 7 I 세트의 엑스 코드 5와 내장 내 아이폰 응용 프로그램에서 UIViewControllerBasedStatusBarAppearance=YES에서 info.plist, 그리고 내에서 ViewController이 코드를 가지고 :

-(UIStatusBarStyle) preferredStatusBarStyle
{
    return UIStatusBarStyleLightContent;
}

그러나 상태 표시 줄은 검은 색 배경에 대해 여전히 검은 색입니다.

UIViewControllerBasedStatusBarAppearance=NO에서 설정하여이 앱 전체를 변경할 수 있다는 것을 알고 info.plist있지만 실제로 런타임 viewControllerviewController이를 기준으로 변경해야 합니다.


안녕하세요, 질문에서 언급 한 것과 동일한 문제가 있습니다. 해결책을 얻었습니까? 알려주세요.
Noundla Sandeep 2015

답변:


281

ViewController가 navigationController 안에 있으면 navigationController가 navigationBar.barStylestatusBarStyle을 결정 한다는 것을 발견했습니다 .

당신의 내비게이션 바의 설정 barStyle하려면 UIBarStyleBlackTranslucent(예. 흰색 상태 표시 줄의 텍스트를 줄 것이다 UIStatusBarStyleLightContent), 그리고 UIBarStyleDefault검은 상태 표시 줄의 텍스트를 줄 것이다 (예. UIStatusBarStyleDefault).

참고 이것은 당신이 완전히의를 통해 내비게이션 바의 색상을 변경하는 경우에도 적용 barTintColor.


이 큰 ... 나에게 의미가 있습니다

14
나는이 그것 때문에 생각 UINavigationControllerpreferredStatusBarStyle의 ViewController이 호스트를 통해 호출하지 않고, 대신 그 navigationBarStyle에 따라 반환합니다.
mxcl

이 경우보기는 탐색 컨트롤러 내부에 없습니다.
Andrew Smith

바 스타일이 뷰 컨트롤러에서 구현 된 방법보다 우선권을 갖는다 고 생각하는 것은 매우 반 직관적이며 모달 뷰를 표시 할 때만 가능합니다!
Matej 2014

3
UIBarStyleBlackTranslucent 사용되지 않으며, 사용 UIBarStyleBlack대신에
Nhon의 응우 엔

87

좋아요, 여기에 트릭이 있습니다. "컨트롤러 기반 상태 표시 줄보기"키를 추가하고 값을 아니요로 설정해야합니다.

이것은이 키의 의미와 반대이지만 값을로 설정하더라도 No상태 표시 줄의 모양과보기 컨트롤러에 표시되는지 여부를 변경할 수 있습니다. 따라서 "예"처럼 작동하지만 "아니오"로 설정합니다!

이제 상태 표시 줄을 흰색 또는 어둡게 표시 할 수 있습니다.


6
나를 위해 이것은 잘못되었습니다. 예상대로 키를 "예"로 설정해야합니다. 저는 Xcode 5.1 iOS 7.1을 사용 중이므로 변경되었을 수 있습니다.
joel.d

나는 Xcode 5.1과 iOS 7.1도 사용하고 있으며 나를 위해 일하지 않았습니다.
Arjun Mehta 2014 년

이 키를 어디에 추가해야합니까?
Hadu

[AppName] -Info.plist 파일
Saren Inden

1
Xcode6.0, iOS 8.0에서 "View controller-based status bar"키를 "YES"로 설정하면 잘 작동합니다.
bpolat

77

들어 preferredStatusBarStyle()내에서 작동하도록 UINavigationController하고 UITabBarController나는 현재 보이는 뷰 컨트롤러에서 선호하는 상태 표시 줄 스타일을 얻을 것이다 다음 코드를 추가합니다.

extension UITabBarController {
    public override func childViewControllerForStatusBarStyle() -> UIViewController? {
        return selectedViewController
    }
}

extension UINavigationController {
    public override func childViewControllerForStatusBarStyle() -> UIViewController? {
        return visibleViewController
    }
}

들어 스위프트 3 사람들은 방법이 있지만, 속성은 없습니다 :

extension UITabBarController {
    open override var childViewControllerForStatusBarStyle: UIViewController? {
        return selectedViewController
    }
}

extension UINavigationController {
    open override var childViewControllerForStatusBarStyle: UIViewController? {
        return visibleViewController
    }
}

스위프트 4.2 속성은 이름이 변경되었습니다 :

extension UITabBarController {
   open override var childForStatusBarStyle: UIViewController? {
        return selectedViewController
    }
}

extension UINavigationController {
   open override var childForStatusBarStyle: UIViewController? {
        return visibleViewController
    }
}

용법

class ViewController: UIViewController {

    // This will be called every time the ViewController appears
    // Works great for pushing & popping
    override var preferredStatusBarStyle: UIStatusBarStyle {
        return .lightContent
    }

}

6
이것은 단연 최고의 답변입니다 (UINavigationController 또는 UITabBarController를 사용하는 앱의 경우
Kesava

1
이것에 대한 사용법은 무엇입니까?
AnBisw

@Annjawn 이러한 메서드는 UIKit에서 사용됩니다. 프로젝트에 추가하는 것 외에 다른 작업을 수행 할 필요가 없습니다.
Daniel Wood

@DanielWood 그래 나는 약간 다르지만 이전 프로젝트 중 하나에서 똑같은 것을 사용했다는 것을 알았고 완전히 잊었습니다.
AnBisw 2017

이 실제로 가장 좋은 대답
무사 almatri

33

나는 이것에 조금 늦게 올 수 있지만 다른 누군가가 작동하고 검증 된 앱 전체 솔루션을 찾고있는 경우를 대비하십시오.

@mxcl은 이것이 왜 발생하는지 설명하는 데 정확합니다. 이를 수정하기 위해 UINavigationController의 preferredSatusBarStyle () 메서드를 재정의하는 확장 (또는 obj-c의 범주)을 만듭니다. 다음은 Swift의 예입니다.

extension UINavigationController {
    public override func preferredStatusBarStyle() -> UIStatusBarStyle {
        if let rootViewController = self.viewControllers.first {
            return rootViewController.preferredStatusBarStyle()
        }
        return super.preferredStatusBarStyle()
    }
}

이 코드는 단순히 첫 번째 뷰 컨트롤러 (루트 뷰 컨트롤러)를 추출하고 래핑을 해제합니다 (obj-c에서 nil이 아닌지 확인). unwrap이 성공하면 (nil이 아님) rootViewControllers preferredStatusBarStyle을 가져옵니다. 그렇지 않으면 기본값을 반환합니다.

이것이 필요한 사람에게 도움이되기를 바랍니다.


2
Swift 2.0에서는 조건 문의 "as? UIViewController"를 제거해야합니다.
Thomás Calmon 15. 9.

훌륭합니다. "as"문을 제거하는 것 외에도 한 가지 수정을했습니다. 이렇게하면 스택의 맨 위에있는 사용자가 보는 뷰 컨트롤러가 제어 할 수있는 기능을 "first"에서 "last"로 변경했습니다. 상태 표시 줄의 색상입니다. 공유 해주셔서 감사합니다!
Unome 2015

1
탐색 컨트롤러에 뷰 컨트롤러가없는 경우 무한 루프가 발생합니다. return self.preferredStatusBarStyle()이 똑같은 방법으로 다시 호출합니다.
bearMountain

1
제 경우에는 rootViewController를 사용하는 대신 스타일이 변경 될 수있는 스택 중에 topViewController를 사용했습니다.
릭 산토스

2
@Unome은 visibleViewController더 나은 것
쾨르

21

허용되는 답변에 대한 자세한 내용을 제공하려면 앱 델리게이트의 didFinishLaunchingWithOptions:메서드 에 다음 줄을 입력하세요 .

[UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;

그런 다음 Info.plist에서 추가 View controller-based status bar appearance하고 NO.

전체 앱에 대해 동일한 상태 표시 줄 색상을 원하면 탐색 컨트롤러가 아닌 그렇게해야한다고 생각합니다. 에 반드시 포함되지 않은 화면 UINavigationController이나 다른 UINavigationController하위 클래스 및 기타 항목이있을 수 있습니다.

편집 : 코드를 입력하지 않고도 할 수 있습니다 : https://stackoverflow.com/a/18732865/855680


1
이 방법은 IOS 9.0에서 더 이상 사용되지 않습니다
Mohamed Salah

10

viewDidLoad에서 이것을 작성하십시오.

[self setNeedsStatusBarAppearanceUpdate];

그냥 그렇게하면 작동합니다

이거 먹어봐

Set UIViewControllerBasedStatusBarAppearance to NO.
Call [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];

당신이 이와 같은 방법을 썼다는 당신의 질문에서 내가 본 또 하나

 -(void)UIStatusBarStyle PreferredStatusBarStyle ()
        {
            return UIStatusBarStyle.LightContent;
        }

근데 이럴거야

-(UIStatusBarStyle)preferredStatusBarStyle{ 
    return UIStatusBarStyleLightContent; 
} 

이로 인해 preferredStatusBarStyle 메서드가 호출되지만 상태 표시 줄은 여전히 ​​검은 색입니다.
Andrew Smith

내 업데이트 된 답변을 참조하십시오. 작동 여부를 신속하게 알려주세요
User 1531343

내 원래 질문은 상태 표시 줄의보기 제어를 통해보기를 수행해야한다고 명시 적으로 말합니다.
앤드류 스미스

업데이트 된 질문을 참조하여 코드를 확인할 수 있습니까?
사용자 1,531,343

1
[self setNeedsStatusBarAppearanceUpdate];정말 좋은 방법입니다. 감사합니다!
Supertecnoboff

6

여기에 내가 해결 한 방법이 있습니다. 일반적으로 navigationController 또는 tabBarController는 상태 표시 줄의 모양 (숨김, 색상 등)을 결정합니다.

그래서 결국 네비게이션 컨트롤러를 서브 클래 싱하고 preferredStatusBarStyle을 재정의했습니다. 현재 보이는 ViewContorller가 StatusBarStyleHandler를 구현하면 스타일로 사용할 값을 요청합니다. 그렇지 않으면 기본값을 반환합니다.

상태 표시 줄 모양의 업데이트를 트리거하는 방법은 메서드가 반환하는 내용에 따라 다시 setNeedsStatusBarAppearanceUpdate트리거 preferredStatusBarStyle하고 UI를 업데이트 하는 호출 을 호출 하는 것입니다.

public protocol StatusBarStyleHandler {
    var preferredStatusBarStyle: UIStatusBarStyle { get }
}

public class CustomNavigationCotnroller: UINavigationController {

    public override var preferredStatusBarStyle: UIStatusBarStyle {
        if let statusBarHandler = visibleViewController as? StatusBarStyleHandler {
            return statusBarHandler.preferredStatusBarStyle
        }

        return .default
    }
}

그런 다음 사용법

public class SomeController: UIViewController, StatusBarStyleHandler {

    private var statusBarToggle = true

    // just a sample for toggling the status bar style each time method is called
    private func toggleStatusBarColor() {
        statusBarToggle = !statusBarToggle
        setNeedsStatusBarAppearanceUpdate()
    }

    public override var preferredStatusBarStyle: UIStatusBarStyle {
        return statusBarToggle ? .lightContent : .default
    }
}

이 게시물이 문제를 해결하는 이유와 방법을 설명 할 수 있다면 훨씬 개선 될 것입니다.

UINavigationController를 서브 클래 싱하는 대신 UINavigationController에 대한 확장을 생성하고 서브 클래 싱 할 필요없이 동일한 결과를 얻을 수도 있습니다.
wilforeal

4

1) 전체 프로젝트에 대한 하나의 설정 :

가능한 경우 UIViewControllerBasedStatusBarAppearanceinfo.plist에서 키-값 쌍을 NO제거 하거나 제거하지 않고 설정 합니다. info.plist에서 사용할 수없는 경우 아무 작업도하지 마십시오. 기본값은 NO이 속성입니다.

AppDelegate.m에 아래 코드를 추가하십시오.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
}

2) 다른 View Controller에 대한 다른 설정 :

UIViewControllerBasedStatusBarAppearanceinfo.plist에 키-값 쌍을 추가 하고로 설정합니다 YES.

View Controller가 Navigation Controller에 포함되지 않은 경우. MyViewController를 가정 해 보겠습니다. MyViewController.m 파일에 아래 코드를 추가하기 만하면됩니다. View Controller가 Navigation Controller에 포함 된 경우 새 Cocoa Touch 클래스를 만들고 UINavigationController의 하위 클래스로 만듭니다. MyNC라고합시다. 스토리 보드의 오른쪽 창에서 탐색 컨트롤러보기를 선택합니다. Utilities-> Identity Inspector-> Custom Class-> Class, "MyNC"를 입력합니다. Storyboard View를 "MyNC"Cocoa Touch Class와 연결 한 후 MyNC.m에 아래 코드를 추가합니다.

- (BOOL)prefersStatusBarHidden {
    return NO;
}

-(UIStatusBarStyle)preferredStatusBarStyle {
    return UIStatusBarStyleLightContent;
}

iOS9에서 보이는 UIViewControllerBasedStatusBarAppearance는 기본적으로 YES 값을 포함합니다. .plist에 수동으로 추가하고 제대로 작동하려면 NO로 설정해야했기 때문입니다.
Mohd Asim 2011

4

여기에 모든 답변이 있어도 정확한 해결책을 찾지 못했지만 Daniel의 답변으로 시작했습니다. 내가 결국 얻은 것은 :

override var preferredStatusBarStyle: UIStatusBarStyle {
     return visibleViewController?.preferredStatusBarStyle ?? .lightContent
}

내비게이션 컨트롤러에서 (탭과 유사하며 selectedViewController 만). 그리고 다음을 존중합니다.

override var preferredStatusBarStyle: UIStatusBarStyle {
     return .lightContent
}

달리 설정하지 않는 한 각 뷰 컨트롤러에서. setNeedsStatusBarAppearanceUpdate()아무데도 전화 할 필요가 없으며 각 뷰 컨트롤러에 도착하면 업데이트됩니다.


2
몇 시간 동안 고생 한 후 거의 동일한 솔루션을 얻었습니다.
Scott Jungwirth

어느 시점에서 이것은 수정 된 것처럼 보입니다. 각 VC에서 preferredStatusBarStyle을 사용하면 이제 잘 작동합니다.
Andrew Plummer

4

iOS 13 솔루션

가장 많이 득표 한 답변은 "레거시"코드를 사용합니다 👎

barStyle속성 설정 은 이제 (iOS 13 이상) "레거시 사용자 지정"으로 간주됩니다. 애플에 따르면 ,

iOS 13 이상에서는 standardAppearance, compactAppearance 및 scrollEdgeAppearance 속성을 사용하여 탐색 모음을 사용자 지정합니다. 이러한 레거시 접근자를 계속 사용하여 탐색 모음의 모양을 직접 사용자 지정할 수 있지만 다른 모음 구성에 대한 모양을 직접 업데이트해야합니다.

당신의 시도에 관하여-당신은 올바른 길을 가고있었습니다!

UINavigationControllerUIViewController(🙃를 아는) 의 하위 클래스입니다 !

따라서 내비게이션 컨트롤러에 내장 된 뷰 컨트롤러를 제시 할 때 실제로 내장 된 뷰 컨트롤러를 제시하는 것은 아닙니다. 내비게이션 컨트롤러를 소개합니다! 은의 UINavigationController하위 클래스로 UIViewController및을 상속 preferredStatusBarStyle하며 childForStatusBarStyle원하는대로 설정할 수 있습니다.

다음 방법 중 하나가 작동합니다.

  1. preferredStatusBarStyle내 재정의UINavigationController

    • preferredStatusBarStyle( doc )-뷰 컨트롤러의 선호하는 상태 표시 줄 스타일
    • 하위 클래스 또는 확장 UINavigationController

      class MyNavigationController: UINavigationController {
          override var preferredStatusBarStyle: UIStatusBarStyle {
              .lightContent
          }
      }

      또는

      extension UINavigationController {
          open override var preferredStatusBarStyle: UIStatusBarStyle {
              .lightContent
          }
      }
  2. childForStatusBarStyle내 재정의UINavigationController

    • childForStatusBarStyle( doc )-시스템이 상태 표시 줄 스타일을 결정하는 데 사용할 뷰 컨트롤러가 필요할 때 호출됩니다.
    • Apple의 문서에 따르면

      "컨테이너보기 컨트롤러가 자식보기 컨트롤러 중 하나에서 상태 표시 줄 스타일을 파생하는 경우 [이 속성을 재정의]하고 해당 자식보기 컨트롤러를 반환합니다. nil을 반환하거나이 메서드를 재정의하지 않으면 self에 대한 상태 표시 줄 스타일이 사용됩니다. 이 메서드의 반환 값이 변경되면 setNeedsStatusBarAppearanceUpdate () 메서드를 호출합니다. "

    • 즉, 여기서 솔루션 3을 구현하지 않으면 시스템이 위의 솔루션 2로 대체됩니다.
    • 하위 클래스 또는 확장 UINavigationController

      class MyNavigationController: UINavigationController {
          override var childForStatusBarStyle: UIViewController? {
              topViewController
          }
      }

      또는

      extension UINavigationController {    
          open override var childForStatusBarStyle: UIViewController? {
              topViewController
          }
      }
    • 위에서 원하는 뷰 컨트롤러를 반환 할 수 있습니다. 다음 중 하나를 권장합니다.

      • topViewController(of UINavigationController) ( doc )-탐색 스택 맨 위에있는 뷰 컨트롤러
      • visibleViewController(of UINavigationController) ( doc )-탐색 인터페이스에서 현재 보이는보기와 관련된보기 컨트롤러 (힌트 : 여기에는 "탐색 컨트롤러 자체 위에 모달로 표시된보기 컨트롤러"가 포함될 수 있음)

참고 : 하위 클래스로 결정한 경우 UINavigationControllerIB의 ID 검사기를 통해 해당 클래스를 탐색 컨트롤러에 적용해야합니다.

PS 내 코드는 Swift 5.1 구문을 사용합니다 😎


1
매우 완전한 답변, 감사합니다! 또한 한동안 고생 한 부분은 iOS 13에서 .default스타일이 다크 모드를 고려하고 문서화되어 있지 않으므로 이전 iOS 버전도 지원하는 if #available(iOS 13, *) { return .darkContent } else { return .default }경우 상태 표시 줄 스타일을 수동으로 설정하려는 경우 추가 할 수 있습니다 . 상태 표시 줄 뒤의 색상은 "밝음"입니다.
valcanaia

1
재정의 var를 수행하는 확장 방법은 Xcode 11.4 / iOS 13.4에서 더 이상 작동하지 않습니다
Marc Etcheverry

Swift에서 객관적인 C 클래스를 확장하는 것은 Objective C 카테고리를 통해 구현되기 때문입니다. Objective C 범주를 통해 메서드를 재정의하는 것은 권장되지 않으며 중단 될 가능성이 있습니다. 참조 stackoverflow.com/a/38274660/2438634
마크 Etcheverry

UINavigationController를 재정의하는 것이 확실히 작동하지만 Apple 측에서는 기본적으로 topViewController를 반환하는 childForStatusBarStyle을 수행하지 않는 버그처럼 보입니다. 예를 들어 UITabBarController는 탭에 대해이 작업을 수행합니다. 나에게는 UINavigationController가 자체 UI를 제공하는 대신 "실제"뷰 컨트롤러를 호스팅하기위한 엄격한 컨테이너 컨트롤러 인 UINavigationController가 이러한 상태 표시 줄 스타일을 "먹어야"할 이유가 없습니다. Apple을위한 레이더를 생성합니다.
Igor Vasilev

1

splashScreen 중에 statusBar를 숨기고 싶지만 스타일을 라이트 콘텐츠로 변경하려는 경우 (스플래시에서 statusBar를 숨기려면 Plist의 StatusBarInitiallyHidden이 NO 여야 함)이를 appDelegate의 didFinishLaunchingWithOptions 메서드에 추가하여 lightContent로 변경할 수 있습니다.

[[UIApplication sharedApplication]setStatusBarHidden:NO withAnimation:UIStatusBarAnimationSlide];
[[UIApplication sharedApplication]setStatusBarStyle:UIStatusBarStyleLightContent];

1

신속한 예

AppDelegate.swift에서

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool {
    UIApplication.sharedApplication().statusBarStyle = UIStatusBarStyle.LightContent;

    return true
}

info.plist set보기 컨트롤러 기반 상태 표시 줄 모양 : 아니요


1

을 사용하는 경우 하위 뷰 컨트롤러를 참조하도록 NavigationController하위 클래스를 지정할 수 있습니다.NavigationController

// MyCustomNavigationController

- (NSUInteger)supportedInterfaceOrientations {
    UIViewController *viewControllerToAsk = [self findChildVC];
    return [viewControllerToAsk supportedInterfaceOrientations];
}

- (BOOL)shouldAutorotate {
    UIViewController *viewControllerToAsk = [self findChildVC];
    return [viewControllerToAsk shouldAutorotate];
}

- (UIStatusBarStyle)preferredStatusBarStyle {
    UIViewController *viewControllerToAsk = [self findChildVC];
    return [viewControllerToAsk preferredStatusBarStyle];
}

- (UIViewController *)findChildVC {
    return self.viewControllers.firstObject;
}

1

스위프트 4.2

extension UITabBarController {
    open override var childForStatusBarStyle: UIViewController? {
        return selectedViewController
    }
}

extension UINavigationController {
    open override var childForStatusBarStyle: UIViewController? {
        return visibleViewController
    }
}

재정의 var를 수행하는 확장 방법은 Xcode 11.4 / iOS 13.4에서 더 이상 작동하지 않습니다
Marc Etcheverry

@MarcEtcheverry 그래서 왜 대답에 반대 투표를 했습니까? 이상해 보인다.
Vyacheslav

Swift에서 객관적인 C 클래스를 확장하는 것은 Objective C 카테고리를 통해 구현되기 때문입니다. Objective C 범주를 통해 메서드를 재정의하는 것은 권장되지 않으며 중단 될 가능성이 있습니다. stackoverflow.com/a/38274660/2438634
Marc Etcheverry

@MarcEtcheverry '권장하지 않음'! = '절대 사용하지 마십시오!'. jul2018의 경우 대답이 정확했습니다. 이 답변조차도 최신이 아닙니다. 이것은 투표 할 이유가 아닙니다. 나는 미래를 볼 수 없습니다
Vyacheslav

0

상태 표시 줄 스타일을 설정할 수 있습니다. IOS 6 이하와 같은 상태 표시 줄과 비슷합니다.
뷰 컨트롤러에이 메서드를 붙여 넣습니다.

-(UIStatusBarStyle)preferredStatusBarStyle{
    return UIStatusBarStyleBlackOpaque;
}

뷰에서이 메서드를 호출하면 다음과 같이로드됩니다.

if([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0f)
    {
       [self setNeedsStatusBarAppearanceUpdate];
    }

[self setStatusBarNeedsUpdate]두 번째 블록에서 의미 합니까? (또는 적어도 다른 것).
mxcl 2013-10-14

0

내가 직면 한 특정 케이스에 대한 메모를 추가하고 싶습니다. 내 앱에는 항상 내 앱 전체에 떠 다니는 채팅 얼굴을 표시하는 또 다른 UIWindow가 있습니다. 이렇게하면 위의 솔루션이 작동하지 않았으며 그 이유가 확실하지 않습니다! 내가 알아 차린 것은 새로운 UIWindow의 ViewController가 그 이유 였다는 것입니다! 상태 표시 줄 스타일을 변경하려면 새 UIWindow의 해당 뷰 컨트롤러에서 변경해야합니다.

이 메모는 유사한 구조를 가진 다른 사람들에게 도움이 될 수 있습니다! 따라서 기본적으로 새 UIWindow의 ViewController에서 위에서 언급 한 솔루션을 적용 할 수 있습니다.

다시 이것은 특정한 경우입니다.

감사


-1

신속한 3의 경우 UIViewController에서 :

override var preferredStatusBarStyle : UIStatusBarStyle { return UIStatusBarStyle.lightContent }
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.