iOS Metal Tutorial with Swift Part 5: Switching to MetalKit

Learn how to use MetalKit in this 5th part of our Metal tutorial series. By Andrew Kharchyshyn.

Leave a rating/review
Save for later
Share
You are currently viewing page 3 of 3 of this article. Click here to view the first page.

Adding the MTKViewDelegate Protocol

To make your MetalViewController responsible for the draw updates, it must conform to MTKViewDelegate.

Add this extension to the end of the file to implement the protocol methods:

// MARK: - MTKViewDelegate
extension MetalViewController: MTKViewDelegate {
  
  // 1
  func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {
    projectionMatrix = float4x4.makePerspectiveViewAngle(float4x4.degrees(toRad: 85.0), 
      aspectRatio: Float(self.view.bounds.size.width / self.view.bounds.size.height), 
      nearZ: 0.01, farZ: 100.0)
  }
  
  // 2
  func draw(in view: MTKView) {
    render(view.currentDrawable)
  }
  
}

Taking a look at the two protocol methods:

  1. mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) runs whenever the MTKView resizes. Here, you reset the projectionMatrix based on the new size.
  2. draw(in view: MTKView) is called when you need to draw a new frame to the view.

Since you’ve changed the way you call render(), you need to update the method. Find the following code:

func render() {
  if let drawable = metalLayer.nextDrawable() {
    self.metalViewControllerDelegate?.renderObjects(drawable)
  }
}

Then, replace it with this:

func render(_ drawable: CAMetalDrawable?) {
  guard let drawable = drawable else { return }
  self.metalViewControllerDelegate?.renderObjects(drawable)
}

Now that you’re responding to size changes using the delegate, you can remove the viewDidLayoutSubviews() function too.

To connect the view delegate to the view controller, add the following code to the MetalViewController class after the list of properties:

@IBOutlet weak var mtkView: MTKView! {
  didSet {
    mtkView.delegate = self
    mtkView.preferredFramesPerSecond = 60
    mtkView.clearColor = MTLClearColor(red: 0.0, green: 0.0, blue: 0.0, alpha: 1.0)
  }
}

This is a property observer and will connect the view’s delegate to the view controller whenever the outlet is set.

To make the actual connection from the storyboard to the outlet, you need to open up Main.storyboard and have MetalViewController.swift open in the assistant editor. Drag from the unconnected outlet (denoted by the empty circle in the gutter) to the view in the storyboard. When you release, they should be connected:

Outlet to MTKView

All that’s left to do is set the device property of the MTKView. To do that, first find these two lines in viewDidLoad():

device = MTLCreateSystemDefaultDevice()
textureLoader = MTKTextureLoader(device: device)

Below those two lines, add the following line:

mtkView.device = device

Finally, remove the following properties from the top of the class:

var metalLayer: CAMetalLayer! = nil
var timer: CADisplayLink! = nil
var lastFrameTimestamp: CFTimeInterval = 0.0

You’re all done, build and run your app!

IMG_5926 2

The cube still looks exactly like before, but now it’s running on MetalKit! Huzzah!

OK, you might feel a little disappointed because it looks like you ended up right where you started, and that nothing’s changed, right? But don’t fret. Just remember this ancient Chinese proverb: “The journey to Model I/O starts with the single step of porting to MetalKit.” Er, or something like that! :]

Where to Go From Here?

Here is the final example project from this iOS Metal tutorial.

Take a moment to review what you’ve done:

  • You switched to using SIMD’s float4x4.
  • You removed all Objective-C code from the project.
  • You loaded a texture using MTKTextureLoader.
  • You integrated MTKView into the project, removing lots of boilerplate code.
  • And best of all, you didn’t break anything!

You made it! You totally deserve some rest. :]

Feel like you’re up for more Metal? We’re looking to create more Metal tutorials in the future, but in the meantime, be sure to check out some of the great resources below:

Also, tune into the OpenGL ES video tutorials on this site and learn as Ray explains — in depth — how many of these similar concepts work in OpenGL ES.

Thank you for joining me on this tour through Metal. As you can see, it’s a powerful technology that’s relatively easy to implement once you understand how it works.

If you have any questions, comments or Metal discoveries to share, please leave them in the comments below!