Displaying previous image on uiimageview

Viewed 136

I have an app (Swift 5) using a UIImageView and a gesture method to change pictures when touching the image. It works great! The below code cycles thru all 26 pictures and starts over when at the last image. I want to create a button to go back to the previous image - if i was at image 5, how would i go back to image 4?

Global variable set: var number = 1

Gesture method set:

            if segControl.selectedSegmentIndex == 0 && segControl2.selectedSegmentIndex == 0 {
                imageView.image = UIImage(named: "card2")
                imageView.image = UIImage(named: "card\(number)")
                number = number % 26 + 1
            }
            else if segControl.selectedSegmentIndex == 0 && segControl2.selectedSegmentIndex == 1 {
                imageView.image = UIImage(named: "upper2")
                imageView.image = UIImage(named: "upper\(number)")
                number = number % 26 + 1
            }
}
3 Answers

if i was at image 5, how would i go back to image 4?

You could just subtract one from number, but there's a slight complication in that Swift's remainder operator (%) is happy to return a negative number. To make it work more like a modulo operator in other languages, you can add 25 instead of subtracting 1:

number = (number + 25) % 26

That works because (-1 mod 26) is congruent to (25 mod 26), so adding 25 and subtracting 1 are the same thing.

Update: I hadn't noticed that you're counting starting from 1 instead of from 0. I'd still recommend using the method above to cycle through the images, so you're working with the set 0...25 instead of 1...26, and then add an offset (1 in this case) separately to shift the set to match your needs. That way, you're not dealing with some formula that's not easy to understand — it's just plain old modular arithmetic. Keep calculating the index separate from determining the photo number based on that index. Or better, if you can, adjust the numbers you use for the photos to be in the range 0...25. Your future self will thank you.

number = number % 26 + 1 cycles through the numbers in the range 1...26 in increasing order.

To cycle through 1...26 in decreasing order

Replace:

number = number % 26 + 1

with:

number = 26 - (27 - number) % 26

or with:

number = (number + 24) % 26 + 1

In general, the formula to cycle 1...N in reverse is:

number = (number + N - 2) % N + 1

The logic behind this formula is that the modulus function % can return 0, so we always add 1 at the end. So, we subtract 1 by first subtracting 2. We add N so that the value doesn't go negative. Adding N is like adding 0 when modded by N. Doing % N leaves us in the range 0...(N-1), and adding 1 gives us 1...N. Since we subtracted 2 and added 1, the result is subtracting 1.

I have build a simple project for you, which works fine for me, hope this helps to you;

import UIKit
import Photos

class ViewController: UIViewController, UIImagePickerControllerDelegate,UINavigationControllerDelegate {

    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let picker = UIImagePickerController()

    var imageArray: [UIImage] = []
    var photoIndex = 0

    @IBOutlet weak var Billboard: UIImageView!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        picker.delegate = self
        checkPermission()
    }

    @objc  func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {


        if let imageSelected = info[UIImagePickerController.InfoKey.editedImage] as? UIImage {
            imageArray.append(imageSelected)
            print(imageArray.count)
            Billboard.image = imageSelected
        }
        appDelegate.window?.rootViewController!.dismiss(animated: true, completion: nil)

    }

    func checkPermission() {
        let photoAuthorizationStatus = PHPhotoLibrary.authorizationStatus()
        switch photoAuthorizationStatus {
        case .authorized:
            print("Access is granted by user")
        case .notDetermined:
            PHPhotoLibrary.requestAuthorization({
                (newStatus) in
                print("status is \(newStatus)")
                if newStatus ==  PHAuthorizationStatus.authorized {
                    /* do stuff here */
                    print("success")
                }
            })
            print("It is not determined until now")
        case .restricted:
            // same same
            print("User do not have access to photo album.")
        case .denied:
            // same same
            print("User has denied the permission.")
        }
    }

    @IBAction func selectMediaBtnPressed(_ sender: Any) {

        picker.delegate = self
        picker.sourceType = .photoLibrary
        picker.allowsEditing = true
        appDelegate.window?.rootViewController!.present(picker, animated: true, completion: nil)
    }


    @IBAction func nextBtn(_ sender: Any) {
        if imageArray.count != 0 && (photoIndex + 1) < imageArray.count {
            Billboard.image = imageArray[ photoIndex + 1 ]
            photoIndex = photoIndex + 1
        } else if photoIndex == imageArray.count {
            Billboard.image = imageArray.first
            photoIndex = 0
        }
    }

    @IBAction func backBtn(_ sender: Any) {
        if imageArray.count != 0 && (photoIndex - 1 ) >= 0 {
            Billboard.image = imageArray[ photoIndex - 1 ]
            if photoIndex != 0 {
            photoIndex = photoIndex - 1
            }
        }
    }


}

On storyboard i have one UIImageView and 3 buttons.

Related