TextEditor, 이것도 안된다고? (2/3) - TextEditor와 글자의 높이

Taeyoung Won·2023년 4월 7일
0

SwiftUI

목록 보기
4/7
post-thumbnail

이전 글에 이어서 TextEditor의 특징과 문제점을 알아보자.

TextEditor

SwiftUI의 TextEditor

TextEditor도 TextField와 마찬가지로 SwiftUI에서 제공하는 입력 인터페이스다.

한 줄의 짧은 텍스트 입력에 특화된 TextField와는 달리, TextEditor는 기본적으로 여러 줄의 긴 텍스트를 작성할 때 주로 사용한다는 차이점이 있다.



TextEditor의 사용

	@State private var text: String = ""
    
	var body: some View {
        VStack {
            TextField(
                "메세지를 입력해주세요",
                text: $text,
                axis: .vertical
            )
            .border(.black)
            .padding(20)
            
            TextEditor(text: $text)
                .border(.black)
                .padding(20)
        }
    }

TextField와 TextEditor의 가장 눈에 띄는 차이를 보기 위해 VStack 내부에 두 컴포넌트를 나란히 배치해봤다.

TextField는 한 줄만큼의 높이만 차지하지만, TextEditor는 긴 텍스트의 입력을 위한 인터페이스이기 때문에 본인이 차지할 수 있는 최대 범위를 가지게 된다.

TextEditor(text: $text)
	.border(.black)
	.padding(20)
	.frame(height: 200)

물론 직접 지정해주면 원하는 높이로 사용이 가능하다.



TextEditor 커스텀

이전 글에서 설명한 것처럼 텍스트 라인 갯수에 따라 높이가 동적으로 변하는 입력 인터페이스가 필요하다.

그래서 구현에 필요한 요소들을 하나씩 고민해보기로 했다.



한 줄의 높이?

우선은 텍스트 한 줄의 높이를 알아야했다.

리터럴 값으로 테스트 해보고 적당히 맞추는 것도 가능했겠지만, 기기별 사이즈나 폰트 변화에 대응할 수 있는 형태로 구현해야 기획 변경에 유연하게 대응하고 재사용성이 높은 인터페이스를 구현할 수 있을 것 같았다.



타이포그래피

타이포그래피에서 텍스트의 높이와 관련된 이름들이 정의되어 있는 것이 생각났다.

그래서 폰트 내부에 관련 속성들이 이미 정의되어있는지 확인해봤다.

찾아보니 SwiftUI에서 사용하는 Font 타입에는 관련 프로퍼티가 없었지만, UIFont에는 관련 값들이 프로퍼티로 구현되어있었다. (역시 없는게 없는 애플)



Font -> UIFont

UIFont에 있는 lineHeight를 통해서 글자 높이를 구하면 되지만, 그러려면 Font 값을 통해서 UIFont를 초기화하거나 FontUIFont로 변환해야했다. 하지만 아쉽게도 UIFont에서 제공하는 관련 코드가 없었다.

그래서 FontUIFont로 변환하는 익스텐션을 구현했다.

extension UIFont {
    // MARK: Method - SwiftUI system Font를 UIFont 타입으로 변환하는 함수
    static func fontToUIFont(from font: Font) -> UIFont {
        let style: UIFont.TextStyle
        switch font {
        case .largeTitle:
            style = .largeTitle
        case .title:
            style = .title1
        case .title2:
            style = .title2
        case .title3:
            style = .title3
        case .headline:
            style = .headline
        case .subheadline:
            style = .subheadline
        case .callout:
            style = .callout
        case .caption:
            style = .caption1
        case .caption2:
            style = .caption2
        case .footnote:
            style = .footnote
        default:
            style = .body
        }
        return  UIFont.preferredFont(forTextStyle: style)
    }
}

FontUIFont Style을 1:1 대응시켜서 case에 따라 해당하는 UIFont로 리턴하도록 구현했다. (폰트 수가 많지 않아서 다행이다)

이제 프로퍼티에 접근해서 글자의 높이를 구할 수 있게 되었다.



구현부 내용이 길어져서 커스텀 과정은 다음 글에서 이어집니다!

profile
iOS Developer

0개의 댓글