Redacted
에 대해 알아보겠습니다.
Redacted(reason: .placeholder)
iOS 14에서 SwiftUI에는 모든 콘텐츠를 redact
하는 새로운 한정자(modifier)가 있습니다. 새로운 view
한정자가 있는 모든 view
에 .redacted(reason:)
을 적용할 수 있습니다.
이 한정자에는 이유 한정자(reason modifier
)가 필요한데, 이는 이 redact
작업의 이유를 SwiftUI
에 알려줍니다.
현재 Apple은 한 가지 reason modifier
만 제공하고 있습니다. (reason: .placeholder
)
Text("Hello, SwiftUI!")
.redacted(reason: .placeholder)
이름에서 알 수 있듯이 .placeholder
reason modifier는 실제 콘텐츠가 로드되기 전에 .placeholder
로 사용되는 방식으로 콘텐츠를 redact(수정)합니다.
프로필 만들기
간단하게 프로필 하나를 만들어 보겠습니다.
struct ContentView: View {
var body: some View {
VStack{
Image("mydog")
.resizable()
.frame(width: 140, height: 140)
.clipShape(Circle())
Text("서근")
.font(.title)
.fontWeight(.bold)
Spacer().frame(height: 30)
VStack(alignment: .leading, spacing: 12) {
HStack {
Image(systemName: "envelope.circle.fill")
.renderingMode(.original)
Text("ksj083895@gmail.com")
}
HStack {
Image(systemName: "phone.circle.fill")
.renderingMode(.original)
Text("+82 10 1234 5678")
}
HStack {
Image(systemName: "network")
.foregroundColor(.yellow)
Text("seons-dev.tistory.com")
}
}
Spacer().frame(height: 30)
Button(action: {
print("프로필을 업데이트 합니다.")
}){
Text("Update Profile")
.frame(width: 200, height: 40)
.background(Color.orange)
.cornerRadius(10)
.foregroundColor(.white)
}
}
}
}
이렇게 프로필 코드를 만들고 여기에 .redacted(reason:)
한정자를 적용해 보겠습니다. 상단 VStack
이 끝나는 지점에 이 한정자를 추가해줍니다.
struct ContentView: View {
var body: some View {
VStack {...}
.redacted(reason: .placeholder)
}
}
.unredacted()
일부 View
를 redact
하지 않으려면 View
에 .unredacted()
를 사용하여 적용된 reason modifier를 제거할 수 있습니다.
만약 서근의 상세정보에 아이콘만 보이게 해주고 싶다면 아래와 같이 수정합니다.
VStack(alignment: .leading, spacing: 12) {
HStack {
Image(systemName: "envelope.circle.fill")
.renderingMode(.original)
.unredacted()
Text("ksj083895@gmail.com")
}
HStack {
Image(systemName: "phone.circle.fill")
.renderingMode(.original)
.unredacted()
Text("+82 10 1234 5678")
}
HStack {
Image(systemName: "network")
.foregroundColor(.yellow)
.unredacted()
Text("seons-dev.tistory.com")
}
}
startNetworkCall - 지연 효과
앱이 실행되고 나서 3초의 지연시간 뒤에 프로필의 상세 내역이 나타나게 하고 싶다면 아래와 같이 startNetworkCall()
이라는 함수를 만들어 줘야 합니다.
import SwiftUI
struct ContentView: View {
@State private var isLoading = false
var body: some View {...}
func startNetworkCall() {
isLoading = true
//3초 지연 후, 로딩이 완료됨
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
isLoading = false
}
}
}
이렇게 함수
와 @State
를 만들어줬으니 이제 호출을 해줄 차례입니다. VStack 바깥쪽에 .onAppear
을 사용하여 그 안에 만들어준 함수를 넣어줍니다.
삼항연산자
를 사용하여 isLoading
이 true
이면 .placeholder
을 실행 그게 아니면 empty
즉, .redacted(reason: isLoading ? .placeholder : [])
라는 구문도 수정해주겠습니다.
VStack {...}
.onAppear { startNetworkCall() }
//isLoading이 true이면 .placeholder을 실행 그게아니면 empty
.redacted(reason: isLoading ? .placeholder : [])
}
func startNetworkCall() {
isLoading = true
//3초 지연 후, 로딩이 완료됨
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
isLoading = false
}
}
}
로딩이 되지 않았을 경우 버튼 비활성화
위 코드에서 한 가지 문제점이 있습니다. 아직 프로필이 로딩되지 않았음에도 불구하고 버튼을 클릭하면 버튼이 활성화가 됩니다.
로딩이 완료되기 전에는 버튼을 클릭해도 활성화되지 않게 하려면 Button
에 .disabled(isLoading)
을 추가해줘야 합니다.
Button(action: {
print("프로필을 업데이트 합니다.")
}){
Text("Update Profile")
.frame(width: 200, height: 40)
.background(Color.orange)
.cornerRadius(10)
.foregroundColor(.white)
}
.disabled(isLoading)
이제 캔버스를 런 해보면 앱이 실행되고 난 후 3초 뒤에 프로필 상세 내역이 나타나고, 로딩이 되지 않았을 때는 버튼이 활성화되지 않는 것을 확인할 수 있습니다.
전체 코드
<hide/>
import SwiftUI
struct ContentView: View {
@State private var isLoading = false
var body: some View {
VStack{
Image("mydog")
.resizable()
.frame(width: 140, height: 140)
.clipShape(Circle())
Text("서근")
.font(.title)
.fontWeight(.bold)
Spacer().frame(height: 30)
VStack(alignment: .leading, spacing: 12) {
HStack {
Image(systemName: "envelope.circle.fill")
.renderingMode(.original)
.unredacted()
Text("ksj083895@gmail.com")
}
HStack {
Image(systemName: "phone.circle.fill")
.renderingMode(.original)
.unredacted()
Text("+82 10 1234 5678")
}
HStack {
Image(systemName: "network")
.foregroundColor(.yellow)
.unredacted()
Text("seons-dev.tistory.com")
}
}
Spacer().frame(height: 30)
Button(action: {
print("프로필을 업데이트 합니다.")
}){
Text("Update Profile")
.frame(width: 200, height: 40)
.background(Color.orange)
.cornerRadius(10)
.foregroundColor(.white)
}
.disabled(isLoading)
}
.onAppear { startNetworkCall() }
//isLoading이 true이면 .placeholder을 실행 그게아니면 empty
.redacted(reason: isLoading ? .placeholder : [])
}
func startNetworkCall() {
isLoading = true
//3초 지연 후, 로딩이 완료됨
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
isLoading = false
}
}
}
읽어주셔서 감사합니다🤟
본 게시글의 전체코드 GitHub 👇🏻
'SWIFTUI > Others' 카테고리의 다른 글
SwiftUI : Preview 레이아웃을 미리 보는방법 (2) | 2021.04.05 |
---|---|
SwiftUI : layoutPriority( ) - 뷰 우선순위 (0) | 2021.03.14 |
SwiftUI : Menu 버튼을 눌렀을 때 메뉴를 표시 (0) | 2021.01.30 |
SwiftUI : Animation #2 (0) | 2021.01.26 |
SwiftUI : Animation #1 (2) | 2021.01.26 |