TipKit is a new framework introduced in iOS 17 that allows developers to create and display tips within their apps. Hints help highlight new, interesting, or hidden features that users might not discover on their own. In this article, you will learn how to use his TipKit with his SwiftUI, a modern declarative UI framework for iOS.
To create a tip using TipKit, you must employ the Tip protocol, which defines the content and appearance of a tip. A tip consists of a title, an optional message, and an optional image. For example, let’s say you want to create a feature tip that allows users to save photos as favorites. You can define a struct that conforms to the Tip protocol as follows:
struct FavoriteTip: Tip {
var title: Text {
Text("Save the photo as favorite")
}var message: Text? {
Text("Your favorite photos will appear in the favorite folder.")
}
var image: Image? {
Image(systemName: "heart")
}
}
You can use any SwiftUI view for the title, message, and image properties as long as it complies with the View protocol. The Tip protocol also has several optional properties that you can use to customize the tip’s appearance and behavior, including background color, text color, font, alignment, and padding. For more information about the Tip protocol, please refer to the official documentation.
TipKit offers two ways to display tips in your app: inline view or popover view. Inline views are regular SwiftUI views that can be placed anywhere in the view hierarchy. A popover view is a special view that appears on top of another view and has an arrow pointing to it.
To display a tip as an inline view, you can use the TipView structure, which takes the tip as an argument. For example, you can create an instance of FavoriteTip and pass it to TipView like this:
struct ContentView: View {
private let favoriteTip = FavoriteTip()var body: some View {
VStack {
// Place the tip view near the feature you want to highlight
TipView(favoriteTip)
// The rest of your app's UI
...
}
}
}
To display a tip as a popover view, you can use the PopoverTip modifier, which attaches a tip to any SwiftUI view. You also need to specify the arrowEdge parameter, which determines which edge of the view the arrow points to. For example, you can attach a FavoriteTip to an image view like this:
struct ContentView: View {
private let favoriteTip = FavoriteTip()var body: some View {
VStack {
// The rest of your app's UI
...
// Attach the tip to the image view with an arrow pointing to the top edge
Image(systemName: "heart")
.font(.system(size: 50))
.popoverTip(favoriteTip, arrowEdge: .top)
}
}
}
To enable hints in your app, you must set up the hint center when you launch the app. The Tip Center is a singleton object that manages the state and display of all tips in your app. You can use the Hint Center’s configure method to set hint options, such as how often the hint appears and where the data is stored.
The configure method takes an array of ConfigurationOption values as an argument. There are two types of configuration options available: displayFrequency and datastoreLocation. The displayFrequency option determines how often tips are displayed in your app. You can choose from three values: Immediately (the hint will appear as soon as possible), Once (the hint will only appear once per app launch), or Never (the hint will not appear at all). The datastoreLocation option determines where the chip’s persistent state information is stored. You can choose between two values: applicationDefault (the hint saves state in the app’s default container) or Custom (the hint saves state in the custom container you provide).
Tip To configure the center, you need to call the configure method in the task modifier of the main app’s content view. For example, you can set the hint to display immediately and save its state to your app’s default container like this:
@main
struct TipKitDemoApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.task {
// Configure and load your tips at app launch
try? Tips.configure((
.displayFrequency(.immediate),
.datastoreLocation(.applicationDefault)
))
}
}
}
}
Note that the configure method throws an error if the hint fails to load or configure. You can use a do-catch block to handle any errors that may occur.
You may want to display hints only under certain conditions, such as when the user performs a certain action or meets certain criteria. For example, you may want to display a hint for a feature that is only available after the user logs in or completes a tutorial. To accomplish this, we use a Rule structure that defines the conditions for displaying tips.
A rule consists of two parts: a parameter and an expression. Parameters are values that you need to monitor for changes, such as user settings, state variables, and events. An expression is a Boolean expression that evaluates a parameter and returns true or false. For example, you can create a rule to check if a user is logged in like this:
struct LoginRule: Rule {
// A parameter that monitors the user's login status
@Parameter var isLoggedIn: Bool// An expression that evaluates the parameter and returns true if the user is logged in
var expression: Bool {
isLoggedIn
}
}
You can use the @Parameter property wrapper to declare the value you want to monitor as a parameter. The @Parameter wrapper automatically updates the rules whenever the value changes. ==,!=,<、>You can also use operators and functions that return Boolean values in expressions, such as , &&, ||, and contains.
To associate a rule with a tip, you must implement the rule property of the Tip protocol and return an instance of the rule. For example, you can associate a LoginRule with a FavoriteTip like this:
struct FavoriteTip: Tip {
...// A rule that determines when to display the tip
var rule: Rule? {
LoginRule(isLoggedIn: true)
}
}
Note that the rule property is optional, so you can omit it if you don’t need a condition to display the tip.
Another way to control when tips appear is to use events. Events are user-defined actions that can trigger or ignore hints. For example, you can display a hint when the user taps a button, or dismiss the hint when the user scrolls through a list. To create an event, you must employ an event protocol that defines the event’s name and repetition count.
An event consists of two properties: name and repeatCount. The name property is a string that identifies the event. The repeatCount property is an integer that specifies how many times the event can occur before it becomes inactive. For example, you can create an event to represent a button tap like this:
struct ButtonTapEvent: Event {
// A name that identifies the event
var name: String {
"ButtonTap"
}// A repeat count that determines how many times the event can occur
var repeatCount: Int {
1
}
}
The name property can be any string as long as it is unique among all events in your app. You can also use any positive integer for the repeatCount property, or -1 to indicate that the event can occur indefinitely.
To associate an event with a tip, you must implement the triggerEvent or dismissEvent property of the Tip protocol and return an instance of the event. The triggerEvent property specifies the event that triggers the display of the tip, and the dismissEvent property specifies the event that closes the tip. For example, you can associate ButtonTapEvent with FavoriteTip as a trigger event as follows:
struct FavoriteTip: Tip {
...// An event that triggers the display of the tip
var triggerEvent: Event? {
ButtonTapEvent()
}
}
Note that both the triggerEvent and dismissEvent properties are optional, so you can omit them if you don’t need the event to show or hide the tip.
To fire an event in your app, you must call the Tip Center’s fire method and pass it the name of the event. For example, he can fire a ButtonTapEvent when the user taps a button like this:
struct ContentView: View {
...var body: some View {
VStack {
...
// A button that fires an event when tapped
Button("Tap Me") {
// Fire an event with the same name as our ButtonTapEvent
Tips.fire("ButtonTap")
}
}
}
}
Note that the occurrence of an event does not guarantee that the hint will be displayed or hidden. The Tip Center evaluates all tips and their rules and events before deciding whether to display them or ignore them.
TipKit makes it easy to create and display tips in your SwiftUI apps to help users discover new features and improve their experience. TipKit offers a variety of options to customize and control your tips, including content, appearance, rules, and events.