Created
August 22, 2021 19:19
-
-
Save yccheok/b660cc09b404ae3bab3eb4a586c33cc8 to your computer and use it in GitHub Desktop.
zoomable and swipeable image viewer
This file contains 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
// | |
// MyPaveViewController.swift | |
// zzz | |
// | |
// Created by Yan Cheng Cheok on 22/08/2021. | |
// | |
import UIKit | |
class MyPageViewController: UIPageViewController { | |
let imageNames = [ | |
"0", | |
"1", | |
"2", | |
"3", | |
"4" | |
] | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
dataSource = self | |
delegate = self | |
let imageViewController = ImageViewController() | |
imageViewController.postInit(imageName: "0") | |
setViewControllers([imageViewController], direction: .forward, animated: true, completion: nil) | |
} | |
} | |
extension MyPageViewController: UIPageViewControllerDataSource, UIPageViewControllerDelegate { | |
func pageViewController(_ pageViewController: UIPageViewController, viewControllerBefore viewController: UIViewController) -> UIViewController? { | |
let imageable = viewController as! Imageable | |
let imageName = imageable.imageName | |
let index = imageNames.firstIndex(of: imageName) | |
if let index = index { | |
if index <= 0 { | |
return nil | |
} | |
let imageViewController = ImageViewController() | |
let newIndex = index - 1 | |
imageViewController.postInit(imageName: imageNames[newIndex]) | |
return imageViewController | |
} else { | |
return nil | |
} | |
} | |
func pageViewController(_ pageViewController: UIPageViewController, viewControllerAfter viewController: UIViewController) -> UIViewController? { | |
let imageable = viewController as! Imageable | |
let imageName = imageable.imageName | |
let index = imageNames.firstIndex(of: imageName) | |
if let index = index { | |
if index >= imageNames.count-1 { | |
return nil | |
} | |
let imageViewController = ImageViewController() | |
let newIndex = index + 1 | |
imageViewController.postInit(imageName: imageNames[newIndex]) | |
return imageViewController | |
} else { | |
return nil | |
} | |
} | |
func pageViewController(_ pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [UIViewController], transitionCompleted completed: Bool) { | |
guard let viewControllers = self.viewControllers else { return } | |
guard let imageViewController = viewControllers.first as? ImageViewController else { return } | |
imageViewController.becomeCurrentPage() | |
} | |
} | |
// | |
// ImageViewController.swift | |
// zzz | |
// | |
// Created by Yan Cheng Cheok on 22/08/2021. | |
// | |
import UIKit | |
class ImageViewController: UIViewController, Imageable { | |
var imageName: String { | |
return _imageName | |
} | |
private var _imageName: String! | |
private var firstTime = false | |
private lazy var imageScrollView: ImageScrollView = { | |
let imageScrollView = ImageScrollView() | |
imageScrollView.imageContentMode = .aspectFit | |
imageScrollView.initialOffset = .center | |
return imageScrollView | |
}() | |
func postInit(imageName: String) { | |
self._imageName = imageName | |
} | |
override func viewDidLayoutSubviews() { | |
super.viewDidLayoutSubviews() | |
if firstTime { | |
return | |
} | |
firstTime = true | |
// viewDidLayoutSubviews is the only place where imageScrollView.display will work correctly. | |
imageScrollView.display(image: UIImage(named: imageName)!) | |
} | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
imageScrollView.setup() | |
imageScrollView.translatesAutoresizingMaskIntoConstraints = false | |
self.view.addSubview(imageScrollView) | |
NSLayoutConstraint.activate([ | |
imageScrollView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor), | |
imageScrollView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor), | |
imageScrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor), | |
imageScrollView.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor) | |
]) | |
} | |
func becomeCurrentPage() { | |
// Ensure the image is in zoom-out state. | |
imageScrollView.refresh() | |
} | |
} | |
// | |
// Imageable.swift | |
// zzz | |
// | |
// Created by Yan Cheng Cheok on 22/08/2021. | |
// | |
import Foundation | |
protocol Imageable { | |
var imageName: String { get } | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment