πŸ‘†UIFeedbackGeneratorTutorial ν–…ν‹± λŒ€μž‘μ „

Overview

UIFeedbackGeneratorTutorial-iOS

πŸ‘† UIFeedbackGeneratorTutorial ν–…ν‹± λŒ€μž‘μ „

λ‚΄μš©

  • shake motion 을 μΈμ‹ν•΄μ„œ ν™”λ©΄μ „ν™˜ μ‹œ 진동 μΆ”κ°€

μ‹œμž‘ μ „

apple developer 개발자 λ¬Έμ„œμ—μ„œλŠ” μ•„μ΄ν°μ—μ„œ μ‚¬μš©ν• λ•Œ λŠλ‚„ 수 μžˆλŠ” "λšœλ‘‘" ν˜Ήμ€ "뚝" ν•˜λŠ” μ΄λŸ¬ν•œ 촉각 κ²½ν—˜μ„ haptic 으둜 λͺ…μ‹œν•˜κ³  μžˆλ‹€.

진동기λŠ₯을 μΆ”κ°€ν•˜κΈ° μœ„ν•΄μ„œ ν–…ν‹± κ΄€λ ¨ν•΄μ„œ 곡뢀λ₯Ό ν•˜λ‹€κ°€ ν–…ν‹± νŒ¨ν„΄μ„ μ ‘ν•˜κ³  λ‚΄κ°€ μ›ν•˜λŠ” 진동은 μ—†κ΅¬λ‚˜ 라고 λŠκΌˆλ‹€. κ·Έλž˜λ„ κ³΅λΆ€ν•œκ²Œ μ•„μ‰¬μ›Œμ„œ 남긴닀.

Haptics 와 Vibrate

  • λΉ„λ°€λ²ˆν˜Έ μž…λ ₯ μ‹œ(ex.카카였페이) β†’ ν–…ν‹±
  • μ€‘μš”ν•œ νŒμ—… λ“±μž₯ μ‹œ(ex.μΉ΄μΉ΄μ˜€ν†‘ νμ•Œμ½”λ“œ) β†’ λ°”μ΄λΈŒλ ˆμ΄νŠΈ

πŸ™Œ HIG - Haptics

  • Human Interface Guidelines 의 ν•„μš”ν•œ λ‚΄μš©μ„ μ •λ¦¬ν•΄λ³΄μž. λ¬Έμ„œμ—μ„œ μ—¬λŸ¬ νŒ¨ν„΄μ˜ 진동 λ―Έλ””μ–΄κΉŒμ§€ μ œκ³΅ν•˜λ‹ˆ 더 μžμ„Έν•œ λ‚΄μš©μ€ 링크λ₯Ό ν™•μΈν•΄λ³΄μž.

Haptics

햅틱은 μ‚¬λžŒλ“€μ˜ 촉각에 κ΄€μ—¬ν•˜μ—¬ ν™”λ©΄ μΈν„°νŽ˜μ΄μŠ€μ™€ μƒν˜Έμž‘μš©ν•˜λŠ” κ²½ν—˜μ„ ν–₯μƒμ‹œν‚¨λ‹€. 예λ₯Ό λ“€μ–΄ μ‹œμŠ€ν…œμ€ μ‹œκ° 및 청각 ν”Όλ“œλ°±κ³Ό λ”λΆˆμ–΄ 햅틱을 μž¬μƒν•˜μ—¬ Apple Pay 거래의 확인을 κ°•μ‘° ν‘œμ‹œν•©λ‹ˆλ‹€. λ˜ν•œ picker λ₯Ό μŠ€ν¬λ‘€ν•˜κ±°λ‚˜ switch λ₯Ό ν† κΈ€ν•˜λŠ” 것과 같은 ν„°μΉ˜ 제슀처 및 μƒν˜Έμž‘μš©μ„ κ°•μ‘°ν•  수 μžˆλ‹€. 개발자 지침은 Animation and Haptics λ₯Ό 참쑰해라.

μ§€μ›λ˜λŠ” iPhone λͺ¨λΈμ—μ„œλŠ” μ—¬λŸ¬κ°€μ§€ λ°©λ²•μœΌλ‘œ 앱에 햅틱을 μΆ”κ°€ν•  수 μžˆλ‹€.

μ‹œμŠ€ν…œ 제곡 컨트둀 및 햅틱을 μ‚¬μš©ν•˜λŠ” 경우 iOS λŠ” 강도와 ν”Όλ“œλ°±μ˜ λ™μž‘μ„ κ΄€λ¦¬ν•œλ‹€. 예λ₯Ό λ“€μ–΄ μŠ€μœ„μΉ˜λŠ” λ―Έλ¬˜ν•œ tap 을 μžλ™μœΌλ‘œ μž¬μƒν•˜κ³  "success" notification 에 λŒ€ν•œ feedback generator λŠ” μ•„λž˜μ˜ νŒ¨ν„΄μ„ μž¬μƒν•œλ‹€. μ‚¬λžŒλ“€μ€ μ‹œμŠ€ν…œ μ •μ˜ 햅택을 μΈμ‹ν•˜λ―€λ‘œ λ¬Έμ„œν™”λœ μ˜λ―Έμ— 따라 μ‚¬μš©ν•˜λŠ” 것이 μ€‘μš”ν•˜λ‹€.

(μœ„μ˜ HIG λ¬Έμ„œμ—μ„œλŠ” μ‹€μ œλ‘œ 햅틱을 μ²΄ν—˜ν•΄λ³Ό 수 μžˆλ‹€! κΌ­ λ“€μ–΄κ°€μ„œ 확인해보길 λ°”λž€λ‹€.)

Notification

Notification haptics λŠ” μž‘μ—… λ˜λŠ” μž‘μ—…μ˜ 결과에 λŒ€ν•œ ν”Όλ“œλ°±μ„ μ œκ³΅ν•œλ‹€.

  • λ§ν¬μ—μ„œ μ—¬λŸ¬ νŒ¨ν„΄μ„ 확인할 수 μžˆλ‹€.

Impact

Impact haptics λŠ” μ‹œκ°μ  κ²½ν—˜μ„ λ³΄μ™„ν•˜λŠ”λ° μ‚¬μš©ν•  수 μžˆλŠ” 물리적 메타포λ₯Ό μ œκ³΅ν•œλ‹€. 예λ₯Ό λ“€μ–΄ μ‚¬λžŒλ“€μ€ view κ°€ μ œμžλ¦¬μ— 고정될 λ•Œ 탭을 λŠλΌκ±°λ‚˜ 두 개의 무거운 물체가 μΆ©λŒν•  λ•Œ μΏ΅ μ†Œλ¦¬λ₯Ό λŠλ‚„ 수 μžˆμŠ΅λ‹ˆλ‹€.

  • λ§ν¬μ—μ„œ μ—¬λŸ¬ νŒ¨ν„΄μ„ 확인할 수 μžˆλ‹€.

Selection

Selection haptics λŠ” UI μš”μ†Œμ˜ 값이 λ³€κ²½λ˜λŠ” λ™μ•ˆ ν”Όλ“œλ°±μ„ μ œκ³΅ν•œλ‹€.

  • λ§ν¬μ—μ„œ μ—¬λŸ¬ νŒ¨ν„΄μ„ 확인할 수 μžˆλ‹€.

μ‹œμŠ€ν…œμ—μ„œ μ œκ³΅ν•˜λŠ” 햅틱을 μ‚¬μš©ν•˜λ“  자체적으둜 λ§Œλ“€λ“  μ‚¬λžŒλ“€μ„ λͺ©ν‘œμ—μ„œ λ°©ν•΄ν•˜μ§€ μ•ŠμœΌλ©΄μ„œ μ‚¬μš©μž κ²½ν—˜μ„ ν’λΆ€ν•˜κ²Œ λ§Œλ“œλŠ” λ°©μ‹μœΌλ‘œ 햅틱을 μ‚¬μš©ν•˜λŠ” 것이 μ€‘μš”ν•˜λ‹€.


μ΄ν›„μ˜ HIG λ¬Έμ„œλŠ” haptics 둜 μΈν„°νŽ˜μ΄μŠ€λ₯Ό λ””μžμΈν•˜λŠ” λ‚΄μš©κ³Ό Custom Haptic Patterns λ₯Ό λ§Œλ“œλŠ” λ‚΄μš©μ„ μ œκ³΅ν•œλ‹€.

이제 개발자 λ¬Έμ„œλ₯Ό μ‚΄νŽ΄λ³΄μž!

πŸ™Œ Apple Developer - Animation and Haptics

πŸ“Œ Haptick Feedback

Provide haptic feedback in response to specific types of events.

: The abstract superclass for all feedback generators.

: A concrete UIFeedbackGenerator subclass that creates haptics to simulate physical impacts.

: A concrete UIFeedbackGenerator subclass that creates haptics to communicate successes, failures, and warnings.

: A concrete UIFeedbackGenerator subclass that creates haptics to indicate a change in selection.

πŸ‘ 원리

To use a feedback generator, the following are required:

  1. Instantiating the Generator
  • feedback 을 μƒμ„±ν•˜λ €λ©΄ λ¨Όμ € UIFeedbackGenerator 클래슀의 ꡬ체적인 ν•˜μœ„ν΄λž˜μŠ€(UIImpactFeedbackGenerator, UISelectionFeedbackGenerator, or UINotificationFeedbackGenerator) 쀑 ν•˜λ‚˜λ₯Ό μΈμŠ€ν„΄μŠ€ν™” ν•΄μ•Όν•©λ‹ˆλ‹€.
  1. Preparing the Generator (optional)
  • generator λ₯Ό preparing ν•˜λ©΄μ„œ feedback 을 νŠΈλ¦¬κ±°ν• λ•Œ λŒ€κΈ°μ‹œκ°„μ„ 쀄일 수 μžˆλ‹€. 이것은 μ†Œλ¦¬ λ˜λŠ” μ‹œκ°μ  μ‹ ν˜Έμ™€ λ§€μΉ˜ν• λ•Œ 특히 μ€‘μš”ν•˜λ‹€.
  • generator 의 prepare() λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•˜λ©΄ Taptic Engine 이 μ€€λΉ„μƒνƒœκ°€ λœλ‹€. νŒŒμ›Œλ₯Ό λ³΄μ‘΄ν•˜κΈ° μœ„ν•΄μ„œ Taptic Engine 은 초 λ‹¨μœ„μ˜ 짧은 μ‹œκ°„λ™μ•ˆ 이 μƒνƒœλ₯Ό μœ μ§€ν•˜κ±°λ‚˜ ν”Όλ“œλ°±μ„ νŠΈλ¦¬κ±°ν• λ•ŒκΉŒμ§€ μœ μ§€ν•©λ‹ˆλ‹€.
  • λ§Œμ•½, prepare() λ©”μ„œλ“œλ₯Ό ν˜ΈμΆœν•œ λ‹€μŒ μ¦‰μ‹œ ν”Όλ“œλ°±μ„ νŠΈλ¦¬κ±°ν•˜λ©΄ μ‹œμŠ€ν…œμ€ Taptic Engine 을 μ€€λΉ„λœ μƒνƒœλ‘œ μ „ν™˜ν•  μ‹œκ°„μ΄ μΆ©λΆ„ν•˜μ§€ μ•Šκ³ , μ§€μ—°μ‹œκ°„μ΄ 쀄어듀지 μ•Šμ„ 수 μžˆλ‹€. λ°˜λ©΄μ—, prepare() λ©”μ„œλ“œλ₯Ό λ„ˆλ¬΄ 일찍 ν˜ΈμΆœν•˜λ©΄ ν”Όλ“œλ°±μ„ νŠΈλ¦¬κ±°ν•˜κΈ° 전에 Taptic Engine 은 λ‹€μ‹œ μ‚¬μš©λ˜μ§€ μ•ŠλŠ” μƒνƒœκ°€ λœλ‹€.

(μ•„λž˜μ˜ μ½”λ“œλ₯Ό 보게되면 λ²„νŠΌμ΄ 클릭되기 전에 generator λ₯Ό μ€€λΉ„ν•˜κ³ , μ•‘μ…˜μ΄ 싀행될 λ•Œ νŠΈλ¦¬κ±°ν•˜λŠ” λͺ¨μŠ΅μ„ λ³Ό 수 μžˆλ‹€.)

  1. Triggering Feedback
  • 각 feedback generator ν•˜μœ„ ν΄λž˜μŠ€λŠ” κ³ μœ ν•œ 트리거 방법을 가진닀. 트리거 ν•˜κΈ° μœ„ν•΄μ„œ impactOccurred()selectionChanged(), or notificationOccurred(_:) 을 μ μ ˆν•˜κ²Œ ν˜ΈμΆœν•΄μ•Όν•œλ‹€.
  • 이런 λ©”μ„œλ“œλ“€μ„ ν˜ΈμΆœν•΄λ„ haptic 이 직접 μž¬μƒλ˜μ§€λŠ” μ•ŠλŠ”λ‹€. λŒ€μ‹  μ‹œμŠ€ν…œμ— 이벀트λ₯Ό μ•Œλ¦°λ‹€. 그런 λ‹€μŒ μ‹œμŠ€ν…œμ€ application’s state, amount of bateery power remaining , factors 듀을 기반으둜 haptic 을 μž¬μƒν• μ§€ μ—¬λΆ€λ₯Ό κ²°μ •ν•©λ‹ˆλ‹€.

For example, haptic feedback is currently played only:

  • On a device with a supported Taptic Engine(iPhone 6s μ΄ν›„μ˜ λͺ¨λ“  iPhone 및 Apple watch, MacBook, Trackpad 등에 νƒ‘μž¬λ˜μ–΄μžˆμŒ)
  • When the app is running in the foreground
  • When the System Haptics setting is enabled

  • ν”Όλ“œλ°±μ„ μž¬μƒν• μ§€ 여뢀에 λŒ€ν•΄μ„œ μ‹œμŠ€ν…œμ„ 신뒰해라. μ‘°κ±΄λΆ€λ‘œ ν”Όλ“œλ°±μ„ νŠΈλ¦¬κ±°ν•˜λ € ν•˜μ§€ 말아라.
  1. Releasing the Generator (optional).
  • 더 이상 μ€€λΉ„λœ generator ν•„μš”μ—†μœΌλ©΄ generatro object 의 μ°Έμ‘°λ₯Ό μ œκ±°ν•˜κ³ , μ‹œμŠ€ν…œμ—μ„œ deallocate ν•˜λ„λ‘ ν•œλ‹€. μ΄λ ‡κ²Œ ν•˜λ©΄ Taptic Engine 을 λ‹€μ‹œ μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” μƒνƒœλ‘œ λ§Œλ“€ 수 μžˆλ‹€.

(μ•„λž˜μ˜ μ½”λ“œλ₯Ό 보게되면 ν–…ν‹± λ™μž‘ 이후 λ§ˆμ§€λ§‰μ— generator 에 nil 을 ν• λ‹Ήν•˜μ—¬ ν•΄μ œν•˜λŠ” 것을 λ³Ό 수 μžˆλ‹€.)

  • generator 에 μ•„λ¬΄λŸ° μ°Έμ‘°κ°€ μ—†μœΌλ©΄ μ‹œμŠ€ν…œμ€ deallocate ν•œλ‹€.

πŸ‘ μ‹œμž‘ν•˜κΈ°

  • λͺ¨λ“  햅틱을 μ²΄ν—˜ν•΄λ³΄κΈ° μœ„ν•¨μ΄κΈ° λ•Œλ¬Έμ— κ²½μš°μ— 따라 generator λ₯Ό prepare ν•˜κ±°λ‚˜ release ν•˜λŠ” μ½”λ“œλŠ” 없을 수 μžˆλ‹€.

UINotificationFeedbackGenerator

import UIKit

class ViewController: UIViewController {

    // MARK: - Properties
    
    var notificationFeedbackGenerator: UINotificationFeedbackGenerator?
    // ...
    
    // MARK: - View Life Cycle
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        setNotificationFeedbackGenerator()
    }
    
    // UINotificationFeedbackGenerator action
    @IBAction func touchNotificationSuccessButton(_ sender: Any) {
        notificationFeedbackGenerator?.notificationOccurred(.success)
    }
    
    @IBAction func touchNotificationWarningButton(_ sender: Any) {
        notificationFeedbackGenerator?.notificationOccurred(.warning)
    }
    
    @IBAction func touchNotificationErrorButton(_ sender: Any) {
        notificationFeedbackGenerator?.notificationOccurred(.error)
    }
}

// MARK: - Extensions

extension ViewController {
    /// set UINotificationFeedbackGenerator
    private func setNotificationFeedbackGenerator() {
        notificationFeedbackGenerator = UINotificationFeedbackGenerator()
        notificationFeedbackGenerator?.prepare()
    }
}

UIImpactFeedbackGenerator

import UIKit

class ViewController: UIViewController {

    // MARK: - Properties
    
    // ...
    var impactFeedbackGenerator: UIImpactFeedbackGenerator?
    
    // MARK: - View Life Cycle
    
    override func viewDidLoad() {
        // ...
    }
 
    // UIImpactFeedbackGenerator action
    @IBAction func touchImpactHeavyButton(_ sender: Any) {
        impactFeedbackGenerator = UIImpactFeedbackGenerator(style: .heavy)
        impactFeedbackGenerator?.impactOccurred()

        impactFeedbackGenerator = nil
    }
    
    @IBAction func touchImpactMediumButton(_ sender: Any) {
        impactFeedbackGenerator = UIImpactFeedbackGenerator(style: .medium)
        impactFeedbackGenerator?.impactOccurred()

        impactFeedbackGenerator = nil
    }
    
    @IBAction func touchImpactLightButton(_ sender: Any) {
        impactFeedbackGenerator = UIImpactFeedbackGenerator(style: .light)
        impactFeedbackGenerator?.impactOccurred()

        impactFeedbackGenerator = nil
    }
}

UISelectionFeedbackGenerator

import UIKit

class ViewController: UIViewController {

    // MARK: - Properties

    // ...
    var selectionFeedbackGenerator: UISelectionFeedbackGenerator?
    
    // MARK: - View Life Cycle
    
    override func viewDidLoad() {
        // ..
    }
    
    // UISelectionFeedbackGenerator action
    @IBAction func touchSelectionButton(_ sender: Any) {
        selectionFeedbackGenerator = UISelectionFeedbackGenerator()
        selectionFeedbackGenerator?.selectionChanged()

        selectionFeedbackGenerator = nil
    }
}

λ·°

  • λ²„νŠΌμ„ μƒμ„±ν•΄μ„œ Haptic 을 μ²΄ν—˜ν•  수 μžˆλ„λ‘ ꡬ성


κΉƒν—ˆλΈŒ :

GitHub - hyun99999/UIFeedbackGeneratorTutorial-iOS: πŸ‘† UIFeedbackGeneratorTutorial ν–…ν‹± λŒ€μž‘μ „

GitHub - 28th-SOPT-iOS-CloneCoding/MiraClone-KimHyunGyu: 🧚 μ•„μš” 미라클둠코딩 κΉ€ν˜„κ·œ


μ°Έκ³  :

iOS ) Haptic Feedback

Haptics - User Interaction - iOS - Human Interface Guidelines - Apple Developer

You might also like...
Owner
Hyungyu Kim
λ‚˜λŠ” ν˜„κ·œλ‹€
Hyungyu Kim