apple/SwiftUI & Combine
[SwiftUI] GeometryReader
lgvv
2022. 5. 19. 00:49
GeometryReader
✅ GeometryReader에 대해서 알아보자.
GeometryReader는 쉽게 말해서 디바이스 기기마다 대응하기 위함이다.
음,, 대충 오토 레이아웃이라고 생각하면 좋아!
✅ 코드
import SwiftUI
enum Index { // enum으로 처리한다.
case one, two, three
}
struct MyGeometryReaderVStack : View {
@State var index: Index = .one // 초기 상태는 one으로
var body: some View{
// 부모뷰의 비율을 사용 가능하다.
GeometryReader{ geometry in
VStack{
Button(action:{
// 버튼이 클릭되었을때 로직
print("1번이 클릭되었습니다.")
withAnimation { // 애니메이션을 걸기 위함.
self.index = .one // index를 1로 바꾼다.
}
}){
// 버튼의 생김새
Text("1")
.font(.largeTitle)
.fontWeight(.black)
.frame(width: 100, height: geometry.size.height / 3)
.padding(.horizontal, self.index == .one ? 50 : 0)
.foregroundColor(Color.white)
.background(Color.red)
}
Button(action:{
// 버튼이 클릭되었을때 로직
print("2번이 클릭되었습니다.")
withAnimation {
self.index = .two
}
}){
// 버튼의 생김새
Text("2")
.font(.largeTitle)
.fontWeight(.black)
.frame(width: 100, height: geometry.size.height / 3)
.padding(.horizontal, self.index == .two ? 50 : 0)
.foregroundColor(Color.white)
.background(Color.blue)
}
Button(action:{
// 버튼이 클릭되었을때 로직
print("3번이 클릭되었습니다.")
withAnimation {
self.index = .three
}
}){
// 버튼의 생김새
Text("3")
.font(.largeTitle)
.fontWeight(.black)
.frame(width: 100, height: geometry.size.height / 3)
.padding(.horizontal, self.index == .three ? 50 : 0)
.foregroundColor(Color.white)
.background(Color.green)
}
}
}
.background(Color.yellow)
.edgesIgnoringSafeArea(.all)
}
}
SwiftUI에서 코드 접는 펴는 방법
- 알트 커멘트 왼쪽(오른쪽)
✅ GeometryProxy position
이건 왜 사용하냐면 절대적인 포지션을 잡기 위함이다.
GeometryReader는 "뷰의 좌표에 이름을 정해서 다른 코드에서 작동하도록 하는 메서드"
GeometryProxy는 "컨테이너 뷰의 좌표나 크기를 접근할 수 있는 것"
즉, GeometryReader는 기하학적인 정보를 가지고 있는 컨테이너 뷰 자체이고 해당 정보를 얻어내기 위해선 GeometrryProxy를 이용해야 하는 것이죠.
import SwiftUI
enum Index {
case one, two, three
}
struct MyGeometryReaderVStack : View {
@State var index : Index = .one
// 지오메트리 프록시를 매개변수로 가지고 CGPoint 를 반환하는 클로져
let centerPosition : (GeometryProxy) -> CGPoint = { proxy in
return CGPoint(x: proxy.frame(in: .local).midX,
y: proxy.frame(in: .local).midY)
}
var body: some View {
GeometryReader { proxy in
VStack {
Button(action: {
// 버튼이 클릭되었을때 로직
print("1번이 클릭되었습니다.")
withAnimation {
self.index = .one
}
}){
// 버튼의 생김새
Text("1")
.font(.largeTitle)
.fontWeight(.black)
.frame(width: 100, height: proxy.size.height / 3)
.padding(.horizontal, self.index == .one ? 50 : 0)
.foregroundColor(Color.white)
.background(Color.red)
}
// Button(action: {
// // 버튼이 클릭되었을때 로직
// print("2번이 클릭되었습니다.")
//
// withAnimation {
// self.index = .two
// }
//
//
// }) {
// // 버튼의 생김새
// Text("2")
// .font(.largeTitle)
// .fontWeight(.black)
// .frame(width: 100, height: proxy.size.height / 3)
// .padding(.horizontal, self.index == .two ? 50 : 0)
// .foregroundColor(Color.white)
// .background(Color.blue)
// }
//
// Button(action: {
// // 버튼이 클릭되었을때 로직
// print("3번이 클릭되었습니다.")
//
// withAnimation{
// self.index = .three
// }
//
// }) {
// // 버튼의 생김새
// Text("3")
// .font(.largeTitle)
// .fontWeight(.black)
// .frame(width: 100, height: proxy.size.height / 3)
// .padding(.horizontal, self.index == .three ? 50 : 0)
// .foregroundColor(Color.white)
// .background(Color.green)
// }
}
// .position(CGPoint(x: proxy.frame(in: .local).midX, y: proxy.frame(in: .local).midY))
.position(centerPosition(proxy))
}
.background(Color.yellow)
.edgesIgnoringSafeArea(.all)
}
}
(참고)
https://fomaios.tistory.com/entry/SwiftUI-GeometryReader%EB%9E%80?category=933741