Skip to content

Instantly share code, notes, and snippets.

@magickworx
Created May 19, 2022 13:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save magickworx/4136f18b0c27b9c424e775e9707b1369 to your computer and use it in GitHub Desktop.
Save magickworx/4136f18b0c27b9c424e775e9707b1369 to your computer and use it in GitHub Desktop.
ImageViewer to Display UIImage with SwiftUI (Zoomable)
/*
* FILE: ImageViewer.swift
* DESCRIPTION: AppDevKitSwiftUI: Image Viewer
* DATE: Thu, May 19 2022
* UPDATED: Thu, May 19 2022
* AUTHOR: Kouichi ABE (WALL) / 阿部康一
* E-MAIL: kouichi@MagickWorX.COM
* URL: https://www.MagickWorX.COM/
* COPYRIGHT: (c) 2022 阿部康一/Kouichi ABE (WALL)
* LICENSE: The 2-Clause BSD License (See LICENSE.txt)
*/
import SwiftUI
public struct ImageViewer: View
{
private let image: Image
private let imageWidth: CGFloat
private let imageHeight: CGFloat
public init(uiImage: UIImage) {
self.image = Image(uiImage: uiImage)
self.imageWidth = uiImage.size.width
self.imageHeight = uiImage.size.height
UIScrollView.appearance().bounces = false
}
@State private var currentScale: CGFloat = 1.0
@State private var previousScale: CGFloat = 1.0
private var magnificationGesture: some Gesture {
MagnificationGesture()
.onChanged {
(scale) in
let delta = scale / self.previousScale
self.previousScale = scale
self.currentScale = max(0.5, self.currentScale * delta)
}
.onEnded { _ in
self.previousScale = 1.0
}
}
private var doubleTapGesture: some Gesture {
TapGesture(count: 2)
.onEnded { _ in
self.currentScale = 1.0
self.previousScale = 1.0
}
}
@ViewBuilder
public var body: some View {
GeometryReader {
(geometry) in
let viewWidth = geometry.size.width
let viewHeight = geometry.size.height
let widthFactor = viewWidth / imageWidth
let heightFactor = viewHeight / imageHeight
let scaleFactor = min(widthFactor, heightFactor) * self.currentScale
let width = floor(imageWidth * scaleFactor)
let height = floor(imageHeight * scaleFactor)
ZStack {
Color.black.ignoresSafeArea()
ScrollView([ .horizontal, .vertical ], showsIndicators: false) {
image
.resizable()
.edgesIgnoringSafeArea(.all)
.frame(width: width, height: height)
}
.gesture(magnificationGesture)
.gesture(doubleTapGesture)
}
}
}
}
struct ImageViewer_Previews: PreviewProvider
{
static var previews: some View {
ImageViewer(uiImage: UIImage(named: "azakura")!)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment