안녕하세요 Niro 🚗 입니다!
SwiftUI 에서 TextField 를 쓰던 중 글자 수를 제한하는 기능이 필요했습니다.
찾아보니 해당 기능은 지원하지 않았고 내가 직접 modifier 를 만들어야겠구나 싶었습니다.
struct MaxLengthModifier: ViewModifier {
@Binding var text: String
let maxLength: Int
func body(content: Content) -> some View {
content
.onChange(of: text) { oldValue, newValue in
if newValue.count > maxLength {
text = oldValue
}
}
}
}
우리는 무언가를 입력하면 즉각적으로 변해야 하기 때문에 TextField
에는 입력 값을 Binding 해야만 합니다.
그렇기 때문에 우리는 State 변수를 선언해서 값을 받아오게 되죠!
어쨋든 TextField
의 값을 받아오고자 Binding 속성인 String 유형 프로퍼티와 입력 가능한 글자 수를 정하기 위한 maxLength
프로퍼티도 만들어주었습니다.
그 다음 text 프로퍼티가 값이 변하는 것을 실시간으로 관리하고자 onChange
수정자를 사용했습니다.
onChange
수정자는 기존 값과 새로운 값을 관리할 수 있습니다. 글자 수 제한을 위해 새로 입력받은 newValue
의 count 가 maxLength
를 넘는다면 oldValue
를 text 에 다시 할당해주었습니다.
자 우리가 직접 만든 MaxLengthModifier
를 TextField
에서 사용할 수 있도록 만들어보겠습니다.
extension TextField {
/// TextField 에서 최대 글자수를 정하기 위한 Modifier
func maxLength(text: Binding<String>, _ maxLength: Int) -> some View {
return ModifiedContent(content: self,
modifier: MaxLengthModifier(text: text,
maxLength: maxLength))
}
}
maxLength
라는 메서드를 TextField
에 Extension 으로 만들어주었습니다.
ModifiedContent
는 이름 직역 그대로 수정된 Content 뜻을 갖고 있죠?
기존의 View 에 어떠한 modifier 를 통해 수정하여 다시 반환해주는 역할을하게 됩니다.
content
는 수정을 적용할 원래의 View 를 넣어주고 modifier
는 적용할 수정자를 의미합니다.
ViewModifier 도 만들어봤고 메서드도 만들어봤으니 이제 직접 사용을 해봐야겠죠?
@State var inputText = ""
TextField("글자 수 입력 제한", text: $inputText)
.maxLength(text: $inputText, 10)
먼저, @State 속성 감지자(property wrapper)를 사용하여 상태를 관리하는 inputText
변수를 선언합니다. 이 변수는 사용자가 텍스트 필드에 입력한 내용을 저장합니다.
TextField
에 Extension 으로 maxLength
를 만들어주었기 때문에 다음과 같이 . 만 으로도 호출이 가능해지게 되고
TextField
에 입력받은 어떠한 값을 Binding 받을 inputText
를 다시 maxLenghth
에 Binding 해주게 됩니다.
실제로 써면 다음과 같이 글자 수 제한을 10자로 해놨을 때 그 이상 입력되지 않는 모습을 볼수가 있죠!
앞으로 프로젝트 내에서 필요한 기능이 있다면 자유롭게 Modifier 를 만들 수 있는 실력을 키우는게 필요할거 같습니다!