We’ve got one important piece missing from our drawing pad implementation. We aren’t storing our drawings, and we can’t see a thumbnail version in the mindmap cell. We’ll fix that up in this episode, with some more help from UIGraphicsImageRenderer.
Model.swift
We’ll start with updating the cell’s model, in CellModel.swift
Just like we did in DrawingPadView, we’ll replace the original drawing with a UIImage.
var drawing: 🟩UIImage?
Adjust the update drawing method the same way.
mutating func update(drawing: 🟩UIImage) {
self.drawing = drawing
}
And the method down in CellStore.
func updateDrawing(cell: Cell, drawing: 🟩UIImage) {
CellView.swift
We’ll need to update the actual cell view, as well.
Down in the body, find the if statement checking for a drawing.
And replace this drawing view, with an Image made from our drawing UIImage.
Image(uiImage: drawing)
DrawingPadView.swift
Back in DrawingPadView.swift, we can uncomment the code in the save button, and because we updated the underlying types and CellStore method, this will just work!
if let cell = cellStore.selectedCell,
let drawing = drawing {
cellStore.updateDrawing(cell: cell, drawing: drawing)
}
ContentView.swift
One more thing, in ContentView.swift, we need to pass the selected cell’s drawing into the drawing pad again.
DrawingPadView(drawing: cellStore.selectedCell?.drawing)
Clean the project and compile it and preview the app. We can tap the drawing button, draw a picture and then save it.
Now, this drawing is huge. We could resize it with SwiftUI modifiers, but as an alternative, I’m going to show you how to render a smaller version of an image.
Model.swift
We’ll start in the model, again. Create a new computed property on Cell for the thumbnail. We’ll return an Image that we’ll create from the resized UIImage. Make sure that there is a drawing image. If there isn’t then just return nil.
var thumbnail: Image? {
guard let drawing = self.drawing else {
return nil
}
}
Now, set up a scaled size:
let thumbnailSize = CGSize(width: drawing.size.width / 6,
height: drawing.size.height / 6)
And create the Image Renderer
let thumbnail = UIGraphicsImageRenderer(size: thumbnailSize).image { context in
}
return Image(uiImage: thumbnail)
Now we can just draw the image into the context, and return the image as a SwiftUI Image
drawing.draw(in: CGRect(origin: .zero, size: thumbnailSize))
We’ve got a thumbnail. We just need to display it in the cell.
CellView.swift
So back in CellView.swift. Just under CellView, open a new extension. Create a new View structure for the Cell thumbnail. Give it size and image properties to define the thumbnail.
extension CellView {
struct Thumbnail: View {
let size: CGSize
let drawing: Image
var body: some View {
}
}
}
And in the body, set up a ZStack to lay the drawing over the system’s current background color.
ZStack {
Color(uiColor: .systemBackground)
drawing
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: size.width, height: size.height)
}
All we have to do now is use this little custom thumbnail view instead of the too-large Image we just put in the cell.
Thumbnail(size: cell.size, drawing: Image(uiImage: drawing))
To stop the thumbnail from leaking out over the side of the cell, we can clip it with the cell’s shape.
.clipShape(cell.shape.shape)
Go back to ContentView.swift and clean and build the project and make sure that it all works in the live preview.
Select a cell and go into the canvas. Draw something. Save it. And there is a nicely sized thumbnail image, cropped to the cell shape!