욤찌의 개발 일기
[SwiftUI] .onChange 와의 초면 본문
이전에 포스팅 한 <Log in 화면 구현하기> 를 조금씩 업그레이드 하고 있는데,
일단 가장 먼저 하고싶었던 것이 아이디와 비밀번호를 입력하지 않으면 이용약관 토글이 활성화가 되지 않는 것이었다.
그러니까 아이디와 비밀번호 두가지가 모두 다 입력 되어야만 토글이 활성화가 되게 만드는 !!!!!
그래서 아주 포포포포포폭풍 검색을 하다가 .onChange 를 만나게 되었다.
https://developer.apple.com/documentation/swiftui/scene/onchange(of:initial:_:)-7b6vh
onChange(of:initial:_:) | Apple Developer Documentation
Adds an action to perform when the given value changes.
developer.apple.com
.onChange 를 공식문서에서 찾으면
Adds an action to perform when the given value changes. 이라고 설명해준다.
어떤 주어진 값이 변경될때마다 수행할 작업을 추가한다는 의미..인데
결국 .onChange에 주어진 값이 변하면 수행할 작업을 추가해서 수행하겠다는 의미로 이해했다.
func onChange<V>(
of value: V,
initial: Bool = false,
_ action: @escaping (V, V) -> Void
) -> some Scene where V : Equatable
표현식은 이렇게 생겼움,, (아직 공식문서에 나와있는 표현식들이 넘 어색,, 친해져야하눈데,,)
파라미터는 다음과 같이 구성되어 있음.
1️⃣ value : The value to check when determining whether to run the closure. The value must conform to the Equatable protocol. (클로저를 실행할지 말지를 결정할 때 체크하는 value인데, 이 값은 Equatable 프로토콜을 따라야 한다)
📍설명은 이렇게 나와있음. 해당 value 값이 변할 때 closure를 실행한다는 의미로 이해함. 근데 나는 또 Equatable과 초면이라.. 이건 나중에 따로 공부해야 할 것 같음..
2️⃣ initial : Whether the action should be run when this scene initially appears. (이 scene이 처음 나타났을 때, 작업을 실행할지말지에 대한 여부)
📍onChange가 있는 scene이 처음 시작했을 때 이걸 실행할거냐고 묻는거. Boolean 타입으로 지정되어 있고 false임. 처음에는 당연히 실행하면 안되겠지,, value 가 바뀌어야 실행해야 하니까 당연히 false 로 지정되어있어야 하는걸로 이해함.
3️⃣ action : A closure to run when the value changes. (값이 변했을때 실행되는 closure)
📍값이 변했을 때 설정한 작업을 수행한다는 의미로 이해함. Equatable 한 값을 input으로 넣어서 아무것도 return 하지 않는 함수를 넣어주면 됨.
여기서 newValue 와 oldValue를 파라미터로 갖게 되는데,
4️⃣ oldValue : The old value that failed the comparison check (or the initial value when requested). (비교 검사에 실패한 이전 값 혹은 리퀘스트 되었을 때 초기값)
📍원래 지정되어 있던 value 를 말함. 근데 왜 비교 검사에 실패한 이전 값이라고 표현한건지는 모르겠음. 그냥 원래 설정해놨던 초기값을 의미한다고 이해함.
5️⃣ newValue : The new value that failed the comparison check. (비교 검사에 실패한 새로운 값)
📍아 여기서 알았음!!! 왜 Equatable 프로토콜을 사용해야 하는지..! 비교검사를 해야해서 그렇구나~ 비교검사를 해서 이전에 값과 다르다고 판정이 되어야 값을 변경해서 closure 를 실행하니까 그렇구나~ 이해함. (근데 이걸 영어로 fail 이라고 표현하는구나.. 아니면 내가 잘못 이해한걸 수도 있음..ㅋ 근데 이렇게 아니면 어떻게 해석해야 할지 모르겠음..ㅎ!)
Xcode에서는 아래와 같이 확인할 수 있음.
.onChange(of: Equatable, perform: (Equatable) -> Void)
perform 부분 클로져 엔터치면
.onChange(of: Equatable) { newValue in
(code)
}
이로케 나옴
하,, 이해하는 것이 왜이렇게 힘들어버릴까..^^,,
째뜬 그래서 나는 이것을 어디서 어떻게 썻냐며~언~
// id와 비밀번호를 담은 변수
@State var id: String = ""
@State var password: String = ""
// 이용약관 동의하는지 토글을 변경해줄 Bool 타입 변수
@State var agreeToTerms: Bool = false
일단 이전 포스팅에도 있지만 여기서도 기억하려고 한 번 써보겠다
1️⃣ id 와 비밀번호를 입력하면 담을 변수를 생성. 텍스트필드에서 user가 입력하면 여기에 담길 것이다.
2️⃣ 이용약관 동의 여부를 토글로 설정할 수 있는 Bool 타입의 변수도 생성. 일단 false 로 초기값 설정해서 비활성화
요고 말하는거임!!
Toggle("Agree to terms and conditions", isOn: $agreeToTerms)
.disabled(!agreeToTerms)
3️⃣ 이용약관 토글에 .disabled 를 통해 비활성화로 완전히 막아놨움. 나는 !agreeToTerms 라고 하면 처음에 false 로 초기값 설정해놔서 true 인거 아닌가? 했는데 그냥 이 변수 자체를 true 로 보고 !를 붙이면 false 라는 뜻인가봄.. 왜냐면 그렇게 작동하기 때문이다..
func updateToggleEnabled() {
agreeToTerms = id.contains("@") && password.count > 8
}
}
4️⃣ updateToggleEnabled 라는 함수를 통해 agreeToTerms 변수가 id 에 @이 포함되어야 하고 password 는 9자리 이상 입력이 되는 조건을 다 만족해야만 토글이 활성화가 되는 함수를 만든다!!!
// id 입력하는 텍스트필드에 .onChange 적용하기
TextField(" Enter your E-mail", text: $id)
.onChange(of: id) { newValue in
updateToggleEnabled()
}
// 비밀번호 입력하는 텍스트필드도 똑같음
if showPassword {
TextField(" Enter your password", text: $password)
.onChange(of: password) { newValue in
updateToggleEnabled()
}
} else {
SecureField(" Enter your password", text: $password)
.onChange(of: password) { newValue in
updateToggleEnabled()
}
5️⃣ 해당 textField에 .onChange 를 통해 적용해주면 된다. id 를 예로 들자면, .onChange의 value 값으로 id 를 지정해서 id 값이 변하면 closure 구문을 실행하겠다는 뜻임. 나는 closure 말고 구현해놓은 함수를 직접 넣음. (근데 함수내용 closure 자리에 복붙해도 에러 안뜸.. newValue가 지금은 직접 사용되지 않아서 그런지.. newValue 자리에 와일드카드 패턴 써도 상관없움.)
째뜬! 우당탕탕이지만,, 이렇게 했더니 잘만 작동합니다요~!
그래서 이 코드의 결과는 다음 동영상과 같습니당
처음에 아무리 토글 눌러도 실행 안되고 아이디에 @ 들어가야 하고, 비밀번호가 9자리가 눌려야 토글이 활성화가 됩니당ㅎ
이렇게 .onChange 맛보기만 살짝 해보았읍니다,,, 멀고도 험한 개발자의 길,,,
그러다 넘나 재밌는,,,,
제 포스팅에 언제든지 태클 부탁드립니다 갈길이 먼 이 개발자 한 번만 도와주세요..~!
'SwiftUI' 카테고리의 다른 글
[SwiftUI] Custom Calendar을 만들어보자 (1) | 2024.03.11 |
---|---|
[SwiftUI] @FocusState 와의 초면 (0) | 2023.07.10 |
[SwiftUI] Log in 화면을 만들어 보쟈📱 (0) | 2023.06.23 |