One of the core features of Retrospective Timelines is the ability to share an Event as an image. I’m working in SwiftUI on this project so my first attempt was to see if I could render SwiftUI views as images. Last June Erica Sadun wrote a post about rendering SwiftUI on macOS Mojave that gave me some ideas to try. There is some sample code in that post that renders a UIView as an image, but the view is hosting SwiftUI views in the first place. I tried to adapt this to my needs in the app, but I quickly ran into issues.
First, I couldn’t find a way to make SwiftUI/iOS render view content that was not on screen. If I wanted to make a large resolution image I would need to scale it to fit on screen on an iOS device in order to save it as an image. Second, scaling the image in this manner introduced all sorts of scaling artifacts. The backgrounds look OK but the text was awful.
The next I thing I tried ended up being my “good enough” solution. I rendered a UIView offscreen with all of the text views manually positioned and added to this view.
Content View contains a simple UI. At the top is an Image view that is showing a live preview of the final image that we are rendering and sharing. There is a text field to enter a string of text and a simple color picker object in a scroll view. The function called `createViewToRender()` is doing most of the work here. I create some views, position them, and add them to a parent object.
There are a couple utility code snippets that make help out the content view.
The color view as a flattened version of the one I’m using in the Timeline picker. This control just using a @Binding string variable where the string is the name of a color asset.
I’m sure there are better ways to handle a feature like this, but this approach is fine for now. There are a number of changes I’d like to make in future versions.
- Dynamic text / auto-layout. Currently the text views are manually positioned and sized around a simple layout, but this does not allow for different fonts and sizes.
- It might be interesting to offer some gradients in addition to the colors
- I’d like to add some decorations such as patterns or simple images that can make the images more interesting.