watchOS: Complications

Feb 7 2023 · Swift 5.6, watchOS 8.5, Xcode 13

Part 2: Tinted & Custom Complications

11. Build a SwiftUI View for a Complication

Episode complete

Play next episode

Next
About this episode
Leave a rating/review
See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 10. Tint SwiftUI Complications Next episode: 12. Refactor SwiftUI Views

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Transcript: 11. Build a SwiftUI View for a Complication

For most complications, you’ll use the templates you learned about earlier in the course.

Sometimes, however, you’ll want greater control over the design. As you saw with our Happy app, watchOS lets you design some complications with SwiftUI.

Custom graphs are a common and great use case for SwiftUI-based complications.

But we’ll do something a little easier and build a custom complication to show the next calendar entry for the day.

Showing an appointment

Open the CalendarComplication starter project.

EventStore.swift reads the local calendar via EventKit, and EventView.swift, is the view you’ll modify for the complication.

EventView.swift

I already performed the pieces related to EventKit to save you some time.

Your goal is to create a display similar to the one Apple provides for their Calendar app.

Find the “Hello, World!” Text line and replace it with an HStack.

HStack {

}

Draw a rectangle with a small corner radius, so the edges are slightly rounded.

HStack {
  RoundedRectangle(cornerRadius: 3)
}

We can create a rounded vertical line shape if we make it five points wide.

  RoundedRectangle(cornerRadius: 3)
    .frame(width: 5)

To customize the color of the line, EventKit provides the calendar color. It comes packaged as a CGColor, which we can convert to a SwiftUI Color, no problem.

    .frame(width: 5)
    .foregroundColor(Color(event.calendar.cgColor))

Calendar appointments usually show a time range instead of just the start time.

To format the dates, add a new formatter property to the top of the struct, and let the compiler know that it will be a DateIntervalFormatter, specifically.

private let formatter: DateIntervalFormatter = {

}

Now we can create a formatter, and configure it so that it won’t show dates, and will use a short time style, like 2:00 pm.

  let formatter = DateIntervalFormatter()

  formatter.dateStyle = .none
  formatter.timeStyle = .short
  return formatter
// 3
}()

That pattern might look a bit strange to you if you’re new to Swift.

This {…}() is a closure. When you use the parens right at the end like this, Swift runs it, just like it would a function, and then assigns the result to the formatter.

This type of structure lets you perform the necessary configuration for a property right where you declare it.

Now that you’ve got the formatting set up, you show the date exactly as you’d like in the view!

Inside the HStack, after the rectangle, add a VStack. This will look nice if the text is all aligned to the leading side.

// 1
VStack(alignment: .leading) { 

}

At the top, show the date range for the appointment in a .subheadline font for a slightly smaller size.

  Text(formatter.string(from: event.startDate, to: event.endDate))
    .font(.subheadline)

For the event title, use a headline font to make it a little larger than the dates.

  Text(event.title)
    .font(.headline)

Locations are optional, so you only show the location if one is set.

  if let location = event.location {
    Text(location)
      .font(.subheadline)
  }
}

If you have the Canvas displayed, you’ll notice that you don’t see the appointment due to calendar permissions.

I know, that’s terrible, and we’ll get these previews working in the next episode.

But for now, build and run the app on your actual phsyical watch!

When the app first launches, accept calendar permissions.

Then, after a bit, as long as you’ve created an appointment on the local calendar on your iPhone, you’ll see the event: