iOS 15의 키보드 회피 [UIKit]

🗓이 글은 Classi developers Advent Calendar 2021의 네 번째 날이다🗓

이마


아이폰 앱을 개발하는 과정에서 여러 차례 이뤄진 입력 형태다.
이 입력 형식에서 반드시 요구에 도달해야 하는 것은 키보드가 표시될 때 입력 형식을 숨기지 않는다는 것이다.
지금까지 이 목표를 실현하기 위해 많은 iOS 엔지니어들이 ScrollViewTextField를 배치하고 NotificationCenter로 키보드 디스플레이 사건을 포착하며 모든 수단을 다 썼다.
드디어 iOS 15UIKeyboardLayoutGuide에서 준비된 것으로, 이전 AutoLayout의 요령으로 실현 가능🎉
이번에는 그쪽의 방법을 소개하고 싶습니다.

이 기사가 할 수 있는 일



이른바 UIKeyboardLayoutGuide


응용 프로그램 레이아웃에서 키보드가 차지하는 공간의 레이아웃 안내서
A layout guide that represents the space the keyboard occupies in your app’s layout.
인용자 문서
어쨌든 키보드 사각형에 맞춘 레이아웃 매뉴얼이죠!
예를 들어 view.keyboardLayoutGuide.topAnchor 키보드는 화면에 표시될 때 사각형의 상단 가장자리이고 표시되지 않을 때는 SafeArea의 Bottom과 같다.

빨리 해봐.


먼저 코드를 사용하여 화면 아래쪽에 TextField를 구성합니다.
import UIKit

class ViewController: UIViewController {
    private lazy var field: UITextField = {
        let field = UITextField()
        field.translatesAutoresizingMaskIntoConstraints = false
        field.borderStyle = .roundedRect
        field.placeholder = "Input here"
        return field
    }()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setUpUI()
    }
    
    private func setUpUI() {
        view.backgroundColor = .systemBackground
        view.addSubview(field)
        NSLayoutConstraint.activate([
            field.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            field.widthAnchor.constraint(equalToConstant: 200),
            field.heightAnchor.constraint(equalToConstant: 40)
        ])
    }
}
부터 너비 200, 높이 40의 Text Field가 화면 아래쪽에 설정됩니다.

하지만 표만 이렇게 클릭하면 키보드에 숨겨져 있다.
따라서 NSLayoutConstraint.activate의 제한에 다음과 같은 내용을 추가한다.
view.keyboardLayoutGuide.topAnchor.constraint(equalTo: field.bottomAnchor, constant: 10)
그게 어떻게 된 일입니까?
형식이 유행하고 키보드를 따르기 시작한 거 아닐까요!

신중하게 보기 위해 제약의 설정 부분은 다음과 같다.
NSLayoutConstraint.activate([
    field.centerXAnchor.constraint(equalTo: view.centerXAnchor),
    field.widthAnchor.constraint(equalToConstant: 200),
    field.heightAnchor.constraint(equalToConstant: 40),
    view.keyboardLayoutGuide.topAnchor.constraint(equalTo: field.bottomAnchor, constant: 10)
])
마지막으로 추가된
view.keyboardLayoutGuide.topAnchor.constraint(equalTo: field.bottomAnchor, constant: 10)
의 부분은 iOS 15UIView로부터 속성이 있는keyboardLayoutGuideTop에 포맷Bottom으로부터의 제한을 가하여 상술한 동작을 실현할 수 있습니다!
마지막으로 constant: 10 부분은 10개의 공간을 비워 두셔도 상관없습니다.

스토리보드에 설정하면 안 돼요?


해봤는데 지금 상황이 어려울 것 같아...
선택할 수 있는 것은 역시 Superview 또는 SafeArea입니다.

그래도 스토리보드에 UI를 구성하고 싶을 때가 있다고 생각합니다.
이 경우 스토리보드에서 먼저 세이프아레아에 제약을 가해 프로리티를 낮춰 대응할 수 있다.

import UIKit

class ViewController: UIViewController {
    
    @IBOutlet private var field: UITextField!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setUpUI()
    }
    
    private func setUpUI() {
        let keyboardConstraint = view.keyboardLayoutGuide.topAnchor.constraint(equalTo: field.bottomAnchor, constant: 10)
        keyboardConstraint.priority = .defaultHigh
        NSLayoutConstraint.activate([
            keyboardConstraint
        ])
    }
}

표가 여러 개 있을 때?


그래.
차라리 자주 이루어지는 입력 형식은 보통 여러 항목이 있다.
반면 여러 개가 있어 화면 아래쪽에 포즈를 취해 키보드와 겹쳤다.
따라서 아래의 것만 키보드에 덮어씌울 수 있는 입력 형식이 얼마나 많은지 생각해 보자.
이런 그림이네.

UI의 구성은 UIStackView 에서 UITextField 배열이 간단할 뿐입니다.

우선 가장 간단한 대응 방법은 가장 아래의 형식에 대한 제한이다.
import UIKit

class ViewController: UIViewController {
    
    @IBOutlet private var firstNameField: UITextField!
    @IBOutlet private var lastNameField: UITextField!
    @IBOutlet private var addressField: UITextField!
    @IBOutlet private var phoneNumberField: UITextField!
    @IBOutlet private var emailField: UITextField!
    @IBOutlet private var confirmEmailField: UITextField!
    @IBOutlet private var stackView: UIStackView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setUpUI()
    }
    
    private func setUpUI() {
        NSLayoutConstraint.activate([
            view.keyboardLayoutGuide.topAnchor.constraint(greaterThanOrEqualTo: confirmEmailField.bottomAnchor, constant: 10)
        ])
    }
}
이렇게 하면 다음과 같은 동작을 실현할 수 있습니다!

형식에 따라 효과가 있을 것 같아요.👏
그나저나 디버거로 이 행동을 확인한 후 StackView 자체의 사이즈는 변경되지 않고 안에 있는 요소만 움직였다.

이번처럼 형식적인 배열에 그치고 공백 부분도 잘 존재하는 화면이라면 위와 같은 대응에는 문제가 없을 것 같지만, 실제 화면 요소는 대부분이라고 생각한다.
그래서 나도 이런 상황을 생각해 볼게.
예를 들면 이런 화면.

이런 상황에서는 예전처럼 화면을 굴리는 것이 좋다.
구체적인 구성은 UIScrollView에 배치UIStackView하고 그 중에서 배열UILabelUITextField의 사용자 정의 보기가 균등하게 배열된 이미지이다.
이렇게 굴러가는 창에 대해 키보드에 표시된 알림을 받아 키보드 프레임의 y 좌표를 얻어 초점을 맞춘 필드의 좌표와 비교합니다.상당히 번거로운 일을 했지만 앞으로는 다음과 같은 제약을 주면 기분이 좋은 동작을 할 수 있다.
NSLayoutConstraint.activate([
    view.keyboardLayoutGuide.topAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 10)
])
이게 다야.
앞서 설명한 바와 같이 Storyboard 측UIScrollView의 Bottom의 제한은 Prority를 낮추었다
이렇게 되면 동작은 다음과 같다.

미국🎉🎉🎉

후기


어때?
iOS 15 이후에 이걸 사용할 수 있지만 지금까지 설치한 번거로움을 대폭 없앨 수 있을 것 같아요.
다양한 방법으로 결정적인 공을 피하는 멋진 생활을 하세요.
그나저나 이번에는 접촉은 없지만 아이패드는 키보드를 분리해서 조작할 수 있는 기능이 있다.
따라서 KeyboardLayoutGuide를 사용할 때는 시간이 좀 걸린다.
자세한 내용은 여기.를 참조하십시오.
한편 이번에 소개된 샘플 코드는GiitHub에서 공개합니다.이다.
"대단해, 이런 방법이 있었구나!"이런 것들, "번거로움을 줄이고 쓸모가 있어!"이런 느낌을 가진 분들은 꼭 채널(팔로우)에 접속해서 높은 평가(스타)를 부탁드립니다!
그럼 내일 Classi developers Advent Calendar 2021노역선생님.✨
기대해주세요!!

좋은 웹페이지 즐겨찾기