SwiftUI로 프로필 화면 만들기

 
 
Introduction

  이번 포스팅은 지난번 만들었던 로그인 화면 만들기에 이어 계속 포스팅 하도록 하겠습니다. 아직은 swiftUI를 이용하여 만들 예정이기때문에 내부에 저장관련기능 및 내부 기능연결 등 부분들은 추후에 다듬어 포스팅 할 예정이니 기다려주시기 바랍니다. :)
 
 
 
SwiftUI로 프로필 화면 만들기 프롤로그

 
Balsamiq Mockups를 이용하여 채팅화면UI를 위와 같이 구성을 해보았습니다.기존에 나와있는 카카오와 유사하게 구성하였습니다.  만들어진 결과물은 상위 그림과 다르지만, 기본 툴은 설정하고 진행하시는게 좋겠죠? 
 
#무엇이 필요할까?
  이번에도 만들기 전 무엇이 필요할지 고민해볼까요? 
 
CheckList
  • Image
    • 상단 프로필 및 하단 아이콘 이미지 추가
    • 추가된 이미지의 모양 변경(두근 사각형, 원)
  • TextField
    • 이미지 하단에 글자 추가
  • Button
    • 이미지 및 텍스트에 대해 버튼 기능 추가 
  • Layout
    • 상단과 하단을 분리하기 위한 공간
 
생각보다 간단할 것 같죠? 네, 생각보다 간단합니다. 상위에 작성한 부분은 무엇을 할지에 대해 정리하기위해 적어두었지만, 다른 부분들로 해결가능하니 참고 바랍니다. 
 

 

 

 
결과 및 레이아웃 미리 보기

 
 
결과 화면은 상위 그림과 같습니다. 프로필에 들어가는 이미지는 Apple WWDC에 나온 이미지를 잘라서 사용하였습니다. 그리고 이미지 교체 부분은 향후 Data저장관련 부분을 다루며 포스팅으로 이어질 예정입니다. 여기서는 어떻게 사용자 프로필을 구성하는지에 대해 알아보도록 하겠습니다. 
 
 
이미지 리소스 추가

 
이번에는 프로필을 만들기 위해서 이미지 리소스를 추가해야합니다. Xcode Project 내부 Assets.xcassets 를 선택하면 상위 그림과 같이 나타납니다. 그리고 사용하고자 하는 이미지를 추가하시면 됩니다. 이때, 이미지 파일명은 규칙적으로 변경 후 추가해주시기 바랍니다. 
 
추가된 이미지는 사각형입니다. 하지만, 결과물을 보면 동그란 원으로 나와있죠? 동그란 원 외 타원, 둥근 사각형 등으로도 변경 가능하니 포토샵에서 추가 작업을 하지 않으셔도 됩니다. 
 
사용되는 기본 예제 텍스트 추가

 
가장 먼저 프로필 화면에 보이는 기본적인 텍스트를 아래와 같이 입력해주시기 바랍니다. 
struct ContentView: View {
    
    var ProfileImgName:String = "User_01"
    var nickName:String = "nickName"
    var lastMsg:String = "좋은하루되세요^^"
    
    var body: some View {
          VStack {

            // 향후 작업 추가 공간 

        }
    }
}
 
body는 Vstack{}을 만들어두고 향후 추가되는 작업들은 extension을 이용하여 만들어서 사용할 예정입니다. 
 
 
사용자 프로필 사진 추가하기

 
상위 그림과 같이 프로필 사진을 추가를 하기 위해 아래의 코드와 같이 입력을 하시면 됩니다. 이때, 앞에서 이야기 드린 것과 같이 이미지를 추가하지 않을 경우, 좌측이미지와 같이 동그란 원만 생성되오니 참고 바랍니다. 그리고 추가되는 이미지의 이름 일치해야하는 것은 기본인건 아시죠? 
 
 
body는 아래와 같이 수정을 하시면 됩니다. 
var body: some View {
          VStack {
            UserMainImage
        }
    }
 
그리고 body에 추가되는 UserMainImage는 extension을 이용하여 아래와 같이 사용하시면 됩니다. 
private extension ContentView {
    
    var UserMainImage: some View {
        CircleImage(image: Image(ProfileImgName))
        .offset(y: -130)
        .padding(.bottom, -130)
    }
}
간단하죠? 그리고 UserMainImage는 CircleImage를이용하여 초기화를 해두고 있습니다. CircleImage는 프로필에 들어가는 이미지를 동그란 원으로 만들기위해서 사용하고 있습니다. 소스코드는 아래의 구조체를 참고해주시기 바랍니다. 
 
코드에서는 offset, padding을 이용하여 Y축의 값을 조절하여 이미지를 아래로 옮겼습니다.  그리고 상단에 작성한 ProfileImage이름을 파라미터로 전달한 것이 끝이네요? 그럼 circleImage구조체를 확인해보도록 할까요?
struct CircleImage: View {
    var image: Image
    var imgHW: CGFloat = 300

    var body: some View {
        image
            .resizable()
            .frame(width: imgHW, height: imgHW)
            .clipShape(Circle())
            .overlay(Circle().stroke(Color.white, lineWidth: 3))
            .shadow(radius: 5)
            //.cornerRadius(15)
    }
}
CircleImage 구조체는 프로필 이미지에서 여러번 사용되기 때문에 따로 추출하여 사용합니다. 이미지의 크기를 가장 먼저 변경하기위해서 resizable()을 사용합니다. 그리고 이미지의 크기 조절은 frame()를 사용하시면 됩니다.  그리고 동그란 원을 표현하기위해서 clipShape을 사용하시면 됩니다.  그리고 동그란 원의 주변효과를 위해 overlay 및 shadow를 이용하시면 됩니다. 
 
코드를 변경하였을 때, 어떻게 변화하는지 조금씩 알아보고 넘어가 주시기 바랍니다. 
 
  • 숙제: clipShape함수 내부에 들어가는 도형을 찾아보고, 변경해보세요
 
 
사용자 정보 추가하기

 
이번에는 사용자의 정보를 입력하는 부분을 확인해보도록 하겠습니다. 결과화면을 보면 사용자 정보(닉네임, 남깃말)을 추가하였더니 layout의 위치가 조금 변경되었네요? 혹 원하는 위치가 아닐 경우, 상단 offset을 이용하여 값을 변경해보시기 바랍니다. 
private extension ContentView {
    
    var UserMainImage: some View { // 생략 … }
    
    var UserInfo : some View {
        VStack(alignment: .leading) {
        Text(nickName)
            .font(.title)

        HStack(alignment: .top) {
            Text(lastMsg)
                .font(.subheadline)
            Spacer()
              }
          }
          .padding()
    }
}
 
참고: body에는 UserInfo를 추가해야 결과물이 변경 됩니다. 
  UserInfo를 상위 코드와 같이 작성하였습니다. 눈으로만 봐도 간단한 구조인게 느껴지시죠? Vstack을 이용하여 Text 두개를 입력하시면 끝…!!  그리고 눈치 채셨을지 모르겠지만, 그냥 Text를 연달아 추가하게 되면 덕지덕지 붙어 있어 미관을 찌푸리게 됩니다. 그래서 적절히 spacer()와 padding()을 이용하여 여유공간을 추가해주시면 됩니다. 상단 이미지의 붉은색 공간이 padding을 이용하여 추가한 공간이니 참고 바랍니다. 
 

 

 

 

 
하단 메뉴 추가하기

 
마지막으로 하단 메뉴를 추가하도록 하겠습니다. 상단 사용자 프로필 사진(원)과 크기만 다르고 동일하죠? 그리고 상위 그림에 제가 표기해둔 레이아웃을 보면 HStack, VStack을 이용하여 구성하고 이미지와, Text만을 이용하여 추가하면 될 것 같네요!!?
 
그럼 코드를 확인해보도록 하겠습니다. 
private extension ContentView {

    // 생략

    var BottomMenu : some View {
        HStack{
            BottomMenuUI(ImageName: "User_02", menuName: "menu1")
            BottomMenuUI(ImageName: "User_03", menuName: "menu2")
            BottomMenuUI(ImageName: "User_04", menuName: "menu3")
            BottomMenuUI(ImageName: "User_05", menuName: "menu4")
        }
    }
}
extension을 이용하기때문에 아래에 계속 추가하시면 됩니다. 이번에는 BottomMenuUI를 이용하여 메뉴를 추가할 수 있도록 하였습니다. 
struct BottomMenuUI : View {
    
    var ImageName:String
    var menuName:String
    
    var body : some View {
        VStack{
            CircleImageBtn(image: Image(ImageName))
            Text(menuName)
        }
    }
}
BottomMenuUI는 단순히 작은 그림(원)과 텍스트로 구성된 구조체 입니다. 그리고 이때 사용한 CircleImageBtn은 상위 프로필과 현재 코드가 동일합니다. 코드를 추가 수정하지는 않았지만, 상위 프로필 사진과 동일하게 쓰시지는 않겠죠? 그래서 설명을 위해 따로 코드를 작성하였습니다. 현재 차이점은 이미지의 크기가 다르고 그외에는 동일 합니다. 
struct CircleImageBtn: View {
    var image: Image
    var imgHW: CGFloat = 80

    var body: some View {
        image
            .resizable()
            .frame(width: imgHW, height: imgHW)
            .clipShape(Circle())
            .overlay(Circle().stroke(Color.white, lineWidth: 3))
            .shadow(radius: 5)
            //.cornerRadius(15)
    }
}
이렇게 SwiftUI를 이용하여 사용자 프로필 화면을 만들어보았습니다. 실제 사용하기위해서는 조금 더 다듬어야 하는 부분도 있고, 향후 navigationBar 또는 TabView를 이용하여 화면 전환등이 필요할 것입니다. 그리고 사진 변경하는 기능도 추가해야하고…많죠? 
 
하지만, SwiftUI를 이용하여 인터페이스에 익숙해진 이후, 보이지 않는 코드를 만지는걸 추천드립니다. 
짧은 포스팅은 여기서 마치도록 하겠습니다. 
 
향후 포스팅 예고

 
다음 포스팅은 상위 그림과 같이 친구목록을 SwiftUI를 이용하여 만들 예정입니다. 좌측과 우측 인터페이스가 다르죠? 
좌측은 NavigationBar를 이용하여 만든 최종 결과화면이고, 다음 포스팅은 좌측그림과 같이 리스트만 보이는 화면에 대해 알아보도록 하겠습니다. 
 
잘 따라오고 계시죠~? ^^

 

Reference

 

이 글을 공유하기

댓글(0)

Designed by JB FACTORY