SwiftUI + Combine을 이용하여 Fleek Copy app 만들기(4-1)

안녕하세요.

회사일이 바빠.. 근 한달만에 업로드 하네요..

오늘은 인트로 화면이 끝나면 만날 수 있는 home화면을 만들어 보도록 하겠습니다.


먼저 제가 실제 사용하고있는 Fleek의 routine 화면입니다.

IMG_18657079FAF8-1.jpeg

상단 네비게이션 바, 각종 버튼들, 그리고 루틴에 따른 루틴 리스트 등이 노출되어야 겠네요.

Fleek 앱에서는 루틴리스트가 늘어날 경우, 뷰 전체가 스크롤이 되는 형태이기때문에, 일단 똑같이 만들어보도록 하겠습니다.’

먼저 네비게이션바를 만들어보도록 하겠습니다.

navigationBar를 만들려면 NavigationView를 사용해야 합니다.

스크린샷 2023-04-25 오후 10.08.26.png

ios 16이상부터는 NavigationStack과 NavigationSplitView를 사용하라고 되어있지만, 하위버전에서는 여전히 사용해야 하기 때문에 설명은 계속 진행하도록 하겠습니다.

UIKit에서의 NavigationController와 마찬가지로 탐색할 view들을 계층적으로 쌓아 이전,다음으로 이동 처리합니다.


저희는 하단에서 제공되는 function들을 확인할 수 있으며, navigationTitle을 설정해주고, backbutton 노출여부, displayMode에 대한 설정을 제공하네요.

스크린샷 2023-04-25 오후 10.10.02.png

저희가 필요한 부분은, 화면이동이 아닌, navigationTitle입니다.

NavigationView를 이용하여 타이틀을 만들어 보도록 하겠습니다.

import SwiftUI

struct Routine: View {
    var body: some View {
        NavigationView {
            ZStack {
                Text("RoutineView Main")
                    .foregroundColor(.black)
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .navigationTitle(
                Text("FLEEK")
            )
            .navigationBarTitleDisplayMode(.inline))
        }
    }
}

struct Routine_Previews: PreviewProvider {
    static var previews: some View {
        Routine()
    }
}

NavigationView를 사용하여 위와같은 화면을 만들어 보았습니다.

FLEEK이라는 타이틀을 가진 네비게이션 바와, RoutineView Main이라고 써있는 Text가 잘 노출되는지 확인해보도록 하겠습니다.

스크린샷 2023-04-25 오후 10.20.27.png

원하는 대로 네비게이션 바에 FLEEK이라는 타이틀이 노출되고, 화면에는 RoutineView Main이라는 Text가 잘 노출되는걸 확인할 수 있습니다.


저희가 copy해야 할 RoutineView는 상단 타이틀이 빨간색이며, 배경색은 black 입니다.

빨간 타이틀과 black 배경색을 적용해보도록 하겠습니다.

import SwiftUI

struct Routine: View {
    var body: some View {
        NavigationView {
            ZStack {
                Text("RoutineView Main")
                    .foregroundColor(.white)
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .navigationTitle(
                Text("FLEEK")
                    .foregroundColor(.red)
            )
            .navigationBarTitleDisplayMode(.inline)
                .background(.black)
        }
    }
}

struct Routine_Previews: PreviewProvider {
    static var previews: some View {
        Routine()
    }
}

navigationTitle에 들어간 Text view의 foregroundColor에 .red를 적용했고

ZStack의 backgroundColor를 .black으로 설정했습니다.

변경이 잘 되었는지 확인해보겠습니다.

스크린샷 2023-04-25 오후 10.26.05.png

스크린샷 2023-04-25 오후 10.27.32.png


UINavigationBarAppearance

  • UIKit 에 선언되어있는 Appearance를 사용해야 한다고 합니다.

    스크린샷 2023-04-25 오후 10.30.14.png

    • 설명이 정말 깔끔하게 잘 나와있네요. (네비게이션바 모양을 사용자 정의하기 위한 객체)

저희가 필요한건 titleTextAttributes인것 같네요.

NavigationView의 onAppear에 appearance 관련 속성을 적용해주면 될 것 같습니다.

import SwiftUI

struct Routine: View {
    var body: some View {
        NavigationView {
            ZStack {
                Text("RoutineView Main")
                    .foregroundColor(.white)
            }
            .frame(maxWidth: .infinity, maxHeight: .infinity)
            .navigationTitle(
                Text("FLEEK")
                    .foregroundColor(.red)
            )
            .navigationBarTitleDisplayMode(.inline)
                .background(.black)
        }
        .onAppear {
            let appearance = UINavigationBarAppearance()
            appearance.titleTextAttributes = [.foregroundColor : UIColor.red]
            UINavigationBar.appearance().standardAppearance = appearance
            UINavigationBar.appearance().compactAppearance = appearance
        }
    }
}

struct Routine_Previews: PreviewProvider {
    static var previews: some View {
        Routine()
    }
}

onAppear에 appearance관련 속성을 적용해주었습니다.

standardAppearance와 compactAppearance 2가지 속성이 있는걸 볼 수 있는데요. 각각의 속성은 다음과 같습니다.

  • standardAppearance : 표준 높이의 navigationBar의 노출속성
  • compactAppearance : 가로 회전같은 경우에 navigationBar의 height가 compact 해졌을 경우의 노출속성

결과는 아래와 같습니다.

스크린샷 2023-04-25 오후 10.41.37.png

원하는대로 FLEEK 타이틀이 빨간색으로 노출되는것을 확인할 수 있었습니다.

회사가 바빠져서 글 작성이 많이 늦었네요.. 늘 한 단락을 크게 잡다보니, 글 작성에 허들이 더 커지는 것 같습니다.

할 수 있는데까지 하더라도, 작게 쪼개서라도 자주 업로드해보려고 합니다.

다음 시간에는 양쪽에 버튼을 달고, 나머지 main화면을 작성해보도록 하겠습니다.