How to animate a text field?

I want to change the content of a text box after a short delay, like this:

  1. do something
  2. set the text box to first result
  3. wait 3 seconds
  4. set the text box to second result
  5. wait 5 seconds
  6. wipe the text box contents

Can we use scheduledTimerWithTimeInterval: for this? And how?
Is there a better way?

Thx

A timer probably makes sense. You could possibly use animation, but I suspect the duration is too long to make it practical.

Ok. Here is my problem: In the following example, the 2 timers are fired at the same time.
Where is my error?

on mainHandler()
	-- some statements…
	
	if badLength = true then
		theAlert's setStringValue:"20 charactères minimum."
		current application's NSTimer's scheduledTimerWithTimeInterval:3 target:me selector:"timerDidFire:" userInfo:(missing value) repeats:false
	end if
	
	if toPasteboard = true then
		theAlert's setStringValue:"Copié dans le presse-papier."
		current application's NSTimer's scheduledTimerWithTimeInterval:3 target:me selector:"timerDidFire:" userInfo:(missing value) repeats:false
	end if
	
end mainHandler

on timerDidFire:theTimer
	theAlert's setStringValue:""
end timerDidFire:

Well you’re passing them the same time interval…

Can’t find a set of intervals that works with this structure of code.
The only way I found to successfully display the 2 strings one after a another is to pass the string as userInfo: and do the umpdate in the selector: handler:

on mainHandler()
	-- some statements…
	
	if badLength = true then
		current application's NSTimer's scheduledTimerWithTimeInterval:0 target:me selector:"timerDidFire:" userInfo:"20 charactères minimum." repeats:false
	end if
	
	if toPasteboard = true then
		set thePlus to (badLength as integer) * 3
		current application's NSTimer's scheduledTimerWithTimeInterval:(0 + thePlus) target:me selector:"timerDidFire:" userInfo:"Copié dans le presse-papier." repeats:false
		current application's NSTimer's scheduledTimerWithTimeInterval:(4 + thePlus) target:me selector:"timerDidFire:" userInfo:"" repeats:false
	end if
end mainHandler

on timerDidFire:theTimer
	set theMess to theTimer's userInfo()
	theAlert's setStringValue:theMess
end timerDidFire:

But the performSelector: method seems to be more accurate in this case: it leaves the timer available for other tasks like faking an idle handler…

 on mainHandler()
	-- some statements…
	
	if badLength = true then
		my performSelector:"alertInWin:" withObject:"20 caractères minimum." afterDelay:0
	end if
	
	if toPasteboard = true then
		set thePlus to (badLength as integer) * 3
		my performSelector:"alertInWin:" withObject:"Copié dans le presse-papier." afterDelay:(0 + thePlus)
		my performSelector:"alertInWin:" withObject:"" afterDelay:(4 + thePlus)
	end if
end mainHandler

on alertInWin:theMess
	theAlert's setStringValue:theMess
end alertInWin:

You could have used different selectors. Anyway, under the hood timers and performSelector::: use the same mechanism.

I had no luck with this: the 2 different handlers were executed at the same time as well.

But they are considered separate tasks? Or will they be in conflict if used in the same script?

Yes but you scheduled them at the same time. Run this in Script Editor, holding down the Control key so it runs in the main thread:

use AppleScript version "2.5" -- macOS 10.11 or later
use framework "Foundation"
use scripting additions

current application's NSTimer's scheduledTimerWithTimeInterval:1 target:me selector:"timerDidFire:" userInfo:(missing value) repeats:false
current application's NSTimer's scheduledTimerWithTimeInterval:5 target:me selector:"timerDidFire2:" userInfo:(missing value) repeats:false

on timerDidFire:theTimer
	display dialog "timerDidFire:" giving up after 2
end timerDidFire:

on timerDidFire2:theTimer
	display dialog "timerDidFire2:" giving up after 2
end timerDidFire2:

Yes. That method essentially just schedules timers on the main thread’s run loop.

There is an important notion that I missed : run loop.
With your help and after a few reading, I’m beginning to understand how it’s working.
I think my error (in the first script) was to execute the setStringValue: method outside of the selector.

Do you agree with that?

The biggest problem I see there is that you gave both timers the same time interval.

@ShaneStanley,

Here is a Xcode project illustrating what I mean.
Could you run it and give me your opinion?
Thanks.

timerTest.zip (37.0 KB)

I’m not sure what you’re asking me. But calls to schedule a time return immediately, so if you want to control when the text changes, it needs to be done in the handler called by the timer.

It’s sometimes difficult for me to understand all the subtleties of AppleScriptObjC…
Thank you for your help.