SwiftUI

SwiftUI Profile View

Daesiker 2021. 3. 30. 17:52
반응형

오늘은 SwiftUI 프레임워크를 이용하여 간단한 Profile UI를 만들 예정이다.

결과

프로필 사진과 사용자에 대한 간단한 정보를 담아주는 Textfield가 있고 오른쪽 상단에는 저장하는 버튼과 삭제하는 버튼을 생성하였다.

State 변수 선언

struct ContentView: View {
    
    @State private var firstName = ""
    @State private var lastName = ""
    @State private var company = ""
    var body: some View {
        
    }
}

우선 TextFiled에 입력된 값을 담는 변수들을 State로 감싸서 선언해주었다. SwiftUI의 컴포넌트는 일반적으로 Struct단위로 구성되어 사용되는데 Struct 내에서는 값이 변경이 될 수없다. 하지만 값이 변경되어야할 상황이 TextField처럼 존재하는데 이때 @State로 변수를 감싸주면 값의 변경을 허용해 준다.

ProfileImage 생성

struct ProfileImage: View {
    var imageName: String
    
    var body: some View {
        Image(imageName)
            .resizable()
            .frame(width: 100, height: 100)
            .clipShape(Circle())
    }
}

imageName이라는 String값을 받아서 imageName이란 이미지가 있으면 이미지로 반환시켜주는 구조체이다. resizable()을 통해 크기조절을 허용한 뒤, 고정된 프레임 값을 받아서 이미지의 크기를 고정시키고 clipShape 속성을 이용해서 Image를 원모양으로 만들어 준다.

NavigationView

struct ContentView: View {
    
    @State private var firstName = ""
    @State private var lastName = ""
    @State private var company = ""
    var body: some View {
        NavigationView {
            
            }
            .navigationTitle("Profile")
    }
}

가장 처음에 View를 NavigationView로 감싸줌으로써 navigation이 가능하도록 만들어 준다. .navigationTitle에 View의 타이틀을 적어준다.

VStack

struct ContentView: View {
    
    @State private var firstName = ""
    @State private var lastName = ""
    @State private var company = ""
    var body: some View {
        NavigationView {
            VStack {
                ProfileImage(imageName: "iu")
                    .padding()
                Form {
                    Section(header: Text("Person Info")) {
                        TextField("First Name", text: $firstName)
                        TextField("Last Name", text: $lastName)
                        TextField("Company", text: $company)
                    }
                }
            }
            .navigationTitle("Profile")
            
        }
    }
}

VStack을 사용하여 컴포넌트 요소들을 세로로 쌓아준다. ProfileImage 컴포넌트의 파라미터인 imageName에 Assets에 있는 이미지 이름을 넣어주면 해당 이미지가 표시된다. Form은 컴포넌트를 담는 공간이다. 컨테이너라고 생각을 하면된다. Form안에 Section 컴포넌트를 통해 TextField가 3개 들어있는 Section을 만들어준다. header 파라미터안에 Section의 제목을 넣으면 된다.

Toolbar

struct ContentView: View {
    
    @State private var firstName = ""
    @State private var lastName = ""
    @State private var company = ""
    var body: some View {
        NavigationView {
            VStack {
                ProfileImage(imageName: "iu")
                    .padding()
                Form {
                    Section(header: Text("Person Info")) {
                        TextField("First Name", text: $firstName)
                        TextField("Last Name", text: $lastName)
                        TextField("Company", text: $company)
                    }
                }
            }
            .navigationTitle("Profile")
            .toolbar {
                ToolbarItemGroup(placement: .navigationBarTrailing)
                {
                    Button {
                        print("Save tapped")
                    } label: {
                        Label("Save", systemImage: "square.and.arrow.down")
                    }
                
                    Button {
                        print("Clear")
                    } label: {
                        Label("Clear", systemImage: "trash")
                    }
                }
            }
        }
    }
}

마지막으로 가장 하단 부분에 toolbar을 넣어서 View에 도구를 넣어준다. .toolbar 속성안에 넣어주면 되고 여러개를 사용할 때는 ToolbarItemGroup을 통해 묶어주면 된다. placement 파라미터는 toolbar의 위치를 결정해준다. .navigationBarTrailing을 넣음으로 써 네비게이션 바 오른쪽에 도구들이 나타난 것을 볼 수 있다.

Full Code

import SwiftUI

struct ContentView: View {
    
    @State private var firstName = ""
    @State private var lastName = ""
    @State private var company = ""
    var body: some View {
        NavigationView {
            VStack {
                ProfileImage(imageName: "iu")
                    .padding()
                Form {
                    Section(header: Text("Person Info")) {
                        TextField("First Name", text: $firstName)
                        TextField("Last Name", text: $lastName)
                        TextField("Company", text: $company)
                    }
                }
            }
            .navigationTitle("Profile")
            .toolbar {
                ToolbarItemGroup(placement: .navigationBarTrailing)
                {
                    Button {
                        print("Save tapped")
                    } label: {
                        Label("Save", systemImage: "square.and.arrow.down")
                    }
                
                    Button {
                        print("Clear")
                    } label: {
                        Label("Clear", systemImage: "trash")
                    }
                }
            }
        }
    }
}

struct ProfileImage: View {
    var imageName: String
    
    var body: some View {
        Image(imageName)
            .resizable()
            .frame(width: 100, height: 100)
            .clipShape(Circle())
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}
반응형

'SwiftUI' 카테고리의 다른 글

SwiftUI Segmented Control  (0) 2021.04.01
SwiftUI Binding, Environment  (0) 2021.03.31
SwiftUI 사진 가져오기(3)  (0) 2021.03.20
SwiftUI 사진 가져오기(2)  (0) 2021.03.19
SwiftUI 사진 가져오기(1)  (2) 2021.03.17