상세 컨텐츠

본문 제목

[Workout app on Apple Watch] 애플워치 운동 중일 때 보여지는 AOD 화면 커스텀으로 만들어보기

watchOS 캐기

by Atlas 2023. 9. 21. 02:05

본문

728x90
반응형

 시나리오 :  Apple의 Workout 앱에서 운동을 시작하거나 운동을 진행 중일 때 AOD 모드로 돌아가면 현재앱 화면에서 현재 시간만 나오는 화면이 보인다. 이 화면처럼 커스텀하게 만들 수 있는 방법을 찾아보자.
 

Appl의 Workout 실행 중(좌) , 앱 활성화 중 AOD 모드 실행(우)

운동활성화가 되지 않은 상황이라면 사용자가 지정한 AOD로 보이지만 운동 중일 때는 오른쪽 이미지와 같이 AOD 화면이 다르게 표시되고 있는 것을 확인할 수 있다. 
 
HealthKit을 활용한 애플리케이션을 만들 때 어떻게 하면 이와 같은 기능을 구현할 수 있을까?
 
뚜-둥! 
 
ScenePhase 를 사용하면 Scene의 상태를 확인할 수 있다. 
 

@Environment(\.scenePhase) private var scenePhase

 
ScenePhase는 enum으로 background, inactive, active 3가지 case를 확인할 수 있다.

  • background : 화면에 보이지 않는 케이스
  • inactive : 앱이 띄워져(foreground에) 있지만 동작은 일시중지하는 케이스 
  • active : 앱이 띄워져(foreground에) 있고 상호작용을 할 수 있는 케이스 

 

 

사용법

struct MyView: View {
    @ObservedObject var model: DataModel
    @Environment(\.scenePhase) private var scenePhase


    var body: some View {
        TimerView()
            .onChange(of: scenePhase) { phase in
                model.isTimerRunning = (phase == .active)
            }
    }
}

 
간단하게 scenePhase의 enum 값을 비교해서 상태에 따라 화면을 변경할 수 있었다. 
 
전체코드

import SwiftUI
import HealthKit

struct ContentView: View {
    @Environment(\.scenePhase) private var scenePhase
    
    var body: some View {
        if scenePhase == .active {
            VStack {
                Text("Hello, world!")
                Image(systemName: "figure.walk")
                    .imageScale(.large)
                    .padding()
            }
            .padding()
        } else {
            Image(systemName: "figure.walk.motion")
                .imageScale(.large)
                .padding()
        }
    }
}

 
 
다음으로는 onChange를 이용한 방법으로 구현해 보았다. 
isInactivated 변수를 만들어서 추가적인 조건이 필요할 때 간편하게 조건을 확인할 수 있도록 가독성도 고려해 보았다.
 

  .onChange(of: scenePhase) { phase in
        isInactivated = phase == .inactive
    }

 
watchOS 10에서 deprecated 되었다는 워닝 뜨는 것도 깔끔하게 수정해 주었다. 
 

.onChange(of: scenePhase) { oldValue, newValue in
    isInactivated = newValue == .inactive
}

 

전체코드 

import SwiftUI
import HealthKit

struct ContentView: View {
    @Environment(\.scenePhase) private var scenePhase
    @State var isInactivated = true
    
    var body: some View {
        VStack{
        
            if isInactivated {
                Image(systemName: "figure.walk.motion")
                    .imageScale(.large)
                    .padding()
                    .onChange(of: scenePhase) { oldValue, newValue in
                        isInactivated = newValue == .inactive
                    }
            } else {
                Text("Hello, world!")
                Image(systemName: "figure.walk")
                    .imageScale(.large)
                    .padding()
                    .onChange(of: scenePhase) { oldValue, newValue in
                        isInactivated = newValue == .inactive
                    }
                
            }
        }
    }
}

 
 

결과화면

앱 실행 중(ScenePhase가 active일 때)에는 Hello, world!  문구와 이미지(figure.walk)가 표시되고
AOD 모드 즉, ScenePhase가 active 하지 않을 때는 "figure.walk.motion" 이미지로 표기되도록 커스텀할 수 있는 것을 확인해 보았다.
 

 
 

마무리

- watchOS 도 재밌어요! 한번 도전해 보셔요 👍👍👍
 
 
 
깃 레포 :
https://github.com/PotatoArtie/Potato-iOS/tree/master/Labs/Playground/LosingWeight
 
Apple ScenePhase 문서 :
https://developer.apple.com/documentation/swiftui/scenephase

 

ScenePhase | Apple Developer Documentation

An indication of a scene’s operational state.

developer.apple.com

 

반응형

관련글 더보기

댓글 영역