Paging UIScrollView in increments smaller than frame size
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.
Introduction
UIScrollView's built-in isPagingEnabled snaps to multiples of the scroll view's frame size. To page in smaller increments (such as showing a card carousel where adjacent cards peek from the edges), you must disable isPagingEnabled and implement custom snapping in the scroll view delegate's scrollViewWillEndDragging(_:withVelocity:targetContentOffset:) method. Alternatively, you can use a UICollectionView with UICollectionViewFlowLayout paging behavior or the modern UICollectionViewCompositionalLayout with orthogonal scrolling.
The Problem with Default Paging
With isPagingEnabled = true, the scroll view snaps in increments of 375 points (its frame width). There is no built-in property to change the paging increment.
Custom Paging with Delegate
Disable built-in paging and control snapping manually:
The key is scrollViewWillEndDragging(_:withVelocity:targetContentOffset:) — it lets you modify the target offset before the deceleration animation begins.
Clip-to-Bounds Trick for Peeking Cards
To show adjacent cards peeking from the edges while still using built-in paging:
The scroll view's frame is 295pt wide, so paging snaps in 295pt increments. Setting clipsToBounds = false makes adjacent cards visible beyond the frame edges.
UICollectionView with Custom Paging
UICollectionView provides more structured paging control:
Override targetContentOffset(forProposedContentOffset:withScrollingVelocity:) on the layout to control snapping behavior.
Common Pitfalls
- Leaving
isPagingEnabled = truewith custom snapping: IfisPagingEnabledis true, the scroll view's built-in paging overrides the delegate'stargetContentOffset. Always setisPagingEnabled = falsewhen implementing custom paging logic. - Forgetting
decelerationRate = .fast: Without fast deceleration, the scroll view glides too far after a flick, making custom snapping feel sluggish. Set.fastto match the feel of native paging. - Not handling velocity in the delegate: Without velocity checks, a fast flick may snap to the current page instead of advancing. Check
velocity.xto determine whether the user intended to advance or retreat. - Setting
clipsToBounds = falsewithout handling touches: WhenclipsToBounds = false, content is visible outside the scroll view's frame but taps on that content are not registered. OverridehitTest(_:with:)on the parent view to forward touches to the scroll view. - Incorrect
contentSizecalculation: IfcontentSizedoes not account for spacing between pages, the last page may not be reachable or may snap to the wrong position. Calculate as(pageWidth + spacing) * pageCount.
Summary
isPagingEnabledonly supports paging at the scroll view's frame width — no built-in way to change the increment- Implement custom paging by disabling
isPagingEnabledand usingscrollViewWillEndDragging(_:withVelocity:targetContentOffset:)to snap to custom increments - Use the
clipsToBounds = falsetrick to show peeking adjacent cards with built-in paging on a smaller frame - For collection views, override
targetContentOffset(forProposedContentOffset:withScrollingVelocity:)on a custom flow layout - Always set
decelerationRate = .fastand handle velocity for natural-feeling paging - Forward touches to the scroll view when using
clipsToBounds = falseto keep off-frame content interactive
Related reading
- PANIC Broken AVD system path. Check your ANDROID_SDK_ROOT value
- Parcelable encountered IOException writing serializable object getactivity
- Parse for iOS Errors when trying to run the app
- Parsing HTML into NSAttributedText - how to set font?
- Parsing query strings on Android
- Parsing query strings on Android
- Pass deep link into iOS Simulator?
- Passing an array to a function with variable number of args in Swift
.png&w=3840&q=75)
Tackling System Design Interview Problems
A short course that equips you with the skills to approach system design interviews methodically.
Start the free courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Interview Questions practice on Codemia
Over 8,000 real interview questions from top companies, searchable by company and role.