[Swift] SwiftUI로 화면을 자르십시오.
15472 단어 SwiftshapeUIBezierPathpathSwiftUI
전치
유저에게 힌트를 내는 화면이 많은 앱으로 구현되고 있을까 생각합니다.
이 화면은 실제로 SwiftUI
로 만들어집니다.
그렇다면 어떻게 했는지 살펴 보겠습니다.
구현 방법
2 패턴 소개하고 싶습니다.
1. UIBezierPath on SwiftUI로 구현
UIKit
의 경우는 UIBezierPath
를 사용한 구현 방법이 있었습니다.
다음은 Objective-C
코드이므로 낡습니다만, 비교적 알기 쉬운 코드 예입니다.
UIBezierPath
로 「화면 전체」와 「자르는 부분」을 겹치는 것으로, 겹친 부분만 투과할 수 있다고 하는 방법입니다. 이것을 SwiftUI
의 View
에 적응하기 만하면됩니다.
이번에는 아래와 같이 조금 간단하게 한 화면에서 소개하겠습니다.
빼기 전
빼낸 후
화면 구성
화면 자체는, 이하의 3개를 조합한 매우 심플한 구성으로 되어 있습니다.
① 경고 화면
②검은 필터 화면
③ 투명한 구멍 화면
① 경고 화면
struct TutorialAlertView: View {
var handler: (() -> Void)?
var body: some View {
VStack {
Text("Title")
.padding(EdgeInsets(top: 8, leading: 0, bottom: 0, trailing: 0))
Text("Description")
.padding(EdgeInsets(top: 8, leading: 0, bottom: 0, trailing: 0))
Button(action: { handler?() }, label: {
Text("OK")
.frame(width: 252, height: 44)
.foregroundColor(.white)
.background(Color.red)
.cornerRadius(4)
.padding(EdgeInsets(top: 8, leading: 0, bottom: 8, trailing: 0))
})
.contentShape(Rectangle())
}
.frame(maxWidth: 300)
.background(Color.white)
.cornerRadius(4)
}
}
② 검은색 필터 화면
struct TutorialFilterView: View {
var body: some View {
Color.black
.opacity(0.7)
.mask(TutorialHoleView())
.edgesIgnoringSafeArea(.all)
}
}
mask()
를 사용하여 필터 부분을 잘라냅니다.
③ 투명한 구멍 화면
struct TutorialHoleView: View {
var body: some View {
// 穴
let holePath = UIBezierPath(roundedRect: CGRect(
x: 8,
y: 60,
width: 100,
height: 80
), cornerRadius: 24)
// 全体
var shape = Path(CGRect(
origin: .zero,
size: UIScreen.main.bounds.size
))
shape.addPath(Path(holePath.cgPath)) // Pathに変換
return shape.fill(style: FillStyle(eoFill: true))
}
}
SwiftUI
에서는 Path
라고 하는 것이 있어, UIBezierPath
로부터 변환하는 것으로 취급할 수가 있습니다. 변환 자체는 .cgPath
를 참조하는 것만으로 가능하므로 매우 간단합니다. FillStyle
가 없으면 투과 부분이 반전되어 버리므로 붙여 주십시오.
①~③을 조합한 화면
이것을 ZStack
로 겹쳐 조합하면 완성됩니다.
화면
중첩
struct TutorialView: View {
var body: some View {
ZStack {
TutorialFilterView()
TutorialAlertView { /* do some button action */ }
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
이번은 예이므로 frame
를 고정으로 하고 있습니다만, 위치를 조정하는 경우는 전의 화면으로부터 건네주어 가야 합니다.
2. SwiftUI에서만 구현
방금 구현한 UIBezierPath
로 구현한 부분을 SwiftUI
의 Shape 를 사용해 구현합니다.
기본적으로는 거의 같고, 「③ 투명한 구멍의 화면」의 코드로 작성한 TutorialHoleView
부분을, 이하와 같이 Shape
(Rectangle)로 합니다.
example code
struct TutorialHoleView: View {
var body: some View {
Rectangle()
.cornerRadius(24)
.frame(width: 100, height: 80)
.position(x: 60, y: 150)
.background(Color.white)
.compositingGroup() // ※1
.luminanceToAlpha() // ※2
}
}
Shape
를 사용하는 경우 다음 두 가지를주의 사항으로 설정해야합니다.
2 패턴 소개하고 싶습니다.
1. UIBezierPath on SwiftUI로 구현
UIKit
의 경우는 UIBezierPath
를 사용한 구현 방법이 있었습니다.다음은
Objective-C
코드이므로 낡습니다만, 비교적 알기 쉬운 코드 예입니다.UIBezierPath
로 「화면 전체」와 「자르는 부분」을 겹치는 것으로, 겹친 부분만 투과할 수 있다고 하는 방법입니다. 이것을 SwiftUI
의 View
에 적응하기 만하면됩니다.이번에는 아래와 같이 조금 간단하게 한 화면에서 소개하겠습니다.
빼기 전
빼낸 후
화면 구성
화면 자체는, 이하의 3개를 조합한 매우 심플한 구성으로 되어 있습니다.
① 경고 화면
②검은 필터 화면
③ 투명한 구멍 화면
① 경고 화면
struct TutorialAlertView: View {
var handler: (() -> Void)?
var body: some View {
VStack {
Text("Title")
.padding(EdgeInsets(top: 8, leading: 0, bottom: 0, trailing: 0))
Text("Description")
.padding(EdgeInsets(top: 8, leading: 0, bottom: 0, trailing: 0))
Button(action: { handler?() }, label: {
Text("OK")
.frame(width: 252, height: 44)
.foregroundColor(.white)
.background(Color.red)
.cornerRadius(4)
.padding(EdgeInsets(top: 8, leading: 0, bottom: 8, trailing: 0))
})
.contentShape(Rectangle())
}
.frame(maxWidth: 300)
.background(Color.white)
.cornerRadius(4)
}
}
② 검은색 필터 화면
struct TutorialFilterView: View {
var body: some View {
Color.black
.opacity(0.7)
.mask(TutorialHoleView())
.edgesIgnoringSafeArea(.all)
}
}
mask()
를 사용하여 필터 부분을 잘라냅니다.③ 투명한 구멍 화면
struct TutorialHoleView: View {
var body: some View {
// 穴
let holePath = UIBezierPath(roundedRect: CGRect(
x: 8,
y: 60,
width: 100,
height: 80
), cornerRadius: 24)
// 全体
var shape = Path(CGRect(
origin: .zero,
size: UIScreen.main.bounds.size
))
shape.addPath(Path(holePath.cgPath)) // Pathに変換
return shape.fill(style: FillStyle(eoFill: true))
}
}
SwiftUI
에서는 Path
라고 하는 것이 있어, UIBezierPath
로부터 변환하는 것으로 취급할 수가 있습니다. 변환 자체는 .cgPath
를 참조하는 것만으로 가능하므로 매우 간단합니다. FillStyle
가 없으면 투과 부분이 반전되어 버리므로 붙여 주십시오.①~③을 조합한 화면
이것을
ZStack
로 겹쳐 조합하면 완성됩니다.화면
중첩
struct TutorialView: View {
var body: some View {
ZStack {
TutorialFilterView()
TutorialAlertView { /* do some button action */ }
}
.frame(maxWidth: .infinity, maxHeight: .infinity)
}
}
이번은 예이므로
frame
를 고정으로 하고 있습니다만, 위치를 조정하는 경우는 전의 화면으로부터 건네주어 가야 합니다.2. SwiftUI에서만 구현
방금 구현한
UIBezierPath
로 구현한 부분을 SwiftUI
의 Shape 를 사용해 구현합니다.기본적으로는 거의 같고, 「③ 투명한 구멍의 화면」의 코드로 작성한
TutorialHoleView
부분을, 이하와 같이 Shape
(Rectangle)로 합니다.example code
struct TutorialHoleView: View {
var body: some View {
Rectangle()
.cornerRadius(24)
.frame(width: 100, height: 80)
.position(x: 60, y: 150)
.background(Color.white)
.compositingGroup() // ※1
.luminanceToAlpha() // ※2
}
}
Shape
를 사용하는 경우 다음 두 가지를주의 사항으로 설정해야합니다.compositingGroup()
: ZStack 내용 그룹화 luminanceToAlpha()
: 어두운 영역은 투명하고 밝은 영역은 불투명 한 검은 색으로 만듭니다 이것을 설정하면 펀칭을 반영할 수 있습니다.
또한
Rectangle
를 사용하고 있지만 Shape
이면 좋기 때문에,등 다양한 도형을 사용하여 빠져 나올 수 있습니다.
결합된 화면
화면
중첩
이와 같이
SwiftUI
가 준비한 도형을 이용하는 것으로, 심플한 구현으로 할 수 있습니다.구분
간단하게 빼내기의 구현이면,
SwiftUI
의 Shape
를 사용한 구현이 편하게 구현 가능합니다. 단, 별 모양이나 하트 등, 어려운 도형을 빼내고 싶은 경우는, Path
or UIBezierPath
로 도형을 작성하게 됩니다.동작하는 리포지토리를 두어 두므로, 여러가지 시험해 보면 재미있을까 생각합니다.
기타
UIBezierPath
의 방법을 소개했습니다만, Path
로 도형을 만드는 방법도 게재해 둡니다 Reference
이 문제에 관하여([Swift] SwiftUI로 화면을 자르십시오.), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/hcrane/items/7211453164ff6726a73c텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)