소개
Swift에서 진동(Vibration 또는 Haptic)을 구현하는 방법입니다. 진동은 아이폰에서만 지원하고 아이패드나 아이팟 터치에서는 사용할 수 없습니다. 테스트하려면 실제 아이폰 기기가 필요합니다.
기초
아이폰에서 진동을 발생시키는 방법은 크게 3가지가 있습니다. 각 진동은 말로 설명하기는 어려우므로 실제로 체험해보세요(?)
- UINotificationFeedbackGenerator를 사용하는 방법
- 성공(
success), 경고(warning), 에러(error)를 나타낼 때 사용합니다. - 진동이 여러 번 나타납니다.
- 예)
UINotificationFeedbackGenerator().notificationOccurred(.success)
- 성공(
- UIImpactFeedbackGenerator를 사용하는 방법
- 세기에 따라 다르게 단일 신호를 진동시킵니다.
- 종류:
light,medium,heavy+ iOS 13 이상에서soft,rigid - 버튼 등을 눌렀을 때 사용할 수 있습니다.
- 예)
UIImpactFeedbackGenerator(style: .light).impactOccurred()
- UISelectionFeedbackGenerator의 selectionChanged를 사용하는 방법
- 무언가 선택(selection)을 변경했을 때 사용합니다. Apple은 “사용자가 선택하거나 확인할 때 이 피드백을 사용하지 마세요. 선택 항목이 변경될 때만 사용합니다“고 안내하고 있습니다.
- 약한 세기의 단일 진동이 발생합니다.
- 예)
UISelectionFeedbackGenerator().selectionChanged()
- AudioServicesPlaySystemSound를 사용하는 방법 – 옛날 진동 (old school)
- 말 그대로 옛날 핸드폰에서 사용하는 방식의 진동이 발생합니다. 위의 진동들과는 확실이 다른 종류임을 느낄 수 있습니다.
import AVFoundation이 필요합니다.- 예)
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
편리하게 사용하기
아래 코드를 Vibration.swift라는 이름의 파일로 프로젝트에 추가합니다. (출처)
import UIKit
import AVFoundation
enum Vibration: String, CaseIterable {
static var allCases: [Vibration] {
let defaultList = [
error,
success,
warning,
light,
medium,
heavy,
selection,
oldSchool,
]
if #available(iOS 13.0, *) {
return defaultList + [soft, rigid,]
}
return defaultList
}
case error
case success
case warning
case light
case medium
case heavy
case selection
/// 옛 진동 방식
case oldSchool
@available(iOS 13.0, *)
case soft
@available(iOS 13.0, *)
case rigid
public func vibrate() {
switch self {
case .error:
UINotificationFeedbackGenerator().notificationOccurred(.error)
case .success:
UINotificationFeedbackGenerator().notificationOccurred(.success)
case .warning:
UINotificationFeedbackGenerator().notificationOccurred(.warning)
case .light:
UIImpactFeedbackGenerator(style: .light).impactOccurred()
case .medium:
UIImpactFeedbackGenerator(style: .medium).impactOccurred()
case .heavy:
UIImpactFeedbackGenerator(style: .heavy).impactOccurred()
case .soft:
if #available(iOS 13.0, *) {
UIImpactFeedbackGenerator(style: .soft).impactOccurred()
}
case .rigid:
if #available(iOS 13.0, *) {
UIImpactFeedbackGenerator(style: .rigid).impactOccurred()
}
case .selection:
UISelectionFeedbackGenerator().selectionChanged()
case .oldSchool:
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate))
}
}
}
- iOS 13 이상에서 사용하는 프로젝트라면 버전 관련
available부분 및allCases변수를 제거합니다.
사용하고자 하는 곳(예를 들어 버튼을 눌렀을 때 등)에서 다음과 같이 사용합니다.
Vibration.warning.vibrate()
예제: 피커 뷰(Picker View)를 이용해 다양한 종류의 진동 발생시키기
iOS 프로젝트를 생성한 뒤, 메인 화면에 피커 뷰(UIPickerView) 및 버튼을(UIButton)을 추가하고 다음과 같이 IBOutlet 및 IBAction을 뷰 컨트롤러에 연결합니다.

참고) 스위치(
UISwitch)는 기본적으로 값이 변경될 떄마다 진동이 발생하므로 따로 진동을 추가할 필요가 없습니다.Vibration.light와 비슷한 세기의 진동이 발생합니다.
뷰 컨트롤러 코드를 작성합니다.
import UIKit
class ViewController: UIViewController {
@IBOutlet weak var pkvVibrationCategory: UIPickerView!
override func viewDidLoad() {
super.viewDidLoad()
// 피커 뷰 delegate, dataSource
pkvVibrationCategory.delegate = self
pkvVibrationCategory.dataSource = self
}
@IBAction func btnActVibrate(_ sender: Any) {
let index = pkvVibrationCategory.selectedRow(inComponent: 0)
Vibration.allCases[index].vibrate()
}
}
extension ViewController: UIPickerViewDelegate, UIPickerViewDataSource {
func numberOfComponents(in pickerView: UIPickerView) -> Int {
1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
Vibration.allCases.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
Vibration.allCases[row].rawValue
}
}
실제 기기에서 빌드 및 실행합니다. 종류를 선택하고 Vibrate 버튼을 클릭합니다.






0개의 댓글