SwiftUI

SwiftUI - 슬라이더 뷰(Slider View) 사용

iosos 2024. 1. 22. 16:14

 

1. 레이아웃에 VStack 추가하기

struct Chap22: View {
    var body: some View {
        VStack {
            Text("Hello, World!")
        }
    }
}

 

 

 

2. 스택에 슬라이더 뷰 추가하기

  • 라이브러리 패널에서 Slider를 찾아 프리뷰 캔버스에 있는 Text 뷰 위로 드래그 앤 드롭

 

 

 

 

 

 

 

3. 상태 프로퍼티 추가

  • 슬라이더는 Text 뷰를 회전시킬 총량을 제어하는 데 사용됨
  • Slider 뷰와 현재의 회전 값을 저장하게 될 상태 프로퍼티 간에 바인딩이 구축되어야 함
  • 상태 프로퍼티 선언 후 0부터 360까지의 범위로 0.1씩 증가되도록 슬라이더 구성
struct Chap22: View {
    
    @State private var rotation : Double = 0
    
    var body: some View {
        VStack {
            Text("Hello, World!")
            Slider(value: $rotation, in : 0 ... 360, step: 0.1)
        }
    }
}

→ Slider 뷰와 회전 상태 프로퍼티가 바인딩 되도록 선언하기 때문에 ‘$’ 문자를 앞에 붙여야 함

 

 

 

 

 

4. Text 뷰에 수정자 추가

  • font, 폰트의 굵기 변경
var body: some View {
        VStack {
            Text("Hello, World!")
                .font(.largeTitle)
                .fontWeight(.heavy)
            Slider(value: $rotation, in : 0 ... 360, step: 0.1)
        }
    }

 

 

 

5. 회전과 애니메이션 추가

  • Slider에 의해 조절되어 저장된 값을 이용하여 회전과 애니메이션 효과를 Text 뷰에 추가
Text("Hello, World!")
                .font(.largeTitle)
                .fontWeight(.heavy)
                .rotationEffect(.degrees(self.rotation))

→ 바인딩 설정이 아닌, 회전에 대한 상태 프로퍼티에 할당된 값을 읽는 것이기 때문에 프로퍼티 이름 앞에 ‘$’ 표시 하지 않음

 

 

 

 

  • Ease in Out 효과를 사용하여 5초 동안 애니메이션 되도록 Text 뷰에 에니메이션 수정자 추가
Text("Hello, World!")
                .font(.largeTitle)
                .fontWeight(.heavy)
                .rotationEffect(.degrees(self.rotation))
                .animation(.easeInOut(duration: 5))

 

 

 

 

 

6. 스택에 TextField 추가하기

  • 사용자가 입력하는 텍스트가 입력되어 Text 뷰에 표시되도록 구성 → TextField 추가
  • 상태 프로퍼티 추가
struct Chap22: View {
    
    @State private var rotation : Double = 0
    @State private var text : String = "Welcome to SwiftUI"
    
    var body: some View {
        VStack {
            Text(text)
                .font(.largeTitle)
                .fontWeight(.heavy)
                .rotationEffect(.degrees(self.rotation))
                .animation(.easeInOut(duration: 5))
            
            Slider(value: $rotation, in : 0 ... 360, step: 0.1)
            
            TextField("Enter the here", text: $text)
                .textFieldStyle(RoundedBorderTextFieldStyle())
        }
    }
}

→ TextField에 텍스트를 입력하면 text 상태 프로퍼티에 저장되고 바인딩에 의해 Text 뷰에 자동으로 나타남

 

 

 

 

 

 

7. 색상 피커 추가

  • Picker 뷰를 이용하여 Text 뷰의 글자 색상(foreground color)을 사용자가 선택 가능하게 변경
  • 색상 이름 배열 및 색상 객체 배열, 현재의 배열 인덱스를 저장하기 위한 상태 프로퍼티 추가
struct Chap22: View {
    
    var colors : [Color] = [.black, .red, .green, .blue] // 색상 객체 배열
    var colornames = ["Black", "Red", "Green", "Blue"]   // 색상 이름 배열
    
    @State private var colorIndex = 0
    @State private var rotation : Double = 0
    @State private var text : String = "Welcome to SwiftUI"

 

 

 

  • VStack에 Picker 추가
var body: some View {
        VStack {
            Text(text)
                .font(.largeTitle)
                .fontWeight(.heavy)
                .rotationEffect(.degrees(self.rotation))
                .animation(.easeInOut(duration: 5))
            
            Slider(value: $rotation, in : 0 ... 360, step: 0.1)
            
            TextField("Enter the here", text: $text)
                .textFieldStyle(RoundedBorderTextFieldStyle())
            
            Picker(selection: .constant(1), label: Text("Picker")){
                Text("1").tag(1)
                Text("2").tag(2)
            }
        }
    }

 

 

 

 

 

 

  • Picker 뷰는 colorIndex 상태 프로퍼티에서 현재 선택된 것을 저장하고 colorNames 배열에 있는 각각의 색상 이름을 표시되도록 구성해야 함
  • 색상 이름을 표시하는 텍스트 색상이 colors 배열에 있는 해당 색상으로 변경할 것
  • ForEach 문을 사용하여 colorNames 배열에 대한 반복문을 실행하는 이유
    • 배열과 같은 데이터 묶음을 가지고 여러 뷰를 생성하기 위함
VStack {
            Text(text)
                .font(.largeTitle)
                .fontWeight(.heavy)
                .rotationEffect(.degrees(self.rotation))
                .animation(.easeInOut(duration: 5))
                .foregroundColor(self.colors[self.colorIndex])
            
            Slider(value: $rotation, in : 0 ... 360, step: 0.1)
            
            TextField("Enter the here", text: $text)
                .textFieldStyle(RoundedBorderTextFieldStyle())
            
            Picker(selection: $colorIndex, label: Text("Color")){
                ForEach(0 ..< colornames.count){
                    Text(self.colornames[$0])
                        .foregroundColor(self.colors[$0])
                }
            }
        }

 

 

 

 

 

8. 레이아웃 정리하기

  • 여백 추가 → .padding() 수정자 추가
            Slider(value: $rotation, in : 0 ... 360, step: 0.1)
                .padding()
            
            TextField("Enter the here", text: $text)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()
            
            Picker(selection: $colorIndex, label: Text("Color")){
                ForEach(0 ..< colornames.count){
                    Text(self.colornames[$0])
                        .foregroundColor(self.colors[$0])
                }
            }
            .padding()

 

 

 

 

 

  • 뷰들의 간격을 균등하게 설정 → Spacer 뷰 추가
  • Text 뷰 앞 뒤에 Spacer 뷰 추가
VStack {
            Spacer()
            Text(text)
                .font(.largeTitle)
                .fontWeight(.heavy)
                .rotationEffect(.degrees(self.rotation))
                .animation(.easeInOut(duration: 5))
                .foregroundColor(self.colors[self.colorIndex])
            Spacer()
            Slider(value: $rotation, in : 0 ... 360, step: 0.1)
                .padding()
            
            TextField("Enter the here", text: $text)
                .textFieldStyle(RoundedBorderTextFieldStyle())
                .padding()
            
            Picker(selection: $colorIndex, label: Text("Color")){
                ForEach(0 ..< colornames.count){
                    Text(self.colornames[$0])
                        .foregroundColor(self.colors[$0])
                }
            }
            .padding()
        }
  • Spacer 뷰는 가변적인 공간을 제공하므로 레이아웃의 필요에 따라 뷰가 확장되거나 축소됨
  • Spacer 뷰가 스택에 포함된 경우 스택의 축 방향으로 크기가 조절됨

 

 

 

 

  • Text 뷰와 Slider 뷰 사이를 더 명확하게 분리하기 위해 Divider 뷰를 레이아웃에 추가
    	   Spacer()
            Text(text)
                .font(.largeTitle)
                .fontWeight(.heavy)
                .rotationEffect(.degrees(self.rotation))
                .animation(.easeInOut(duration: 5))
                .foregroundColor(self.colors[self.colorIndex])
            Spacer()
            Divider()

→ Divider 뷰를 사용하면 두 뷰 사이가 분리됨을 나타내는 라인을 그림