Show Activity Indicator before Segue.

Hello, I have been trying to show the activityIndicator I have set up before the segue to another viewController. When I tap the button for segue, the app gets into the inactive state for at least 5 seconds. I'm aiming to show the activityIndicator before the view freezes. There is no problem with the setup of the activityIndicator. The problem I'm having is the activityIndicator shows up after the segue on the other viewController. Thanks in advance.


import UIKit

class StitchEffectViewController: UIViewController {
 
  //  @IBOutlet weak var activityIndicator: UIActivityIndicatorView!
 
  let stitchPhotoID = "StitchPhotoID"
 
  @IBOutlet weak var tapAboveOutlet: UIButton!
 
  override func viewDidLoad() {
    super.viewDidLoad()
   
    //    activityIndicator.isHidden = true
    //    activityIndicator.hidesWhenStopped = true
   
   
  }
 
  //  override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
  //    super.viewWillTransition(to: size, with: coordinator)
  //
  //    if UIApplication.shared.applicationState == .inactive {
  //      Spinner.update()
  //    }
  //
  //  }
 
  @IBAction func tapAbove(_ sender: UIButton) {
    Spinner.start(style: .large, backColor: UIColor.white, baseColor: UIColor.green)
    spinnerSetup()

  }
 
  func spinnerSetup() {
   
    DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: {
      self.performSegue(withIdentifier: self.stitchPhotoID, sender: nil)
    })
  }
}

Accepted Reply

Problem comes probably from how you defined the segue.

you should not have a segue and an IBAction for the same button.


If so:

- remove the segue from the button

- create a PresentModally segue from the VC (control drag from the button at the top left over the VC view)

- Name it StictchPhotoID

Replies

When I tap the button for segue, the app gets into the inactive state for at least 5 seconds.

Is it what you expect ?

Why such a long freeze ?


I'm aiming to show the activityIndicator before the view freezes. There is no problem with the setup of the activityIndicator.

The problem I'm having is the activityIndicator shows up after the segue on the other viewController.


What is Spinner class ? Is it a class of yours ?

If so, could you show this class ?


What is Spinner.start doing ?

Why do you setup AFTER start ?

You start spinner, then you transition with segue. So spinner continues to show.

If you don't want, you should probably stop Spinner before segue, inside the dispatch.

Hi Claude, yes I expect that because all the photo effects and objc funcs are slowing the app down. Regarding the block, I've been trying to make the activityIndicator(Spinner.start) to show up before the app freezes due to the segue operation. The activityIndicator shows up after the segue on the next viewController making that viewController irresponsive.

import Foundation
import UIKit

open class Spinner {
 
  internal static var spinner: UIActivityIndicatorView?
 
  public static var style: UIActivityIndicatorView.Style = .large
 
  public static var baseBackColor = UIColor(white: 0, alpha: 0.6)
  public static var baseColor = UIColor.red
 
  public static func start(style: UIActivityIndicatorView.Style = style, backColor: UIColor = baseBackColor, baseColor: UIColor = baseColor) {
   
    if spinner == nil, let window = UIApplication.shared.windows.filter({$0.isKeyWindow}).first {
      let frame = UIScreen.main.bounds
      spinner = UIActivityIndicatorView(frame: frame)
      spinner!.backgroundColor = backColor
      spinner!.style = style
      spinner?.color = baseColor
      window.addSubview(spinner!)
      spinner!.startAnimating()
     
//      NotificationCenter.default.addObserver(self, selector: #selector(update), name: NSNotification.Name.AVCaptureDeviceWasDisconnected, object: nil)
    }
  }
 
  public static func stop() {
    if spinner != nil {
      spinner!.stopAnimating()
      spinner!.removeFromSuperview()
      spinner = nil
    }
  }
 
//  @objc public static func update() {
//    if Spinner.spinner != nil {
//      Spinner.stop()
//      Spinner.start()
//    }
//  }
}

Why don't you create the activityIndicator as an IBOutlet in the view ?

I do not see either where you stop animating.


You add the spinner to the window (scene). So it still is visible when you segue.

I first tried with the outlet but the result didn't change. I added the "Spinner.stop()" in "func spinnerSetup()" before the segue. But the outcome remains the same.

import UIKit

class StitchEffectViewController: UIViewController {
 
  //  @IBOutlet weak var activityIndicator: UIActivityIndicatorView!
 
  let stitchPhotoID = "StitchPhotoID"
 
  @IBOutlet weak var tapAboveOutlet: UIButton!
 
  override func viewDidLoad() {
    super.viewDidLoad()
   
    //    activityIndicator.isHidden = true
    //    activityIndicator.hidesWhenStopped = true
   
   
  }
 
  //  override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
  //    super.viewWillTransition(to: size, with: coordinator)
  //
  //    if UIApplication.shared.applicationState == .inactive {
  //      Spinner.update()
  //    }
  //
  //  }
 
  @IBAction func tapAbove(_ sender: UIButton) {
    Spinner.start(style: .large, backColor: UIColor.white, baseColor: UIColor.green)
    spinnerSetup()

  }
 
  func spinnerSetup() {
   
    DispatchQueue.main.asyncAfter(deadline: .now() + 1.0, execute: {
      Spinner.stop()
      self.performSegue(withIdentifier: self.stitchPhotoID, sender: nil)
    })
  }
}

When I tap the button for segue, the app gets into the inactive state for at least 5 seconds.

Then you need to improve the next view controler, to make view transition faster.

You cannot have much control on view updates while segue is ongoing.


In your next view controller, move time-consuming processing to background thread and show activity indicator until such processing is done.

Problem comes probably from how you defined the segue.

you should not have a segue and an IBAction for the same button.


If so:

- remove the segue from the button

- create a PresentModally segue from the VC (control drag from the button at the top left over the VC view)

- Name it StictchPhotoID

Thanks very much Claude.