|
// |
|
// ImageViewer.swift |
|
// voetje |
|
// |
|
// Created by Jonas Everaert on 04/09/2021. |
|
// |
|
// Based on the Lightbox image viewer |
|
// https://github.com/hyperoslo/Lightbox |
|
// |
|
|
|
import SwiftUI |
|
import UIKit |
|
import Lightbox |
|
|
|
enum JOrientation { |
|
case horizontal |
|
case vertical |
|
} |
|
|
|
// MARK: Listener |
|
protocol JDismissalDelegate { |
|
/// Called when the image is dismissed |
|
func imageIsDismissed() |
|
|
|
/// Determines if the `ImageViewer` is visible or not |
|
var showImageViewer: Bool { get set } |
|
/// Determines what page to navigate to when showing a `ImageViewer` |
|
var page: Int? { get set } |
|
} |
|
|
|
// MARK: ImageViewer |
|
private var _isShown = false |
|
private var _delegate: JDismissalDelegate? |
|
|
|
extension UIViewController: LightboxControllerDismissalDelegate { |
|
/// The handler for dismissing the image viewer |
|
/// - seealso: `JDismissalDelegate` for handling (inside the `Image Viewer` |
|
public func lightboxControllerWillDismiss(_ controller: LightboxController) { |
|
// Handler for dismissing the image viewer |
|
_isShown = false |
|
_delegate?.imageIsDismissed() |
|
//_delegate?.showStatusBar = true |
|
} |
|
} |
|
|
|
/// An image viewer with a slide show |
|
struct ImageViewer: UIViewControllerRepresentable { |
|
// TODO: when tapped -> hide the status bar |
|
|
|
/// The images that will be shown in the slide show |
|
public var images: [LightboxImage] = [] |
|
/// depreceted? |
|
public var isShown: Bool { |
|
get { |
|
return _isShown |
|
} |
|
set (val) { |
|
_isShown = val |
|
} |
|
} |
|
/// The delegate for handling the dismissal event |
|
public var delegate: JDismissalDelegate? { |
|
get { |
|
return _delegate |
|
} |
|
set (val) { |
|
_delegate = val |
|
} |
|
} |
|
/// Initialize this variable to navigate to a page |
|
public var page: Int? |
|
|
|
init(images: [LightboxImage], delegate: JDismissalDelegate) { |
|
self.images = images |
|
_delegate = delegate |
|
} |
|
|
|
init(images: [LightboxImage], delegate: JDismissalDelegate, page: Int?) { |
|
self.images = images |
|
_delegate = delegate |
|
self.page = page |
|
} |
|
|
|
init(images imageNames: [String], delegate: JDismissalDelegate, page: Int?) { |
|
for imageName in imageNames { |
|
self.images.append(LightboxImage(image: UIImage(named: imageName)!)) |
|
} |
|
_delegate = delegate |
|
self.page = page |
|
} |
|
init(images: [UIImage], delegate: JDismissalDelegate, page: Int?) { |
|
for image in images { |
|
self.images.append(LightboxImage(image: image)) |
|
} |
|
_delegate = delegate |
|
self.page = page |
|
} |
|
|
|
init(images imageNames: [String]) { |
|
for imageName in imageNames { |
|
self.images.append(LightboxImage(image: UIImage(named: imageName)!)) |
|
} |
|
} |
|
|
|
init(images imageNames: [String], delegate: JDismissalDelegate, page: Int?, imageConfig: [ |
|
JImageConfig]) { |
|
var i = 0 |
|
for imageName in imageNames { |
|
let image: UIImage |
|
if imageConfig[i].editSizeEnabled == true { |
|
// Resize image (adding white space) |
|
image = ImageUtils.getResizedImage(UIImage(named: imageName)!, addToWidth: imageConfig[i].width, addToHeight: imageConfig[i].height) |
|
} else if imageConfig[i].stitchEnabled == true { |
|
// Stitch images together |
|
var _images: [UIImage] = [] |
|
for _imageName in imageConfig[i].images { |
|
_images.append(UIImage(named: _imageName)!) |
|
} |
|
image = ImageUtils.getStitchedImage(_images, orientation: imageConfig[i].orientation!)! |
|
} |
|
else { |
|
// Regular mode |
|
image = UIImage(named: imageName)! |
|
} |
|
self.images.append(LightboxImage(image: image)) |
|
i += 1 |
|
} |
|
_delegate = delegate |
|
self.page = page |
|
} |
|
|
|
func makeUIViewController(context: Context) -> LightboxController { |
|
let controller = LightboxController(images: images) |
|
|
|
// Set delegates. |
|
// controller.pageDelegate = self |
|
controller.dismissalDelegate = controller.self // TODO: handle dismiss |
|
|
|
// Use dynamic background. |
|
controller.dynamicBackground = true |
|
|
|
|
|
|
|
// Go to a page |
|
if page != nil { |
|
controller.goTo(page!) |
|
} |
|
|
|
// Present your controller. |
|
// controller.present(controller, animated: true, completion: nil) |
|
|
|
return controller |
|
} |
|
|
|
func updateUIViewController(_ uiViewController: LightboxController, context: Context) { |
|
// nothing to do here |
|
} |
|
} |
|
|
|
// MARK: Image config |
|
struct JImageConfig { |
|
let editSizeEnabled: Bool |
|
private let _width: CGFloat? |
|
private let _height: CGFloat? |
|
var width: CGFloat? { get { return _width } } |
|
var height: CGFloat? { get { return _height } } |
|
|
|
let stitchEnabled: Bool |
|
let images: [String] |
|
let orientation: JOrientation? |
|
|
|
/** |
|
Edits the height and/or width of the image, added extra white space |
|
*/ |
|
init(edit: Bool?, addToWidth: CGFloat?, addToHeight: CGFloat?) { |
|
self.editSizeEnabled = edit ?? false |
|
self._width = addToWidth |
|
self._height = addToHeight |
|
|
|
self.stitchEnabled = false |
|
self.images = [] |
|
self.orientation = nil |
|
} |
|
|
|
/** |
|
Stitches multiple images together to make one image |
|
*/ |
|
init(stitch: Bool?, images: [String], orientation: JOrientation) { |
|
self.stitchEnabled = stitch ?? false |
|
self.images = images |
|
self.orientation = orientation |
|
|
|
self.editSizeEnabled = false |
|
self._width = nil |
|
self._height = nil |
|
} |
|
|
|
/** |
|
Passes no configuration to `ImageViewer` |
|
*/ |
|
init() { |
|
self.editSizeEnabled = false |
|
self._width = nil |
|
self._height = nil |
|
|
|
self.stitchEnabled = false |
|
self.images = [] |
|
self.orientation = nil |
|
} |
|
} |