0

I'm discovering issues on attempting to start image slideshow on my app after launching splash screen. For some reason the image slideshow takes too long to start I had to click either previous button or next button or my UISlider to display slideshow then the app crashes. Is there something wrong or missing in my code? The goal is to start image slideshow automatically. Here is my code below. Also, I have a screenshot of how my image slideshow setup in the link below.

Image Slideshow Setup

var Array = [UIImage]()
var counter = 2
var time = Timer()


@IBOutlet weak var menuButton: UIBarButtonItem!
@IBOutlet weak var ImageView: UIImageView!
@IBOutlet weak var Slider1: UISlider!
@IBAction func Slider(_ sender: UISlider) {
    _ = 0
    let value = Int(sender.value)
    ImageView.image = Array[value]
}

@IBAction func NextButton(_ sender: Any) {
    Slider1.value += 1
    ImageView.image = Array[Int(Slider1.value)]
    self.ImageView.animationImages = self.Array
    self.ImageView.animationDuration = 3.0
    self.ImageView.animationRepeatCount = 0
    self.ImageView.startAnimating()

    UIView.transition(with: self.ImageView, duration: 5.0, options: .transitionCrossDissolve, animations: {self.ImageView.image = self.ImageView.image}, completion: nil)

}


@IBAction func PrevButton(_ sender: Any) {
    Slider1.value -= 1
    ImageView.image = Array[Int(Slider1.value)]
    self.ImageView.animationImages = self.Array
    self.ImageView.animationDuration = 3.0
    self.ImageView.animationRepeatCount = 0
    self.ImageView.startAnimating()

    UIView.transition(with: self.ImageView, duration: 5.0, options: .transitionCrossDissolve, animations: {self.ImageView.image = self.ImageView.image}, completion: nil)
}

 //Set Status Bar to light content (white)
override var preferredStatusBarStyle : UIStatusBarStyle {
    return .lightContent
}

override func viewDidLoad() {
    //Set Navigation Bar color Example Home, Back button
    self.navigationItem.backBarButtonItem?.tintColor = UIColor.white;

   time = Timer.scheduledTimer(timeInterval: 5,
                        target: self,
                        selector: #selector(getter: self.Slider1),
                        userInfo: nil,
                        repeats: true)
super.viewDidLoad()

setup()

   Array = [#imageLiteral(resourceName: "MainImage1.jpg"), #imageLiteral(resourceName: "MainImage2.jpg"), #imageLiteral(resourceName: "MainPage3.jpg"), #imageLiteral(resourceName: "MainImage4.jpg"), #imageLiteral(resourceName: "MainImage5.jpg"), #imageLiteral(resourceName: "MainImage6.jpg"), #imageLiteral(resourceName: "MainImage7.jpg"), #imageLiteral(resourceName: "MainImage8.jpg")]

    sideMenus()

    // Do any additional setup after loading the view.
}


override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

func setup(){
self.navigationController?.navigationBar.tintColor = UIColor.white
}

override var prefersStatusBarHidden: Bool{
    return false
}

var navigationBarAppearace = UINavigationBar.appearance()
 override func viewDidAppear(_ animated: Bool){
}



func sideMenus() {

    if revealViewController() != nil {

        menuButton.target = revealViewController()
        menuButton.action = #selector(SWRevealViewController.revealToggle(_:))
        revealViewController().rearViewRevealWidth = 275
        revealViewController().rightViewRevealWidth = 160

        view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
    }
}
    }` 
Mr_Tech
  • 51
  • 7
  • 3
    Unrelated to your question but please note that it is standard practice in Swift to name variables and methods starting with lowercase letters. Classes and structs start with uppercase letters. And it's a really bad idea to name a variable the same as a class. For example, your `Array` variable will be confused with the `Array` class. You really should renamed `Array` to `images` since it is an array of images. – rmaddy Feb 22 '19 at 02:11
  • rmaddy thanks for your reply I was able to rename the Array class to images. Thanks. – Mr_Tech Feb 22 '19 at 10:50

1 Answers1

4

The timer's target selector is the function that gets called on the interval that you specify. In the code above, you're using the getter for your slider property as the function for the timer to call-- that's not doing what you want. The timer is going to call that getter every 5 seconds, but all that getter function does is just "get" the value of the slider property.

You want the timer's selector to do something for you, for example, to trigger the "next" button function. Why not use the form of timer creation that allows you to specify a closure to wrap the behavior? Something like:

time = Timer.scheduledTimer(withTimeInterval: 5, repeats: true) { _ in
    self.NextButton(self)
}

(This seems more elegant in Swift than using a #selector to point to an objc exposed function anyway.)

Ben Zotto
  • 70,108
  • 23
  • 141
  • 204
  • It's best to do `[weak self]` for the timer block. That way the lifecycle of the timer is bound to the lifecycle of the viewcontroller and you don't have to invalidate it manually. For more see [here](https://stackoverflow.com/questions/27416896/what-is-difference-between-self-timer-nil-vs-self-timer-invalidate-in-ios/52544614#52544614). Scroll down to the 'Pro Tip' section – mfaani Jun 24 '19 at 13:40