Adding Undo and Redo support to iOS

People make mistakes. Let’s use allow undoing.

Raul Riera
Jan 27, 2019 · 3 min read

You have accidentally shaken your phone and noticed that little alert screen that says “Undo [something]”. In this story we are going to implement Undo and Redo actions in an iOS app.

By now you are making all your screens using a declarative and functional approach, right? 😉 If not, you can read all about it. Expanding on that approach, we can easily implement undo actions into our app if all our View Controller state is encapsulated like it was demostrated in that article.

Looking at the documentation

When I looked at Undo Manager it appeared like I was going to be dealing with Selectors, old Objective-C API, and whatever else was lurking underneath. I tried to get around this by creating a wrapper struct with some syntactic sugar.

Thankfully, Geoffrey Foster talked me out of it and I end up choosing a better approach. By simply extending to include one more function. Now, taking everything I had in the previous wrapper, all I was left with was this.

Image for post
Image for post
Pretty simple right?

Pretty simple right? To be honest, the biggest issue with writing this short function was embracing the fact that you want to capture your variables inside the closure, while also having it call itself.

Exploring the code

UndoManager works exactly like that. It retains a copy of the data in the closure so you can revert any changes by calling or for that matter. Doing so, executes our callback and recursively calls itself again, but this time with the values inverted. Creating that loop of undo and redo actions that we desire.

Fixing the bug 🙃

There is one issue that you probably spotted by now. If we use reference types, we won’t be maintaining the previous data. Thankfully that is why we have the constraint in the generic type .

By leveraging , we can implement a quick and dirty version of to serialize and deserialze the content of the data, so we can maintain the state.

Image for post
Image for post
Don’t @ me 🙈

This is more like it, now our UndoManager can store and restore the state of any or , and we barely even had to break a sweat writing this.

You can find the source code of this function with a quick implementation into a View Controller in the following link.

Did I miss anything? Get in touch on Twitter: @raulriera

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch

Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore

Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store