[WWDC-2021] Your guide to keyboard layout

2021. 12. 8. 22:09iOS/WWDC

이 글은 WWDC 2021 영상을 정리하여 작성한 글입니다.

원본 영상은 링크를 참고하여 주세요.

Your guide to keyboard layout

Managing the keyboard

오늘은 키보드 레이아웃과 관련해서 과거에 프레임 기반으로 부터 바뀐 새로운 레이아웃 가이드에 대해 소개하는 영상을 정리해 보겠습니다.

만약 앱에서 키보드를 사용한다면, 키보드를 처리하는 방식은 notifications를 등록하고 적절한 위치와 애니메이션을 도출한 다음 계산을 수행하여 레이아웃을 조정하는 것 이였 습니다.

다음은 기존에 키보드를 처리하는 방식입니다.

...
    keyboardGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
    keyboardGuide.topAnchor.constraint(equalTo: textView.bottomAnchor).isActive = true
    keyboardHeight = keyboardGuide.heightAnchor.constraint(equalToConstant: view.safeAreaInsets.bottom)

    NotificationCenter.default.addObserver(self, selector: #selector(respondToKeyboard), 
                                                     name: UIResponder.keyboardWillShowNotification, 
                                                   object: nil)
}

@objc func respondToKeyboard(notification: Notification) {
    let info = notification.userInfo
    if let endRect = info?[UIResponder.keyboardFrameEndUserInfoKey] as? CGRect {
        var offset = view.bounds.size.height - endRect.origin.y
        if offset == 0.0 {
            offset = view.safeAreaInsets.bottom
        }
        let duration = info?[UIResponder.keyboardAnimationDurationUserInfoKey] as? TimeInterval ?? 2.0
        UIView.animate(withDuration: duration, animations: {
            self.keyboardHeight.constant = offset
            self.view.layoutIfNeeded()
        })
    }
}

그러나, 이제부터는 새롭게 추가된 UIKeyboarLayoutGuide에 대해 소개해 드리도록 하겠습니다.

UIKeyboarLayoutGuide는 iOS 15에 새롭게 추가되었습니다. 말그대로 layout guide 입니다. 스토리보드에서 많이 볼 수 있었던 SafeAreaLayoutGuide와 비슷한 역할이라고 보시면 되는데, 이 layout guide를 설명하자면, 뷰를 사용하지 않고 레이아웃에서 공간을 나타내는 방법이라고 설명할 수 있을 겁니다. 그리고 뷰 처럼 anchor들을 가지고 있습니다.

이와같은 layout guide에 UIKeyboarLayoutGuide가 추가되었습니다. 이름 그대로 앱에서 키보드가 차지하는 공간을 나타냅니다. 자 이제 이러한 가이드가 생겼으니 위의 코드에서는 어떠한 작업이 필요가 없어졌을까요?

keyboardGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
keyboardGuide.topAnchor.constraint(equalTo: textView.bottomAnchor).isActive = true
keyboardHeight = keyboardGuide.heightAnchor.constraint(equalToConstant: view.safeAreaInsets.bottom)

우선 guide 가 자체적으로 생겨져 있으니 keyboardGuide와 관련된 오토레이아웃은 필요가 없습니다.

NotificationCenter.default.addObserver(self, selector: #selector(respondToKeyboard), name: UIResponder.keyboardWillShowNotification, object: nil)

그리고 NotificationCenter를 등록하는 일 또한 필요가 없어지고, 이에대한 repond 함수 또한 필요가 없어졌습니다.

자 이제 어떠한 작업이 필요할까요 ?! 단 한줄이면 됩니다.

view.keyboardLayoutGuide.topAnchor.constraint(equalToSystemSpacingBelow: textView.bottomAnchor, multiplier: 1.0).isActive = true

이 keyboardLayoutGuide 프로퍼티는 UIView에 있는 속성입니다. 대부분의 경우에 이 topAnchor를 사용하도록 업데이트하기만 하면 됩니다. 이 가이드는 키보드 키보드가 올라오고 내려오는 애니메이션과도 매치됩니다. 그리고 변화하는 높이도 따릅니다. 때때로 키보드의 높이는 변화하는데, 이에 대해 어떠한 사이즈에도 매치가 되도록 합니다. 그리고 키보드의 도킹이 해제될 때 가이드는 화면 아래쪽으로 내려오게 되고 상단 앵커에 묶인 항목들은 모두 내려옵니다.

이는 safe-area 영역또한 차지하고 있습니다.

애플에서는 왜 이러한 새로운 레이아웃 가이드를 선택하였을 까요? 영상의 개발자는 키보드를 많은 용도로 사용하길 바라기 때문이고, 이러한 확장된 키보드를 앱에 통합하도록 하는 것이 다음 단계라고 이야기 합니다. 키보드 레이아웃은 몇몇 문제들이 많았고 이를 피해야 한다는 이야기를 종종 들었다고 합니다. 따라서 이러한 레이아웃 가이드를 새롭게 만든 동기 중 하나는 개발자에게 사용자가 텍스트를 입력할 수 있는 다양한 방법에 대해 대응할 수 있도록 기능을 제공하고, 키보드를 레이아웃의 일부로써 생각할 수 있도록 하기 위함이였다고 합니다.

따라서 이러한 UIKeyboarLayoutGuide를 사용한다면 원하는 경우 새로운 속성을 통해 도킹에서 해제된 키보드를 모든 형태로 따라할 수 있도록 합니다. 

.followsUndockedKeyboard 

이 값은 기본적으로는 false이지만, 이 값을 true로 설정한다면, 키보드가 도킹해제 되어있거나 떠 있는 경우, 가이드는 키보드를 따르게 되므로, 키보드가 어디에 있든 레이아웃이 반응하도록 제어할 수 있게 됩니다. 더이상 자동으로 아래로 내려갈 필요가 없습니다. 도킹을 해제할 때 키보드 숨김 notification을 수신할 필요가 없습니다. 레이아웃 가이드는 키보드가 있는 위치입니다. 따라서 개발자는 레이아웃이 다른 종류의 키보드에 어떻게 반응하는지 훨씬 더 의식해야 한다는 것을 의미합니다. 

따라서 UIKeyboarLayoutGuide는 새로운 클래스의 하위 클래스입니다. 바로 UITrackingLayoutGuide 입니다.

이곳에서는 특정 edge 근처에서 활성화되고, 종료될 때 비활성화 되는 제약조건과, 또는 특정 엣지로부터 멀어질 때 활성화 되고 엣지 근처에서 비활성화되는 배열을 지정할 수 있습니다. 이해가 잘 안된다면 예시를 보도록 하겠습니다.

다음과 같은 앱이 있습니다. 그리고 키보드를 도킹에서 해제 시킬때 아래와 같이 키보드를 따라다니는 뷰를 만들 수 있습니다.

그리고 키보드가 상단에 가까워 졌을 때 키보드를 따라다니던 뷰는 아래로 이동을 하게 되고

키보드가 옆으로 붙었을 때 입력한 내용들은 키보드가 없는 쪽으로 이동하도록 할 수 있습니다.

이제 코드를 살펴보도록 합시다. 아래 슬라이드에서 editView는 텍스트 필드와 컨트롤들이 있는 뷰 이고, imageView는 이미지 뷰 입니다.

먼저 수직축으로 이동할 때 일어나는 일부터 보도록 합시다.

처음으로 editView의 하단을 키보드 레이아웃 가이드의 상단과 연결하는 배열을 선언합니다. 그런 다음 가이드가 위에서 떨어져 있을 때만 활성화되도록 설정하여 가이드가 top에 가까이 있을 때 비활성화 하도록 합니다. 그런 다음 키보드가 상단에 가까워 질 때 사용할 별도의 제약조건 배열을 정의하고, safe-area의 하단 부분과 오토레이아웃을 적용시킵니다.

자 이제 수평적인 움직임에 대해 보도록 합시다.

키보드가 leading과 trailing 모두에 떨어져 있을 때 editView가 키보드 중앙에 오도록 하고, imageView 또한 중앙에 배치합니다. 그러기 때문에 위의 제약조건 배열을 정의하고, 이를 leading과 trailing 모두에게 멀어질 때 활성화되도록 설정하였습니다.

그런 다음 editView가 trailing 엣지에 있을 경우 trailing으로, leading 엣지에 있을 경우 leading으로 이동하도록 해아하고,

imageView 또한 키보드가 있는 위치와 반대쪽 가장자리에 위치하도록 해야합니다.

그런 다음 키보드의 위치에 따라 제약조건을 활성화되고, 비활성화 되도록 하면 끝입니다.

자 이제, 이러한 키보드의 위치에 대해 한번 자세히 살펴보겠습니다.

키보드가 도킹 된 경우에는 bottom은 near, 그리고 다른 엣지들과는 awayFrom 상태 입니다.

그리고 도킹 해제와 분할한 키보드는 모든 엣지에서 awayFrom 상태일 수도 있고 상단과 near 인 상태가 될 수 있으며 두개의 인접한 엣지와 near인 상태가 될 수 있습니다. 이러한 모든 것들은 followsUndockedKeyboard 설정이 true일 때만 가능합니다. 

또한 아주 흔하진 않지만, 분할 되고 도킹 해제된 키보드는 top과 가까워질 때까지, 모든 엣지들과 awayFrom 상태 입니다.

다음으로 올해 새롭게 생긴 카메라를 이용하여 문자를 보낼 수 있는 새로운 방법이 있습니다.

이는 일반적인 키보드와 동일하지만, 화면을 가득 채우는 키보드 중 하나입니다. 이에 대한 자세한 세션은 WWDC 2021 영상은 "Use the camera for keyboard input in your app." 세션을 확인하시면 됩니다. 

다음으로는 하드웨어 키보드가 부착되어 있는 경우는 어떨까요? 올해부터는 더이상 가득차있지 않고 적응형으로 단축기를 표시하는 bar를 갖게 되었습니다. 사용중인 언어와 단추 수에 따라 너비는 변경됩니다.

따라서 이것은 항상 bottom의 near 상태이고 나머지 엣지들로부터 떨어져 있습니다. 하지만, 이 bar는 접을 수 가 있기 때문에 leading과 trailing 엣지로 부터 near 할 수 있습니다.

하지만, 자신의 앱이 화면상의 유일한 앱이 아니고, 도킹되지 않은 키보드를 따르고 있다면 어떻게 해야 할까요?

먼저 고려할 점은 키보드가 앱의 공간을 떠날 수 있다는 것을 기억해야 합니다. 만약 그렇다면 키보드는 dismiss 된 것처럼 취급 됩니다. 그리고 앱이 가장 좁은 형태일 때는 top과 bottom의 엣지가 유효 하지만, 키보드가 앱 위에 있는지 여부와 관계 없이 leading과 trailing은 awayFrom 상태가 됩니다.

만약 멀티 윈도우 상태일 때 당신의 앱이 넓은 상태라면, 모든 가장자리에서 awayFrom 상태가 될 수 있습니다. 

하지만 앱의 절반의 화면만을 사용하고 있는경우 키보드가 범위를 벗어날 수 있으며 키보드는 leading과 near 상태이고 가이드 영역은 앱 위에 있는 키보드 부분에만 맞도록 크기가 조정됩니다

만약 좁은 상태라면, 도킹된 상태의 키보드가 마찬가지로 양 옆의 엣지들과는 awayFrom 상태로 고정되지만, top 과 bottom 엣지에는 near 상태일 수 있습니다.

그리고 가이드 영역 또한, 앱에서 차지하는 부분만으로 크기가 조정됩니다. 그리고 키보드를 도킹 한다면, leading, trailing, top과도 awayFrom 상태가 되고, 가이드 영역의 크기가 앱의 크기에 맞게 다시 조정됩니다.

slide-over 상태인 앱도 이와 동일합니다.

자 여기까지 세션의 영상이였습니다. 영상을 찾던 중 키보드 레이아웃에 관한 소재가 아주 흥미로워 보여서 정리해 보았습니다. 키보드에 대한 이벤트 처리를 할 때 유용할 것 같네요. iOS 15 타겟 앱을 개발하는 날을 기약하며 .. 이만 줄이겠습니다.

감사합니다 !