Library / Drag, swipe & scroll
Pull-to-refresh threshold
The moment a pull gesture crosses the "release to refresh" threshold, plus a success on completion.
import SwiftUI
struct FeedView: View {
@State private var items: [String] = (1...20).map { "Item \($0)" }
@State private var refreshed = 0
var body: some View {
List(items, id: \.self) { Text($0) }
.refreshable {
// The system plays the threshold haptic for .refreshable.
await reload()
refreshed += 1
}
.sensoryFeedback(.success, trigger: refreshed)
}
func reload() async {
try? await Task.sleep(for: .seconds(1))
items.shuffle()
}
} final class FeedViewController: UITableViewController {
private let threshold: CGFloat = -110
private let clickHaptic = UIImpactFeedbackGenerator(style: .rigid)
private var armed = false
override func scrollViewDidScroll(_ scrollView: UIScrollView) {
let pull = scrollView.contentOffset.y + scrollView.adjustedContentInset.top
if pull < threshold && !armed {
armed = true
clickHaptic.impactOccurred() // mechanism engages
} else if pull > threshold * 0.6 && armed && !scrollView.isDragging {
armed = false // re-arm after release
}
}
}