- Should check this still makes sense. There is a @GestureState thing but I think it was easier not to use that when wanted to have limits.
Created
October 23, 2021 10:50
-
-
Save jamesporter/40fd7eee5fefa6e8da82c1d712be25ea to your computer and use it in GitHub Desktop.
Simple pinch to zoom View extension, allowing for limits to zoom scale
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import SwiftUI | |
| enum Config { | |
| static let zoomRange: ClosedRange<CGFloat> = 0.05...1.0 | |
| } | |
| extension View { | |
| func zoomable(scale: Binding<CGFloat>) -> some View { | |
| ZoomableView(scale: scale) { | |
| self | |
| } | |
| } | |
| } | |
| struct ZoomableView<Child: View>: View { | |
| @Binding var scale: CGFloat | |
| var child: Child | |
| @State private var lastScaleValue: CGFloat = 1.0 | |
| init(scale: Binding<CGFloat>, @ViewBuilder content: () -> Child) { | |
| child = content() | |
| _scale = scale | |
| } | |
| var body: some View { | |
| child.gesture(MagnificationGesture().onChanged { val in | |
| let delta = val / lastScaleValue | |
| // Pain seems like need to save this? | |
| lastScaleValue = val | |
| let newScale = scale * delta | |
| if newScale < Config.zoomRange.lowerBound { | |
| scale = Config.zoomRange.lowerBound | |
| } else if newScale > Config.zoomRange.upperBound { | |
| scale = Config.zoomRange.upperBound | |
| } else { | |
| scale = newScale | |
| } | |
| }.onEnded { val in | |
| lastScaleValue = 1.0 | |
| }) | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment