포스트

SwiftUI (2)

Personal Business Card App 만들기

1. 배경색을 추가하자

1
2
3
4
5
6
7
8
9
struct ContentView: View {
    var body: some View {
        ZStack {
            Color(.green)
                .ignoresSafeArea(.all)
            Text("Hello, world!")
        }
    }
}

강의에서는 edgesIgnoringSafeArea를 사용하지만 현재는 Deprecated 되어있으므로 ignoreSafeArea를 사용하자.

2. Text를 변경 하자

1
2
3
4
5
6
7
8
9
10
11
12
struct ContentView: View {
    var body: some View {
        ZStack {
            Color(red: 0.09, green: 0.63, blue: 0.52)
                .ignoresSafeArea(.all)
            Text("Harold Song")
                .font(Font.custom("Pacifico-Regular", size: 40))
                .bold()
                .foregroundStyle(.white)
        }
    }
}

여기서 폰트를 드래그 앤 드롭하여 추가를 했지만 변화가 없다.

CleanShot 2024-09-07 at 06 47 52@2x

이때는 Info.plist 파일을 수정 해줘야 한다.

그런데 보이지 않는다?

참고 하자

CleanShot 2024-09-07 at 06 51 46@2x

그냥 target에서 수정을 하도록 하자.

CleanShot 2024-09-07 at 06 53 30@2x

이렇게 추가를 해주면 된다.

CleanShot 2024-09-07 at 06 54 01@2x

추가한 폰트가 적용이 되었음을 알 수 있다.

3. VStack 추가하기

이건 생략!

추가로 Text를 더 추가하고 싶을때는 엔터치고 바로 적어도 되지만

이렇게 드래그를 해서 추가도 가능하니 알아두자

Sep-07-2024 06-56-03

4. 이미지 추가하고 변경하기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
struct ContentView: View {
    var body: some View {
        ZStack {
            Color(red: 0.09, green: 0.63, blue: 0.52)
                .ignoresSafeArea(.all)
            VStack {
                Image("turtle")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 200.0, height: 150.0)
                    .clipShape(Circle())
                    .overlay(
                        Circle().stroke(.white, lineWidth: 5)
                    )
                
                Text("Harold Song")
                    .font(Font.custom("Pacifico-Regular", size: 40))
                    .bold()
                    .foregroundStyle(.white)
                Text("iOS Developer")
                    .foregroundStyle(.white)
                    .font(.system(size: 25))
            }
        }
    }
}

여기서 clipShape를 하게되면 원이 생긴다.

그리고 stroke property를 통해 테두리 색과, 테두리의 굵기를 설정이 가능하다

1
2
3
4
.clipShape(Circle())
                    .overlay(
                        Circle().stroke(.white, lineWidth: 5)
                    )

5. 구분선 추가하기

Divider()를 사용하여 구분선을 추가해줄것이다.

Challenge 1

CleanShot 2024-09-07 at 07 38 22@2x

다음과 같이 번호를 입력하는 부분을 만들어 보자.

1
2
3
4
5
6
7
8
Divider()  
ZStack {
    RoundedRectangle(cornerRadius: 25)
    .frame(height: 50)
    .foregroundStyle(.white)
    Text("010-1234-5678")
                
}

처음해보는거라 조금 시간이 걸렸다.

나는 위와같이 하였고 강의는 다음과 같이 했다.

1
2
3
4
5
6
7
Divider()
RoundedRectangle(cornerRadius: 25)
    .fill(.white)
    .frame(height: 50)
    .overlay(
        Text("010-1234-5678")
    )

Challenge 2

CleanShot 2024-09-07 at 07 57 09@2x

다음과 같이 전화 이미지와 텍스트를 같이 두기

너무 1차원 적인 생각을 했다.

1
2
3
4
5
6
7
8
9
10
11
12
Divider()
                RoundedRectangle(cornerRadius: 25)
                    .fill(.white)
                    .frame(height: 50)
                    .overlay(
                        HStack {
                            Image(systemName: "phone.fill")
                                .foregroundStyle(.green)
                            Text("010-1234-5678")
                        }
                        
                    )

HStack을 사용하면 되는것이었다.

6. 별도의 View로 코드를 추출하기

RoundedRectangle의 부분을 별도로 추출을 하고 싶을때는

VHZStack을 추가하듯이 컨트롤 클릭을 하여 추출하면 된다.

CleanShot 2024-09-07 at 08 01 06@2x

Sep-07-2024 08-00-12

7. 모듈화 하기

추출한 뷰를 모듈화를 하여 좀 더 관리하기 쉽게 만들어 보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
struct ContentView: View {
    var body: some View {
        ZStack {
            Color(red: 0.09, green: 0.63, blue: 0.52)
                .ignoresSafeArea(.all)
            VStack {
                Image("turtle")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 200.0, height: 150.0)
                    .clipShape(Circle())
                    .overlay(
                        Circle().stroke(.white, lineWidth: 5)
                    )
                
                Text("Harold Song")
                    .font(Font.custom("Pacifico-Regular", size: 40))
                    .bold()
                    .foregroundStyle(.white)
                Text("iOS Developer")
                    .foregroundStyle(.white)
                    .font(.system(size: 25))
                
                Divider()
                InfoView(
                    text: "010-1234-5678", imageName: "phone.fill"
                )
                
            }
        }
    }
}

#Preview {
    ContentView()
}

InfoView.swift 파일을 새로 만들어 주었다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
struct InfoView: View {
    
    let text: String
    let imageName: String
    
    var body: some View {
        RoundedRectangle(cornerRadius: 25)
            .fill(.white)
            .frame(height: 50)
            .overlay(
                HStack {
                    Image(systemName: imageName)
                        .foregroundStyle(.green)
                    Text(text)
                }
                
            )
            .padding(.all)
    }
}

#Preview(traits: .sizeThatFitsLayout) {
    InfoView(text: "hi", imageName: "phone.fill")
}

그리고 sizeThatFitsLayout를 사용하게 되면 폰 베젤에서 렌더링 되지 않고 보이는데 적용이 안된다고 하면

Sep-07-2024 08-15-44

CleanShot 2024-09-07 at 08 17 19@2x

이걸 클릭하자.

8. 모듈화한것을 사용하기

다시 ContentView로 돌아가서

1
2
3
InfoView(
                    text: "dongik369@naver.com", imageName: "envelope.fill"
                )

이걸 추가해주자.

CleanShot 2024-09-07 at 08 18 59@2x

그럼 이렇게 이젠 모듈화가 되어있기에 property만 변경해주면 된다.

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.