-
Haptic FeedbackiOS 2024. 6. 11. 19:30
안녕하세요. 그린입니다 🍏
이번 포스팅에서는 iOS에서 Haptic을 사용하는 방법에 대해 알아보겠습니다 🙋🏻
Haptic Feedback
우선 햅틱 피드백이라는것은 앱을 통한 인터랙션으로 사람들의 촉각을 자극하고 실제 세계에 대한 친숙함을 제공해줄 수 있는 기능입니다.
예를들어, 흔히 많이 사용하는 스위치, 슬라이더, 셀렉션과 같은 컴포넌트들에서 사용자의 반응에 따라 진동이 울리는 햅틱 기능을 통해 확실한 상호작용을 주는것이죠.
특히 요즘에는 VisionOS까지 나왔으니 앱이나 게임 컨트롤러에서 햅틱 피드백이 많이 사용되고 있습니다.
애플에서는 아래와 같이 햅틱 패턴을 올바르게 사용할 수 있도록 몇가지 가이드를 제공하고 있습니다 😃
1️⃣ 시스템에서 제공하는 햅틱 패턴을 적절하게 사용
2️⃣ 앱이나 게임 전반에 걸쳐서 일관되게 햅틱을 사용
3️⃣ 앱이나 게임에서 다른 피드백 (사운드 등)을 보완하기 위해 햅틱을 사용하는것도 권장
4️⃣ 과도한 햅틱 사용 지양
5️⃣ 개별 이벤트를 보완하는 짧은 햅틱 재생을 권장
6️⃣ 햅틱을 선택사항으로 제공
7️⃣ 햅틱 사용 시 다른 사용자 경험에 영향을 미칠 수 있다는점에 유의
7가지 가이드를 가지고 우리 앱에서 적절히 햅틱 피드백을 이용해보는것이 좋습니다.
이제 그럼 애플에서 제공하는 햅틱 피드백은 어떤 타입들이 있고 실제 어떻게 사용할지 알아볼까요?
UIFeedbackGenerator
먼저 햅틱 피드백을 구현하기 위한 가장 최상위 클래스인 UIFeedbackGenerator를 알아봐야 합니다.
해당 클래스는 모든 피드백 생성을 위한 추상 슈퍼 클래스에요.
@MainActor class UIFeedbackGenerator : NSObject
iOS 10 이상부터 사용 가능하니 대부분의 앱에서 제약은 없겠죠?
해당 슈퍼클래스의 서브 클래스로는 4가지가 존재합니다.
1️⃣ UIImpactFeedbackGenerator
2️⃣ UISelectionFeedbackGenerator
3️⃣ UINotificationFeedbackGenerator
4️⃣ UICanvasFeedbackGenerator
해당 서브 클래스들은 모두 UIFeedbackGenerator를 상속 받고 있습니다.
다만 주의할 부분은 햅틱 피드백 구현을 위해 UIFeedbackGenerator를 직접 생성하거나 서브클래싱하지 않는 것입니다.
위 4가지의 구체적인 서브 클래스를 인스턴스로 만들어 사용해야 합니다.
그럼 이제 이 4가지에 대해 하나씩 알아볼께요.
UIImpactFeedbackGenerator
물리적인 충격 효과를 시뮬레이션 하기 위해 햅틱을 생성하는 클래스입니다.
즉, 우리가 대부분 어떤 터치를 통해 기본적인 진동을 구현하는것이 대체적으로 해당 클래스를 사용하죠.
@MainActor class UIImpactFeedbackGenerator : UIFeedbackGenerator
정의는 이러하며 마찬가지로, iOS 10 이상 사용 가능합니다.
해당 피드백을 만드려면 우선 생성을 해야 합니다.
public init(style: UIImpactFeedbackGenerator.FeedbackStyle)
보시는것처럼 FeedbackStyle이 필요합니다.
해당 임팩트 피드백에 대해 5가지 타입을 가지는데요.
heavy / light / medium / rigid / soft를 줄 수 있습니다.
해당 타입에 따라 강도가 달라지죠.
iOS 17.5 부터는 아래와 같이 뷰를 지정해서도 초기화 가능합니다.
convenience init( style: UIImpactFeedbackGenerator.FeedbackStyle, view: UIView )
이렇게 생성된 인스턴스를 아래 메서드로 실제 피드백을 트리거 해줄 수 있습니다.
func impactOccurred()
해당 메서드로 기본적인 트리거로 햅틱을 제공해줄 수 있습니다.
특정 조건에 따라 파마리터를 줄 수 있는데요.
CGFloat 타입의 intensity 인자를 주어 특정 강도로 햅틱을 트리거해줄 수 있으며,
CGPoint 타입의 at 인자로 지정된 위치에서 피드백을 트리거 해줄 수 있습니다.
두 인자 모두 동시 사용도 가능하구요!
UISelectionFeedbackGenerator
해당 클래스는 선택 사항의 변경을 나타내기 위한 햅틱을 생성하는 클래스입니다.
@MainActor class UISelectionFeedbackGenerator : UIFeedbackGenerator
정의는 이러합니다.
즉, 사용자가 예를들어 길게 누르거나 하는 동작에 대한 응답같은것들을 피드백으로 줄 수 있죠.
impact와 다르게 타입을 따로 주는건 없고 해당 선택 피드백을 아래 메서드로 트리거 할 수 있습니다.
func selectionChanged() func selectionChanged(at: CGPoint)
at 인자로 지정된 위치에서 피드백을 트리거할 수 있죠.
UINotificationFeedbackGenerator
성공, 실패 및 경고에 대한 피드백을 전달하기 위한 클래스입니다.
@MainActor class UINotificationFeedbackGenerator : UIFeedbackGenerator
정의는 이러합니다.
즉, 거의 알림과 관련한 피드백으로 사용됩니다.
생성 시 타입은 없으며, 피드백을 트리거하기 위해 아래 메서드를 이용할 수 있습니다.
func notificationOccurred(UINotificationFeedbackGenerator.FeedbackType) func notificationOccurred(UINotificationFeedbackGenerator.FeedbackType, at: CGPoint)
두가지 인자가 존재하는데요.
하나는 피드백 타입입니다.
success / error / warning으로 줄 수 있으며, 각자 타입에 따라 햅틱 강도와 스타일이 다릅니다.
즉, 작업 결과에 따라 적절히 처리해주는것이 좋겠죠!
at 인자는 마찬가지로 트리거되는 위치를 나타내줍니다.
UICanvasFeedbackGenerator
그리기 캔버스에 이벤트를 표시하기 위해 햅틱을 생성하는 클래스입니다.
해당 클래스는 다른 서브 클래스들과 다르게 iOS 17.5 즉, 현재 최신 OS에서 사용 가능합니다.
@MainActor class UICanvasFeedbackGenerator : UIFeedbackGenerator
정의는 이러합니다.
사용 용도는 아이패드와 아이패드 펜슬을 이용하여 캔버스 작업을 할 때 이용될것 같아요.
생성 시 타입은 없고 트리거 사용 시 아래와 같이 이용할 수 있습니다.
// 개체를 안내선이나 눈금자에 맞추는 등 정렬이 발생하는 시기를 나타내기 위해 피드백을 트리거 func alignmentOccurred(at: CGPoint) // 경로 완료 또는 모양 인식을 나타내기 위해 피드백을 트리거 func pathCompleted(at: CGPoint)
두가지가 존재하여 적절한것을 사용하면 됩니다!
이렇게 필요한 해당 UIFeedbackGenerator의 서브 클래스들을 생성하여 트리거를 줌으로 햅틱을 사용할 수 있죠!
이건 SwiftUI나 UIKit이나 로직상에서 다뤄주면 되기에 제약이 없죠.
그런데 SwiftUI 전용으로 iOS 17 이상부터 편하게 사용할 수 있는 뷰 모디파이어가 있습니다.
한번 간단히 알아보시죠 😃
sensoryFeedback
피드백으로 제공된 값이 변경되면 트리거를 재생합니다.
nonisolated func sensoryFeedback<T>( _ feedback: SensoryFeedback, trigger: T ) -> some View where T : Equatable
정의는 이러하며 여기서 피드백 인자는 어떤 유형의 피드백을 재생할지이고 트리거 인자는 재생 시기를 결정하기 위해 상태 변화를 모니터링한다고 보면 됩니다.
struct MyView: View { @State private var showAccessory = false var body: some View { ContentView() .sensoryFeedback(.selection, trigger: showAccessory) .onLongPressGesture { showAccessory.toggle() } if showAccessory { AccessoryView() } } }
즉, 이런식으로 뷰에 붙여서 해당 트리거 인자 상태를 변경해줌으로 사용할 수 있죠.
struct MyView: View { @State private var phase = Phase.inactive var body: some View { ContentView(phase: $phase) .sensoryFeedback(trigger: phase) { old, new in switch (old, new) { case (.inactive, _): return .success case (_, .expanded): return .impact default: return nil } } } enum Phase { case inactive case preparing case active case expanded } }
이렇게 상태 변화에 따라 여러 종류의 트리거를 재생하게 할 수도 있죠!
여기서 Feedback 인자 타입 종류로는 정해진 케이스들이 있습니다.
위에서 다뤘던것처럼 Feedback 타입들이 impact부터 notification에 해당하는것까지 모두 편하게 호출하여 사용할 수 있죠!
또한, 더욱 커스텀도 가능해졌구요.
마무리
이렇게 햅틱 피드백에 대해 알아봤습니다 😃
햅틱을 과도하게 사용해도 안되겠지만, 적절히 필요 시점에 환기나 알림용으로 자극을 준다면 잊지 못할 사용 경험을 줄 수 있을것 같네요 😄
레퍼런스
'iOS' 카테고리의 다른 글
UIScrollView의 contentInsetAdjustmentBehavior (76) 2024.07.18 View Snapshot Capture (55) 2024.06.18 UIPasteboard를 통한 클립보드 사용하기 (66) 2024.05.07 Core Transferable 톺아보기 (62) 2024.04.18 Transferable 찍먹하기 (55) 2024.04.15