//
// ContentView.swift
// AddRemoveButton
//
// Created by Arvind on 30/12/20.
//
import SwiftUI
struct ContentView: View {
@State private var isRotate = false
@State private var isChangeOffset = false
private let varicalLineWidth: CGFloat = 10
private let varicalLineHeight: CGFloat = 40
private let horiLineWidth: CGFloat = 40
private let horiLineHeight: CGFloat = 10
private let rotationDegree: Double = -45
var body: some View {
ZStack() {
Color.getBackgroundColor().edgesIgnoringSafeArea(.all)
HStack(spacing: -2) {
Rectangle()
.frame(width: horiLineWidth, height: horiLineHeight)
.cornerRadius(4)
.foregroundColor(.white)
.rotationEffect(.degrees(isRotate ? rotationDegree : 0), anchor: .center)
.offset(x: 0, y: isChangeOffset ? 10 : 0)
Rectangle()
.frame(width: horiLineWidth, height: horiLineHeight)
.cornerRadius(4)
.foregroundColor(.white)
.rotationEffect(.degrees(isRotate ? rotationDegree : 0), anchor: .center)
.offset(x: isChangeOffset ? -10 : 0, y: isChangeOffset ? -18 : 0)
}
VStack( spacing: -2) {
Rectangle()
.frame(width: varicalLineWidth, height: varicalLineHeight)
.cornerRadius(4)
.foregroundColor(.white)
.rotationEffect(.degrees(isRotate ? rotationDegree : 0), anchor: .center)
.offset(x: isChangeOffset ? -20 : 0, y: isChangeOffset ? 0 : 0)
Rectangle()
.frame(width: varicalLineWidth, height: varicalLineHeight)
.cornerRadius(4)
.foregroundColor(.white)
.rotationEffect(.degrees(isRotate ? rotationDegree : 0), anchor: .center)
.offset(x: isChangeOffset ? 10 : 0, y: isChangeOffset ? -8 : 0)
}
}.animation(Animation.linear(duration: 0.3))
.frame(height: UIScreen.main.bounds.height)
.onTapGesture {
isRotate.toggle()
Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false) { _ in
withAnimation(Animation.easeInOut(duration: 0.5)) {
isChangeOffset.toggle()
}
}
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
extension Color {
static func getBackgroundColor() -> Color {
return Color(red: 0.15, green: 0.37, blue: 1.00)
}
}
차근차근 정리를 해보자
먼저 변수 부분부터
@State private var isRotate = false
@State private var isChangeOffset = false
private let varicalLineWidth: CGFloat = 10
private let varicalLineHeight: CGFloat = 40
private let horiLineWidth: CGFloat = 40
private let horiLineHeight: CGFloat = 10
private let rotationDegree: Double = -45
먼저 @State로 선언된 isRotate, isChangeOffset부분은 변수명 그대로 회전과 offset값이 변경되었는지 확인하는 부분의 코드인것 같은데 얕게 배운 지식으로는 @state는 다른 뷰간의 데이터 전송을 위한 프로퍼티인줄 알아서 딱히 필요없을 줄 알고 해당 코드를 지워볼려고 했는데 밑에 선언된 .onTapGesture 안에 있는 .toggle에서 오류가 나 toggle에 대해 알아보니 toggle은 true, false를 알려주는 코드이고 toggle을 사용하기 위해서는 state를 붙여야 한다고 한다.
그리고 밑의 변수는 수직, 수평의 선의 크기를 선언하는 변수와 회전 각도를 저장한 변수인 것 같다.
이제 본 코드인 body 안의 코드를 보자
zstack으로 감싸여저 있는 Hstack과 Vstack이 보인다.
Rectangle()
.frame(width : horiLineWidth, height : horiLineHeight)
.cornerRadius(4)
.foregroundColor(.white)
.rotationEffect(.degrees(isRotate ? rotationDegree : 0), anchor : .center)
.offset(x: 0 , y : isChangeOffset ? 30 : 0)
대충 한 부분만 정리를 해도 될 것 같다.
다 동일한데 offset 부분만 다른 것 같아서 굳이 안해도 될 것 같다.
먼저 Rectangle로 사각형을 선언한 후 frame으로 크기를 지정해 준다.
그리고 색을 정해 주는 것 같은데
처음 보는 foregroundColor라는 것이 보인다.
설명으로는 앞부분의 색을 지정해 주는 함수로 보이고 또한 해당 함수는 이제 지원이 끊겼다고 하니 foregroundStyle 함수를 사용하도록 하자.
다음으로 .rotationEffect함수가 있는데 해당 함수는 회전을 시키는 함수로 보인다. degree로 각도를 조절하는 것으로 보인다.
마지막으로 .offset은 자기 자신의 좌표를 중심으로 이동하는 것 같다. .possion함수는 절대 좌표를 중심으로 이동하는 것 같다.
마지막으로 Zstack의 함수들이다.
.animation(Animation.linear(duration: 0.3))
.frame(height : UIScreen.main.bounds.height)
.onTapGesture{
isRotate.toggle()
Timer.scheduledTimer(withTimeInterval : 0.5, repeat: false){_ in
withAnimation(Animation.easeInOut(duration: 0.5)){
isChangeOffset.toggle()
}
}
}
.animation함수는 해당 하는 모든 값에 animation을 적용하는 함수로 보인다.
frame은 크기를 지정하는 함수이고 .onTapGesture은 터치시 작동이 되도록 하는 함수로 보인다.
.onTapGesture함수가 작동 되면 내부에 있는 isRotate.toggle 함수가 작동 되면서 Rectangle이 작동을 하고 Timer 함수를 통해 시간을 딜레이 주면서 withAnimation안에 있는 isChangeOffset.toggle()함수가 작동하면서 Rectangle의 좌표가 움직이는 것으로 보인다.
큰 도움이 되었습니다, 감사합니다.