0
UIView.animateWithDuration(10, delay: 20, options: .TransitionNone, animations: {

    }) { (let finish) in
        print("finish")
    }

Like the code shown, i want to print "finish" after 20 seconds, however i get it immediately.

By the way, how many ways to do make operations delay?

ibirdbluer
  • 38
  • 7
  • I really want to know why animateWithDuration:delay: is useless. I mean, its what the delay parameter do, like the document said: **The amount of time (measured in seconds) to wait before beginning the animations. Specify a value of 0 to begin the animations immediately.** – ibirdbluer Mar 23 '16 at 08:52
  • 1
    i did some testing, and it seems if the animation block is empty, it just jumps to the completion immediately, strange behaviour, but maybe its some kind of optimisation – Fonix Mar 23 '16 at 09:01
  • @Fonix I can confirm that the animation block must not be empty in order to work _as expected_. ;) – CouchDeveloper Mar 23 '16 at 09:27

3 Answers3

3

First Method: NSTimer

func myDelayedFunction() {
    print("delayed")
}

func myMainFunction() {
    let timer = NSTimer.scheduledTimerWithTimeInterval(10, target: self, selector: "myDelayedFunction", userInfo: nil, repeats: false)
    timer.fire()
}

Second Method: performSelector

func myDelayedFunction() {
    print("delayed")
}

func myMainFunction() {
    performSelector("myDelayedFunction", withObject: self, afterDelay: 10)
}

Third Method: GCD (useful if you want an anonymous function) (adapted from this answer)

let delayInSeconds: Int64 = 3
let popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * Int64(NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue()) {
    print("Delayed") 
}

Fourth Method: sleep

func myMainFunction() {
    sleep(10) //This will block whichever thread you're running on.
    print("delayed")
}

I tend to use the first method, because I can always invalidate the timer if I need to (calling timer.invalidate). Each method has its use case, though.

Community
  • 1
  • 1
Quantaliinuxite
  • 2,853
  • 3
  • 14
  • 28
1

if you dont actually need to do any animation, can use GCD to accomplish this

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (Int64)(20 * NSEC_PER_SEC)), dispatch_get_main_queue()){
     print("finish")
};

you can make a neat little helper function as described in this answer as well

Community
  • 1
  • 1
Fonix
  • 10,588
  • 2
  • 41
  • 67
1

I think, there's a misconception. In your code:

UIView.animate(withDuration: 10, delay: 20, options: [], animations: {
    // define animations
    self.myView.alpha = 0  // as an example
}) { (finish) in
    print("finish")
}

the completion handler will be called, when the animation finished. It starts after delay seconds (20.0) and takes duration seconds (10.0). That is, the animation should be completed after 30 seconds measured from the method call.

(You can place NSLog statements in your code to see when things happen)

I cannot reproduce what you are experiencing, that "finish" will be printed immediately. However, I can confirm that UIView.animateWithDuration works as expected - given the animation block is actually not empty.

Karen Hovhannisyan
  • 912
  • 1
  • 17
  • 26
CouchDeveloper
  • 16,175
  • 3
  • 41
  • 59