2

I need to figure out how to stop a loop. I've tried a couple different kinds of loops, but the end result is the same - the stop button cannot be pressed while the loop is in progress. Here's what I have so far...

var stopButtonPressed = false
var numArray = [0,1,2,3,4,5,6,7,8,9]
for num in numArray{
    print(num)
    sleep(2)
    if stopButtonPressed {
        return
    }
}

Obviously the button pressed sets stopButtonPressed to true, but again... the button can't be pressed while the loop is iterating. So what's a better way to do this?

EDIT

@dasblinkinlight

Ok, so I can follow the logic of what you're saying, but the implementation is still confusing. In your example, for the selector, you put "MyClass.doOneStepOfLoop" and that makes perfect sense. Only the timer is unwilling to accept a function as a parameter. So how can I have it do a step if it won't accept a function?

To simplify the problem, how about we just have it print("1") every two seconds? Based off your example, I would think that would look like this...

self.timer = NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: #selector(print("1")), userInfo: nil, repeats: true)

But this doesn't work and gives the error

Argument of '#selector' does not refer to an initializer or method

I looked through the Q&A you posted as well, and unfortunately I still don't get it. I see lots of pseudo code like "YourClass.doAStep" or "Class.buttonPressed" or "Class.test" in for the selector... could you demonstrate some actual implementation of this?

Adam H
  • 100
  • 2
  • 9

1 Answers1

3

You misunderstand the way Cocoa applications handle events: the app will not respond to events until your method exits.

The proper way to do something every two seconds is to set up a timer, not to use a loop. Change the handler of stop button press to stop the timer:

// This goes into your viewWillAppear
self.timer = NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: #selector(MyClass.doOneStepOfYourLoop), userInfo: nil, repeats: true)

// This goes into your stopButtonPressed handler
self.timer.invalidate()
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Goes into my viewWillAppear? Sorry relatively new to swift. I tried tinkering with the idea above by declaring a var timer = NSTimer() and later on in the for loop, I added the line self.timer = NSTimer.scheduledTimerWithTimeInterval(2, target: self, selector: #selector(print(num)), userInfo: nil, repeats: true) in the for loop. it seems mostly ok with it, except the #selector doesn't want to accept an method as input. What am I doing wrong? – Adam H Aug 14 '16 at 21:12
  • @AdamH There will be no loop at all. Schedule the timer when the view comes up, do the work of loop's body in the timer's handler, and end the timer when the button is pressed or the view disappears. Selector syntax has been changing - here is [relevant Q&A](http://stackoverflow.com/q/24007650/335858). – Sergey Kalinichenko Aug 14 '16 at 23:13
  • 1
    Actually, you can disregard the questions in the edit. I finally get it after watching this video https://www.youtube.com/watch?v=umErDZ8i8Ug – Adam H Aug 15 '16 at 16:04
  • 1
    For the sake of new readers, nowadays we would use [`Timer`](https://developer.apple.com/documentation/foundation/timer) and [`scheduledTimer()`](https://developer.apple.com/documentation/foundation/timer/2091889-scheduledtimer/) – Rob Jun 11 '22 at 14:53