Skip to content

Commit

Permalink
Update for visionOS
Browse files Browse the repository at this point in the history
  • Loading branch information
batanus authored Nov 17, 2023
2 parents 6e7fbf4 + 29a5f27 commit d36020d
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 12 deletions.
31 changes: 24 additions & 7 deletions DMScrollBar/DMScrollBar.swift
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,10 @@ public class DMScrollBar: UIView {
switch (isSignificantVelocity, isOffsetInScrollBounds) {
case (true, true): startDeceleration(withVelocity: velocity)
case (true, false): bounceScrollViewToBoundsIfNeeded(velocity: velocity)
case (false, true): generateHapticFeedback()
case (false, true):
#if !os(visionOS)
generateHapticFeedback()
#endif
case (false, false): bounceScrollViewToBoundsIfNeeded(velocity: .zero)
}
}
Expand All @@ -282,10 +285,14 @@ public class DMScrollBar: UIView {
gestureInteractionStarted()
case .cancelled where panGestureRecognizer?.state.isInactive == true:
gestureInteractionEnded(willDecelerate: false)
#if !os(visionOS)
generateHapticFeedback()
#endif
case .ended, .failed:
gestureInteractionEnded(willDecelerate: false)
#if !os(visionOS)
generateHapticFeedback()
#endif
default: break
}
}
Expand All @@ -294,7 +301,9 @@ public class DMScrollBar: UIView {
let scrollOffset = scrollOffsetFromScrollIndicatorOffset(scrollIndicatorTopConstraint?.constant ?? 0)
updateAdditionalInfoViewState(forScrollOffset: scrollOffset, previousOffset: nil)
invalidateHideTimer()
#if !os(visionOS)
generateHapticFeedback()
#endif
updateScrollIndicatorText(
forScrollOffset: scrollOffset,
previousOffset: nil,
Expand Down Expand Up @@ -326,15 +335,23 @@ public class DMScrollBar: UIView {
}
}

// MARK: - Decelartion & Bounce animations
// MARK: - Deceleration & Bounce animations

private var scale: CGFloat {
#if os(visionOS)
1
#else
UIScreen.main.scale
#endif
}

private func startDeceleration(withVelocity velocity: CGPoint) {
guard let scrollView else { return }
let parameters = DecelerationTimingParameters(
initialValue: scrollIndicatorTopOffset,
initialVelocity: velocity,
decelerationRate: UIScrollView.DecelerationRate.normal.rawValue,
threshold: 0.5 / UIScreen.main.scale
threshold: 0.5 / scale
)

let destination = parameters.destination
Expand Down Expand Up @@ -380,7 +397,7 @@ public class DMScrollBar: UIView {
var previousScrollViewOffsetBounds = self.scrollViewOffsetBounds
var restOffset = scrollView.contentOffset.clamped(to: self.scrollViewOffsetBounds)
let displacement = scrollView.contentOffset - restOffset
let threshold = 0.5 / UIScreen.main.scale
let threshold = 0.5 / scale
var previousSafeInset = scrollView.safeAreaInsets

let parameters = SpringTimingParameters(
Expand Down Expand Up @@ -422,8 +439,8 @@ public class DMScrollBar: UIView {
return 0
}()
if overscroll == 0 { return }
let additionalStiffnes = (overscroll / scrollView.frame.height) * 400
bounce(withVelocity: velocity, spring: Spring(mass: 1, stiffness: 100 + additionalStiffnes, dampingRatio: 1))
let additionalStiffness = (overscroll / scrollView.frame.height) * 400
bounce(withVelocity: velocity, spring: Spring(mass: 1, stiffness: 100 + additionalStiffness, dampingRatio: 1))
}

private func invalidateDecelerateAnimation() {
Expand Down Expand Up @@ -622,7 +639,7 @@ public class DMScrollBar: UIView {
}
}

// MARK: - UIGestureRecognizerDelegateg
// MARK: - UIGestureRecognizerDelegate

extension DMScrollBar: UIGestureRecognizerDelegate {
public func gestureRecognizer(
Expand Down
6 changes: 3 additions & 3 deletions DMScrollBar/DMScrollBarConfiguration.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ extension DMScrollBar {
/// Indicates if scroll view should decelerate when ending scroll bar interaction with velocity
public let shouldDecelerate: Bool

/// Inficator configuration, which is placed on the right side
/// Indicator configuration, which is placed on the right side
public let indicator: Indicator

/// Info label configuration, which appears during indicator scrolling. If nil - the info label will be hidden
Expand Down Expand Up @@ -311,7 +311,7 @@ extension DMScrollBar.Configuration {
/// Indicates maximum width of info label. If nil is passed - the info label will grow maximum to the leading side of the screen
public let maximumWidth: CGFloat?

/// Info label corenrs which should be rounded
/// Info label corners which should be rounded
public let roundedCorners: RoundedCorners

/// Info label show/hide animation settings
Expand All @@ -327,7 +327,7 @@ extension DMScrollBar.Configuration {
/// - backgroundColor: Background color of the info label
/// - textInsets: Indicates text insets from the info label to its background
/// - maximumWidth: Indicates maximum width of info label. If nil is passed - the info label will grow maximum to the leading side of the screen
/// - roundedCorners: Info label corenrs which should be rounded
/// - roundedCorners: Info label corners which should be rounded
/// - animation: Info label show/hide animation settings
/// - accessibilityIdentifier: Accessibility identifier of the info label
public init(
Expand Down
2 changes: 2 additions & 0 deletions DMScrollBar/ScrollBarIndicator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ final class ScrollBarIndicator: UIView {
if scrollBarLabelText == indicatorLabel?.text { return }
indicatorLabel?.setup(text: scrollBarLabelText, direction: direction)
indicatorImageLabelStackView.layoutIfNeeded()
#if !os(visionOS)
generateHapticFeedback(style: .light)
#endif
}

// MARK: - Private
Expand Down
2 changes: 2 additions & 0 deletions DMScrollBar/ScrollBarInfoView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ final class ScrollBarInfoView: UIView {
if text == offsetLabel.text { return }
offsetLabel.setup(text: text, direction: direction)
layoutIfNeeded()
#if !os(visionOS)
generateHapticFeedback(style: .light)
#endif
}
}
1 change: 1 addition & 0 deletions DMScrollBar/Utils/ConvenienceFunctions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ func setupConstraint(constraint: inout NSLayoutConstraint?, build: ((CGFloat) ->
setupConstraint(constraint: &constraint, build: build, value: value, priority: priority)
}

@available(visionOS, unavailable)
func generateHapticFeedback(style: UIImpactFeedbackGenerator.FeedbackStyle = .heavy) {
UIImpactFeedbackGenerator(style: style).impactOccurred()
}
8 changes: 6 additions & 2 deletions DMScrollBar/Utils/UIScrollView+Utils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,13 @@ private enum AssociatedKeys {
public extension UIScrollView {
var scrollBar: DMScrollBar? {
get {
objc_getAssociatedObject(self, &AssociatedKeys.scrollBar) as? DMScrollBar
withUnsafePointer(to: &AssociatedKeys.scrollBar) {
objc_getAssociatedObject(self, $0) as? DMScrollBar
}
} set {
objc_setAssociatedObject(self, &AssociatedKeys.scrollBar, newValue, .OBJC_ASSOCIATION_ASSIGN)
withUnsafePointer(to: &AssociatedKeys.scrollBar) {
objc_setAssociatedObject(self, $0, newValue, .OBJC_ASSOCIATION_ASSIGN)
}
}
}

Expand Down

0 comments on commit d36020d

Please sign in to comment.