iOS 기본 (SwiftUI)
[iOS - SwiftUI] Redacted(reason:), skeleton 모자이크 사용 방법
jake-kim
2022. 11. 5. 23:46
Redacted 란
* redact: (민감한 정보를) 수정하다
- 어떤 정보를 수정할 때, 관련 이유를 redacted(reason:) 파라미터로 넣으면 그에 따른 UI를 보여주는 메소드
- (스켈레톤 뷰처럼 뷰의 내용을 가려서 보여주는 것)
- 파라미터로 들어갈 수 있는 값은 .placeholder와 .privacy 존재
.redacated(reason: .placeholder) 사용 방법
ex) 프로필 뷰를 보여줄 때 api 로딩 전에 placeholder를 보여주고 싶은 경우 사용
- 프로필 뷰 구현
struct ContentView: View {
@State var isLoading = true
var body: some View {
profileView
}
@ViewBuilder
var profileView: some View {
VStack {
Image(systemName: "person.fill")
.resizable()
.frame(width: 50, height: 50)
.foregroundColor(.black)
Text("jake")
.foregroundColor(.black)
Button("Tap!") {
print("Tap information")
}
.disabled(isLoading) // redacted를 해도 disabled되지 않으므로 명시적으로 disabled 설정 필요
}
}
}
* 주의할점: redacted를 적용해서 뷰를 스켈리톤처럼 보여주더라도 버튼같은 경우 .disabled()를 명시적으로 해주지 않으면 disable가 안되므로 주의
- redacted(reason:) 추가하여 구현
- 예시를 위해서 DispatchQueue.main.asyncAfter로 3초 있다가 isLoading이 끝난다고 구현
- redcated를 다시 비활성화 할댄 reason 파라미터에 []를 주입
var body: some View {
profileView
.redacted(reason: isLoading ? .placeholder : [])
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
self.isLoading = false
}
}
}
.redacated(reason: .privacy) 사용 방법
- redactionReasons라는 내부적으로 정의된 Environment와 같이 사용
- .privacy는 내부적으로 privacy라는 상태를 저장해놓는 역할
- 환경변수 redactionReasons에 접근하여, privacy를 포함하는지 체크하여 분기문을 태워 뷰 표출
// .privacy 주입
MyView()
.redacted(reason: .privacy)
// redactionReasons 환경 변수에 접근하여 privacy인지 판별
struct MyView: View {
@Environment(\.redactionReasons) var redactionReasons
var body: some View {
if redactionReasons.contains(.privacy) {
Text("This is privacy")
} else {
Text("This is public")
}
}
}
커스텀 RedactionReasons
- 위와같이 .redacted(reason:)으로 RedactionReasons 값을 주입하고, 뷰에서 readactionReasons 환경 변수에 접근하여 분기문을 태워서 사용하는데, 이때 .privacy 값 말고도 다른 값 정의해서 사용도 가능
- rawValue는 일종의 id이므로, 중복되지 않도록 2의 제곱으로 표현
extension RedactionReasons {
static let someReason = RedactionReasons(rawValue: 1 << 2) // 4
static let someReason2 = RedactionReasons(rawValue: 1 << 4) // 16
}
* 사용하는쪽
// 사용하는쪽
MyView()
.redacted(reason: .someReason)
MyView()
.redacted(reason: .someReason2)
// 분기문
struct MyView: View {
@Environment(\.redactionReasons) var redactionReasons
var body: some View {
if redactionReasons.contains(.privacy) {
Text("This is privacy")
} else if redactionReasons.contains(.someReason) {
Text("This is someReason")
} else if redactionReasons.contains(.someReason2) {
Text("This is someReason2")
} else {
Text("This is public")
}
}
}
* 전체 코드: https://github.com/JK0369/ExRedacted-SwiftUI
* 참고
https://developer.apple.com/documentation/swiftui/redactionreasons
https://developer.apple.com/documentation/SwiftUI/View/redacted(reason:)