iOS) 노치에 따른 커스텀 상태바 만들기

1 minute read

커스텀 네비게이션바의 색과 상태바의 색 맞추기

  • 커스텀 네비게이션을 만들게되면서 상태바와 색을 맞춰야하는 일이 생겼다. 노치에 따라 상태바에 UIView 를 얹어서 색으로 맞추는 원리로 만들었다.

iPoneSE 2세대

iOS 13.0 노치가 생긴 이후

Code

Extension 으로 UIViewController 에 함수를 추가.

extension UIViewController {
    func setupStatusBar(_ color: UIColor) {
    
        // 1.
        if #available(iOS 13.0, *) {
        
        // 2.
            let margin = view.layoutMarginsGuide
            let statusbarView = UIView()
            statusbarView.backgroundColor = color
            statusbarView.frame = CGRect.zero
            view.addSubview(statusbarView)
            statusbarView.translatesAutoresizingMaskIntoConstraints = false
            
            //3
            NSLayoutConstraint.activate([
                statusbarView.topAnchor.constraint(equalTo: view.topAnchor),
                statusbarView.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 1.0),
                statusbarView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
                
                // 4.
                statusbarView.bottomAnchor.constraint(equalTo: margin.topAnchor)
            ])
            
       // 5.     
        } else {
            let statusBar = UIApplication.shared.value(forKeyPath: "statusBarWindow.statusBar") as? UIView
            statusBar?.backgroundColor = color
        }
    }
}
  • 1 : 노치가 있는 상태바를 지원하는 iOS 13.0 에 맞춰서 지원하도록 함.
  • 2 : layoutMarginsGuide 는 여백을 나타내는 UILayoutGuide object 를 제공한다. guide 의 anchor 속성을 사용해서 constraints 를 설정할 수 있다.

Apple Developer Documentation - layoutMarginsGuide

  • 3 : 애플 공식문서를 참조하면 NSLayoutAnchor 는 추가적인 type safety 를 제공한다고 한다. 잘못된 제약조건이 우연히 발생하는 것을 예방한다. (NSLayoutConstraint.Attribute 하위 클래스는 type checking 을 제공한다.) 예를들어 leadingAnchor 를 설정해주고 싶다면 파라미터에서도 leadingAnchor 에 맞춰야하는 것이다.

Apple Developer Documentation - NSLayoutAnchor

  • 4 : 우리는 상태바의 높이에 따라서 커스텀 상태바를 맞춰야한다. 그래서 safe area 의 영역을 가져와야 했고 safeAreaLayoutGuide 를 포함하는 layoutMarginsGuide 의 topAnchor 을 통해 constraints 를 설정했다.

  • 참고) view 의 leadingAnchor 를 다른 view 의 leftAnchor 로 constrain 한다면 두 속성 다 NSLayourXAxisAnchor 니까 compile 이 되긴한다. 하지만 Auto Layout 은 leading 과 trailing 속성을 left, right 속성과 함께 쓰는 것을 허락하지 않느다. 결과적으로 runtime 에서 crash 된다.

// 아래와 같이 사용하면 런타임 에러 발생
navigationBar.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor),

  • 5 : iOS 13 으로 변경됨에 따라 KVC 를 통한 접근을 금지하고 있다. 키를 가지고 접근하는 방법으로 작성하는 코드들은 iOS 13 에서 에러가 나타났다고 한다.
//searchbar 에서 textfield 를 접근하는 방법
searchBar.value(forKey: "_searchField") as? UITextField { ... }

//iOS 13 이후
let searchField = searchController.searchBar.searchTextField

하지만 iOS 13 이전에 대해서만 KVO 로써 접근하고 있는 코드이기 때문에 가능하다.

Categories:

Updated: