QuickLook framework is one of the best framework by Apple. It can be used to preview files such as iWork, MS Office, RTF, CSV documents, pdf, text files, Images.
You can use this framework to implement image zooming and sharing feature. We don’t need to write this zooming and sharing code ourself. QuickLook framework provides this all awesome functionality.
Let’s start implementing this powerful and easy framework.
(I have used Swift 3 and XCode 8.3.2)
* Use Single View application template and give a name to your project(App). Select Swift language.
* On Storyboard make your view controller UI like this : Check this image.
Take 2 UIImageViews and take 1 UIButton on each UIImageView. Create necessary IBOutlets and IBActions.
* Your final ViewController Code should look like below.
import UIKit
import QuickLook // Import QuickLook to use it’s functionalities.
let imageURLs = [“https://static2.hdwallpapers.net/wallpapers/2015/03/24/574/thumb_steve-jobs-typographic-portrait.jpg”, “http://www.planetware.com/photos-large/F/france-paris-eiffel-tower.jpg”]
class Downloader { // This is Image Downloader helper class
class func downloadImageWithURL(_ url:String) -> UIImage? {
let data = try? Data(contentsOf: URL(string: url)!)
if let imgData = data {
return UIImage(data: imgData)
}
else {
print(“\n\nThis image url may be wrong : \n \(url)”)
return nil
}
}
}
class iOSConcurrencyViewController: UIViewController, QLPreviewControllerDataSource {
// Connect this 2 imageView outlets with your imageViews.
@IBOutlet weak var imageView1: UIImageView!
@IBOutlet weak var imageView2: UIImageView!
// Connect this outlet with Bar button named – Start
@IBOutlet weak var barButton_Start: UIBarButtonItem!
let quickLookController = QLPreviewController()
var myQLimageURL: URL?
override func viewDidLoad() {
super.viewDidLoad()
// Add QuickLook dataSource to self
quickLookController.dataSource = self
}
@IBAction func didClickOnStart(_ sender: AnyObject) { // Connect this IBAction with Bar button item – Start
// Here we will start downloading images and then disable the start button.
barButton_Start.isEnabled = false
// ################## Dispatch Queues ##################
// Default(System provided) global Dispatch queue
// It can download any image in any order at any time once started.
let imgDownloader_DefaultConcurrentQueue = DispatchQueue.global(qos: .default)
//img1
downloadUsingGCD_AndShowImage(in: imageView1, index: 0, with: imgDownloader_DefaultConcurrentQueue)
//img2
downloadUsingGCD_AndShowImage(in: imageView2, index: 1, with: imgDownloader_DefaultConcurrentQueue)
}
// For GCD – Dispatch Queues
func downloadUsingGCD_AndShowImage(in imageView: UIImageView, index imageIndex: Int, with Queue: DispatchQueue) {
Queue.async { // To avoid blocking UI, download images in background.
let img = Downloader.downloadImageWithURL(imageURLs[imageIndex])
let fileParts = imageURLs[imageIndex].components(separatedBy: “/”)
DispatchQueue.main.async { // UI update code should be on main thread.
imageView.image = img
self.saveImageToDirectory(imageName: fileParts.last!, img: img!)
}
}
}
// You have used a button on each imageView. Give 0 tag for button1 and 1 for button2. Then connect both buttons IBAction to this.
@IBAction func button_ZoomImage_Tapped(_ sender: UIButton) {
var index = Int()
switch sender.tag {
case 0:
index = 0
case 1:
index = 1
default:
break
}
// Get image name with extension from image url
let fileParts = imageURLs[index].components(separatedBy: “/”)
myQLimageURL = getImageFromDirectory(imageName: fileParts.last!)
if let QLImgURL = myQLimageURL {
if QLPreviewController.canPreview(QLImgURL as QLPreviewItem) {
// This line refreshes current preview otherwise you will see only 1 image for both image views.
quickLookController.refreshCurrentPreviewItem()
//navigationController?.pushViewController(quickLookController, animated: true)
present(quickLookController, animated: true, completion: {
print(“completion block”)
})
}
}
}
// Get Documents Directory helper function
func getDocumentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let documentsDirectory = paths[0]
return documentsDirectory
}
// Save Image to Directory
func saveImageToDirectory(imageName: String, img: UIImage) {
//if let image = UIImage(named: imageName) {
if let data = UIImageJPEGRepresentation(img, 0.8) {
let filename = getDocumentsDirectory().appendingPathComponent(imageName)
try? data.write(to: filename)
}
//}
}
// Get Image from Directory
func getImageFromDirectory(imageName: String) -> URL? {
let imageURL = getDocumentsDirectory().appendingPathComponent(imageName)
let imagePath = (getDocumentsDirectory().appendingPathComponent(imageName)).path
if FileManager.default.fileExists(atPath: imagePath) {
return imageURL
}
else {
return nil
}
}
// QuickLook Datasource
func numberOfPreviewItems(in controller: QLPreviewController) -> Int {
return 1 // This will return only 1 image at a time
}
func previewController(_ controller: QLPreviewController, previewItemAt index: Int) -> QLPreviewItem {
return myQLimageURL! as QLPreviewItem
}
Have fun… 🙂
Let me know if you have any queries or problems implementing this feature. Enjoy … 🙂