How to write an AppleScript for Keynote that deletes a text box after clicking it?

Is it possible to write an AppleScript for Keynote that will delete a text box after clicking it, changing the look of the box or anything else? I am trying to make a Jeopardy game and want the ability to show what items are still available on the main screen. It seems like this can be done, but I have no programming ability no matter how hard I try to understand it.


Thanks for any help you can give me



[Re-Titled by Moderator]

Original Title: AppleScript for Keynote

Posted on Dec 13, 2025 5:11 PM

Reply
Question marked as Top-ranking reply

Posted on Dec 15, 2025 2:30 PM

OK, I took a run at this and ran into a roadblock...


As I noted in my earlier post, I was thinking to have a background script actively check which slide was currently visible.


I created an Intro slide with all the category and question values, along with 36 slides for the individual questions.

It's easy enough to setup each question value to jump to a corresponding question slide (Format -> Add Link -> Slide -> Slide #n), and I set each of the question slides to jump back to the master (Format -> Add Link -> Slide -> First Slide). This works fine for the basic flow.


I then wrote an AppleScript that starts the presentation and periodically polls to see which slide is currently showing. At the beginning this would be 'Slide 1', and as you click on any question button, Keynote would switch to the corresponding question slide. The script could detect this change and know that we had to change the initial slide to hide the button corresponding to this question. There's some shenanigans involved in tracking this, but it's a solvable problem.


What's not solvable, though, is that Keynote actively prohibits changing slide elements while the presentation is running. Upon changing to a question slide, I try:


					set opacity of shape (current_slide_number) of slide 1 to 0


which should have the effect of hiding the button that linked to this slide. However, Keynote complains:


> You can’t execute the command “set” on a locked iWork document.


Which I'm interpreting as Keynote having locked the slides because a presentation is in flight.


Indeed, I can kind of get around this by editing the script:


					stop
					set opacity of shape (current_slide_number) of slide 1 to 0
					start


which briefly stops the presentation long enough to change the opacity of the relevant button, then start-up again, but this has the annoying (unacceptable? unavoidable?) screen flash as the presentation stops and starts.


I'll keep poking at this, but here's the framework of what I started with as a baseline:


local current_slide_number, previous_slide_number

-- This quick and dirty script assumes the first slide in a presentation
-- has a number of buttons that correspond to slides in the presentation.
--
-- Clicking a button on the first slide jumps to the relevant slide
-- based on matching numbers (e.g. shape 3 will link to slide 3, etc.)
-- and the script hides that button so that it's not available again when
-- the presentation comes back to the intro screen.
-- Note: uses standard Keynote linking to navigate between slides.

tell application "Keynote"
	tell document 1
		set previous_slide_number to 1
		start
		delay 1
		repeat
			set current_slide_number to slide number of (get current slide)
			if current_slide_number is not previous_slide_number then
				-- we changed slide
				if current_slide_number > 1 then
					-- we just changed to a question slide, not back to the first
                     -- Dirty hack to unlock the slide elements
                     stop
					-- this assumes the buttons map to the slides in a n->n order
					-- i.e. button 2 links to slide 2, button 3 -> slide 3, etc.
					set opacity of shape (current_slide_number) of slide 1 to 0
					-- and resume the presenation
                     start
				end if
				set previous_slide_number to current_slide_number
			end if
			
			-- wait a bit before checking again
            delay 2
		end repeat
	end tell
end tell


There might be some way to refine it further via transitions to mask the stop/start, but I'd really like to find a way to edit the first slide while the presentation is running.

2 replies
Question marked as Top-ranking reply

Dec 15, 2025 2:30 PM in response to Camelot

OK, I took a run at this and ran into a roadblock...


As I noted in my earlier post, I was thinking to have a background script actively check which slide was currently visible.


I created an Intro slide with all the category and question values, along with 36 slides for the individual questions.

It's easy enough to setup each question value to jump to a corresponding question slide (Format -> Add Link -> Slide -> Slide #n), and I set each of the question slides to jump back to the master (Format -> Add Link -> Slide -> First Slide). This works fine for the basic flow.


I then wrote an AppleScript that starts the presentation and periodically polls to see which slide is currently showing. At the beginning this would be 'Slide 1', and as you click on any question button, Keynote would switch to the corresponding question slide. The script could detect this change and know that we had to change the initial slide to hide the button corresponding to this question. There's some shenanigans involved in tracking this, but it's a solvable problem.


What's not solvable, though, is that Keynote actively prohibits changing slide elements while the presentation is running. Upon changing to a question slide, I try:


					set opacity of shape (current_slide_number) of slide 1 to 0


which should have the effect of hiding the button that linked to this slide. However, Keynote complains:


> You can’t execute the command “set” on a locked iWork document.


Which I'm interpreting as Keynote having locked the slides because a presentation is in flight.


Indeed, I can kind of get around this by editing the script:


					stop
					set opacity of shape (current_slide_number) of slide 1 to 0
					start


which briefly stops the presentation long enough to change the opacity of the relevant button, then start-up again, but this has the annoying (unacceptable? unavoidable?) screen flash as the presentation stops and starts.


I'll keep poking at this, but here's the framework of what I started with as a baseline:


local current_slide_number, previous_slide_number

-- This quick and dirty script assumes the first slide in a presentation
-- has a number of buttons that correspond to slides in the presentation.
--
-- Clicking a button on the first slide jumps to the relevant slide
-- based on matching numbers (e.g. shape 3 will link to slide 3, etc.)
-- and the script hides that button so that it's not available again when
-- the presentation comes back to the intro screen.
-- Note: uses standard Keynote linking to navigate between slides.

tell application "Keynote"
	tell document 1
		set previous_slide_number to 1
		start
		delay 1
		repeat
			set current_slide_number to slide number of (get current slide)
			if current_slide_number is not previous_slide_number then
				-- we changed slide
				if current_slide_number > 1 then
					-- we just changed to a question slide, not back to the first
                     -- Dirty hack to unlock the slide elements
                     stop
					-- this assumes the buttons map to the slides in a n->n order
					-- i.e. button 2 links to slide 2, button 3 -> slide 3, etc.
					set opacity of shape (current_slide_number) of slide 1 to 0
					-- and resume the presenation
                     start
				end if
				set previous_slide_number to current_slide_number
			end if
			
			-- wait a bit before checking again
            delay 2
		end repeat
	end tell
end tell


There might be some way to refine it further via transitions to mask the stop/start, but I'd really like to find a way to edit the first slide while the presentation is running.

Dec 15, 2025 10:13 AM in response to kspchp

Conceptually that's pretty easy to do in editing mode.


tell application "Keynote"
    -- target the front document
    tell document 1
        -- get the selection
        set selected_objects to (get selection)
		-- make sure we have only 1 item selected
        if (count of selected_objects) is 1 then
		    -- is it a text box?
            -- note use 'shape' instead of 'text item' if you're using shapes rather than text boxes
            if class of item 1 of selected_objects is text item then
				-- if so, delete it (or change its style, etc.)
                delete item 1 of selected_objects
			end if
		end if
	end tell
end tell


But the same does not apply during presentation mode. 'get selection' would not be valid, so there's no way for the script to know what to delete, and there's no trivial way to invoke the script mid-presentation. You could, potentially, assign a keystroke to run the script, but you'd still have the same issue regarding how to identify which item is 'selected' and needs to be deleted.


What your plan really needs is a way to attached the script to each button, so clicking the button invokes the script, but Keynote doesn't allow for that.


I'm trying to think of creative ways to achieve this via transitions or actions, and can't see a path there either.


In the back of my mind I'm thinking of a background script that 'watches' the presentation and somehow tracks which slides have been shown, but it's not quite fully-baked.

How to write an AppleScript for Keynote that deletes a text box after clicking it?

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.