Library / Press & hold

Hold to record (start / stop)

Voice memo style: press starts recording, release stops it. Each boundary gets its own haptic.

0ms 100ms 200ms 300ms 400ms
Feel
A firm tap at start, a lighter double-tick at stop — two distinguishable bookends.
APIs
.sensoryFeedback(.start / .stop)UIImpactFeedbackGenerator
Minimum OS
iOS 17+ / iOS 13+
Raw .md
SwiftUI (iOS 17+)
import SwiftUI

struct RecordButton: View {
    @State private var isRecording = false

    var body: some View {
        Circle()
            .fill(isRecording ? .red : .gray)
            .frame(width: 72, height: 72)
            .scaleEffect(isRecording ? 1.2 : 1.0)
            .animation(.spring(duration: 0.25), value: isRecording)
            .onLongPressGesture(minimumDuration: 0.1, perform: {}) { pressing in
                isRecording = pressing
                // start/stop your AVAudioRecorder here
            }
            // .start and .stop are semantic activity haptics:
            .sensoryFeedback(trigger: isRecording) { _, recording in
                recording ? .start : .stop
            }
    }
}
UIKit
let startHaptic = UIImpactFeedbackGenerator(style: .medium)
let stopHaptic  = UIImpactFeedbackGenerator(style: .light)

@objc func handlePress(_ gr: UILongPressGestureRecognizer) {
    switch gr.state {
    case .began:
        startHaptic.impactOccurred()
        stopHaptic.prepare()
        // recorder.record()
    case .ended, .cancelled:
        stopHaptic.impactOccurred(intensity: 0.6)
        // recorder.stop()
    default: break
    }
}
Copied