티스토리 뷰

반응형


안녕하세요 :) Zedd입니다.

설날 잘 보내셨나요? 새해 복 많이 받으세요 XD


오늘은..StatusBar에 대해 공부를 더 해볼건데요, 읽기전에 UIStatusBar글을 반드시 읽고오시길 바랍니다. 

그때..저 UIStatusBar공부하면서도



얘네가 있었습니다. ㅎ근데 그냥 지나쳤음

근데 이제...알아야 할 때가 왔다..


childForStatusBarStyle


자.. childForStatusBarStyle은 UIViewController의 인스턴스 프로퍼티네요.

뭔가 child / for / statusBar / style,,이,,,느낌,,


정의는 "시스템이 status bar style을 결정하는데 사용 할 viewController가 필요할 때 호출됩니다" 라고 하네요. 

ㅇㅇ그냥 ㅇ ㅑ!!!!!!!!!!!!!!!!!!나 status bar style 얘꺼 쓸랭ㅎ 하는 것이;ㅁ


리턴값은 

UIViewController...

ㅇㅇ리턴되는 UIViewController의 status bar style을 사용하게따 이거죠.


ContainerViewController가 child View Controller 중 하나에서 status bar style을 가져오고 싶은 경우, 이 프로퍼티를 구현하고, 해당 child View Controller를 이턴하세요. nil을 리턴하거나, override하지 않으면 self에 대한 status bar style이 사용됩니다. 이 프로퍼의 리턴값이 변경되면 setNeedsStatusBarAppearanceUpdate()를 호출하세요.




childForStatusBarHidden


시스템이 status bar hidden/unhidden state를 결정하는데 사용 할 viewController가 필요할 때, 호출됩니다. 

역시나 UIViewController를 리턴하구요. 기본값은 nil입니다. 

discussion도 childForStatusBarStyle과 똑같습니당. 



아직 잘 이해가 안갈텐데요, 코드로 한번 봅시다.

저는 처음에, childForStatusBarStyle이랑 childForStatusBarHidden얘네를 preferredStatusBarStyle, prefersStatusBarHidden처럼 그냥 ViewController안에 선언하면 알아서 동작 할 줄 알았어요.

근데....



override var childForStatusBarStyle: UIViewController? {

        let viewController = SecondViewController()

        return viewController

 }


그래서 이렇게 해줬는데, 안 불 림

아예 이쪽으로 들어오지도 않더라구요?


그래서 찾아봤더니 childForStatusBarStyle은 대부분


class ZeddNavigationController: UINavigationController {


    override var childForStatusBarStyle: UIViewController? {

        return self.topViewController

    }

}


이렇게 어떤 Controller를 새로 만들거나, extension할 때 저렇게 사용 하더라구요.

위처럼 NavigationController가 될 수도 있고, TabBarController...등등

암튼 저런식으로 하면 무슨 뜻이겠음.

Navigation stack에 top에 있는 controller의 status bar style을 사용하겠다~~라는 뜻이죠.


아 그래서 hidden도 마찬가지겠그ㅜ나..했는데



override var childForStatusBarHidden: UIViewController? {

        let viewController = SecondViewController()

        return viewController

    }



childForStatusBarHidden얘는 불립니다!!! 

둘 중에 하나만 불리니까..뭔가 너무 제가 이상하게 하고있는거 같은데..정말 아무것도 안한상태에서 얘네만 해준건데..

암튼 얘는 불려가지고......




SecondViewController의 prefersStatusBarHidden이 true면 ViewController에서는 status bar가 없어집니다.

왜지????

쓰면서 너무 어이가 없어서..암튼 이유를 알게된다면 댓글점



암튼 얘네를 언제쓰면 좋냐..면

UINavigationController에서 stack이 쌓일 때, 

음..예를들어

ViewController -> SecondViewController라는 상황을 가정해봅시다.

근데 제가 SecondViewController에 preferredStatusBarStyle을 lightContent로 지정했다고 해볼게요.

근데 ViewController에서 SecondViewController로 딱 갔을 때 (push로) statusBar style은 lightContent로 바뀌지 않습니다.

추가로 ViewController내에서 (즉, UINavigationController의 root) preferredStatusBarStyle를 지정해도 절대 호출되지 않습니다. 왜냐? 

왜인지는...여기에.. 

간단하게 요약하면, UINavigationController는 기본 StatusBarStyle호출을 child view controller로 전달하지 않는다고 해요. 


주의 : 지금 예를 SecondViewController로 들어서 rootViewController가 아닌 애들만 적용이 된다..이렇게 생각 할 수 있을 것 같은데, 아닙니다. rootViewContoller에서도 preferredStatusBarStyle을 lightContent로 해도 하얗게 안돼요.

왜냐? NavigationController는 지가 알아서 statusBar를 관리합니다. 아무튼 NavigationStack안에서 preferredStatusBarStyle를 호출해도 preferredStatusBarStyle가 전혀 호출이 안됩니다. 브레이크 포인트 걸어서 보시면 알거에요. 안불립니다. 


ㅇ ㅑ 그러면 내가 ViewController에서 무조건 내가...lightContent로 해줘야하는데..그럼 어떻게 해야하는 부분임?

그럴 때 childForStatusBarStyle를 사용하면 좋..습니다.



extension UINavigationController {

    open override var childForStatusBarStyle: UIViewController? {

        return self.topViewController

    }

}


바로 이렇게 말이죠.

이렇게만 해주면, preferredStatusBarStyle를 override하여 lightContent로 해준 ViewController들 한테는 lightContent가 먹게되고, 안해주거나 default를 리턴해준 ViewController들은 default. 즉 검정색 statusBar를 표시하게 됩니다.


hidden도? 

아닙니다. prefersStatusBarHidden이넘은 그냥 ViewController자체에 override해도 preferredStatusBarStyle과는 다르게 잘 동작하게 됩니다. 

왜이러지?? ㅇㄴ


암튼 뭐 그렇다는거?

글 쓰면서 이것저것 해봤는데 참 작동을.....zzz

제가 실험한거는 


class ZeddNavigationController: UINavigationController {

    override var childForStatusBarStyle: UIViewController? {

        return self.topViewController

    }

}


자 뭐 extension한거랑 똑같긴한데, 뭐 암튼 지금 이런상태라고 칩시다.

그럼 머다?? topViewController의 status bar style을 가져온다~



class ViewController: UIViewController {

    override var childForStatusBarStyle: UIViewController? {

        let viewController = SecondViewController()

        return viewController

    }

}



ViewController는 ZeddNavigationController의 root임.

암튼 이렇게 해주면, 원래 childForStatusBarStyle은 안불리는데, 저 topViewController로 설정을 해주게 되면 비로소 불리게 됩니다. 

그래서 SecondViewController의 status bar style이 lightContent면..ViewController의 status bar style도 lightContent가 됩니다!!!!


엥..?그게 왜ㅎ 맞자나ㅎ;;

라고 생각하실 수도 있는데..


자. 지금 ViewController에는 preferredStatusBarStyle을 override안해놓은 상황입니다.

그럼 기본값인 default. 즉 검정색 statusBar겠죠.

저는 childForStatusBarStyle이 해당 ViewController의 preferredStatusBarStyle을 가져와서 그걸로 해준다~ 라고 이해하고 있었는데, 지금 preferredStatusBarStyle가 아닌 childForStatusBarStyle을 본게 신기했어요. 

그리고zzz 



class ViewController: UIViewController {

    override var preferredStatusBarStyle: UIStatusBarStyle {

        return .lightContent

    }

}



childForStatusBarStyle이거 다 지우고 preferredStatusBarStyle를 한다? 그러면 또 이게 불립니다. 


그렇다면....이걸 안해볼 수 없죠. 



class ViewController: UIViewController {

    

    override var childForStatusBarStyle: UIViewController? {

        let viewController = SecondViewController()

        return viewController

    }


override var preferredStatusBarStyle: UIStatusBarStyle {

        return .default

    }

    

}


이렇게 2개를 해놨을 때, 어떤것이...불릴 것인가.

SecondViewController에서 preferredStatusBarStyle는 lightContent로 해놓은 상태입니다.


이런상태에서는 오직 childForStatusBarStyle만 불립니다.

그래서 ViewController의 status Bar style은 lightContent가 된다는 사실..


그러니까 한마디로 childForStatusBarStyle이 있으면 preferredStatusBarStyle는 아예 안불리게 됩니다. 하지만 childForStatusBarStyle이 없으면 preferredStatusBarStyle가 불리게됨...

혹시나 해서 lifeCycle메소드에 setNeedsStatusBarAppearanceUpdate()다 넣어줘봤는데 여전히..똑같습니다.


이 실험은..뭐 참고용이고요. 저 혼자 신나서 떠든 느낌이 굉장히 강한데, 이해가 되었길 바랍니다.

원래 이거 쓰기 시작한지는 꽤 됐는데, 이제서야 마무리를 짓네요.

ㅎ ㅏ 주말동안 공부하고싶은게 정말 많았는데 몸이 아파서 또 이렇게 주말이 날라가네요 

개빡친다





반응형