TipKit kullanarak uygulama özelliklerini keşfedilebilir hale getirmenin temelleri.
TipKit ile Uygulama Özelliklerini Vurgulama
Örnek Kod | TipKit
*iOS 18.0+, iPadOS 18.0+, Mac Catalyst 18.0+*
İpuçları kullanarak uygulamanızdaki yeni özelliklere dikkat çekin.
TipKit ile kullanıcılara uygulamanızdaki yeni bir özelliği öğretebilir veya bir görevi daha hızlı tamamlamanın yollarını gösterebilirsiniz. Bu rehber, uygulamanıza ekleyebileceğiniz farklı ipucu türlerini ve bunların nerede ve ne zaman görüneceğini kontrol etme yöntemlerini açıklar.
İpucu İçeriği Tanımlama
Tip protokolü, özelliklerin ne yaptığını açıklayan metin ve görselleri, ayrıca ipucunun ne zaman görüneceğine dair kuralları tanımlar:
struct InlineTip: Tip {
var title: Text {
Text("Favori Olarak Kaydet")
}
var message: Text? {
Text("Favori bahçeleriniz her zaman listenin en üstünde görünür.")
}
var image: Image? {
Image(systemName: "star")
}
}
İpuçlarını Yapılandırma ve Yükleme
İpuçlarının görüntülenmesi için uygulamaya yüklenmesi gerekir. Uygulama başlangıcında configure(_:)) çağrısıyla tüm ipuçları yüklenir. En iyi uygulama, bunu uygulama oturumu başına bir kez çağırmaktır:
@main
struct TipKitExamples: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
init() {
do {
try Tips.configure()
}
catch {
print("İpuçları başlatılırken hata: \(error)")
}
}
}
Satır İçi (Inline) İpuçları
Mümkün olduğunca bu stil kullanılmalıdır; kullanıcıların etkileşim kurmak isteyebileceği UI öğelerini kapatmaz. Satır içi ipuçları, vurguladıkları özelliği içeren görünüme doğrudan gömülür ve yerleşimi buna göre ayarlar.
struct InlineView: View {
let inlineTip = InlineTip()
var body: some View {
VStack(spacing: 20) {
// İpucuyu vurgulamak istediğiniz özelliğin yakınına yerleştirin.
TipView(inlineTip, arrowEdge: .bottom)
Button {
// Kullanıcı özelliği kullandığında ipucunu geçersiz kılın.
inlineTip.invalidate(reason: .actionPerformed)
} label: {
Label("Favori", systemImage: "star")
}
}
}
}
Popover İpuçları
Alttaki yerleşimi değiştirmek istenmeyen durumlarda veya kullanıcının ipucunun kapattığı kontrollerle etkileşime girmesine gerek olmadığında kullanılır:
struct PopoverView: View {
let highlightTip = HighlightTip()
var body: some View {
Image(systemName: "wand.and.stars")
.imageScale(.large)
.popoverTip(highlightTip)
.onTapGesture {
highlightTip.invalidate(reason: .actionPerformed)
}
}
}
Eylem Düğmeleri
Düğmeler, kullanıcılara yeni bir özelliği kullanıp kullanmamaya karar vermeden önce ek bilgi ve seçenekler sunar:
struct PasswordResetTip: Tip {
var title: Text {
Text("Yardıma İhtiyacınız Var Mı?")
}
var message: Text? {
Text("Hesabınıza giriş yapmak için yardıma mı ihtiyacınız var?")
}
var actions: [Action] {
Action(id: "reset-password", title: "Şifre Sıfırla")
Action(id: "faq", title: "SSS Sayfasını Görüntüle")
}
}
Eylem geri çağrısında action.id kontrol edilerek hangi düğmeye basıldığı belirlenir:
TipView(passwordResetTip, arrowEdge: .bottom) { action in
if action.id == "reset-password", let url = URL(string: "https://iforgot.apple.com") {
openURL(url)
}
if action.id == "faq", let url = URL(string: "https://appleid.apple.com/faq") {
openURL(url)
}
}
Parametre Tabanlı Kurallar
Uygulama durumunu izlemek için bir değişkeni Parameter sarmalayıcısıyla tanımlayın ve #Rule makrosuyla görüntülenme kuralı oluşturun:
struct ParameterRuleTip: Tip {
@Parameter
static var isLoggedIn: Bool = false
var rules: [Rule] {
#Rule(Self.$isLoggedIn) {
$0 == true
}
}
}
Durum değişikliğini tetiklemek için:
Button("Giriş Yap") {
ParameterRuleTip.isLoggedIn.toggle()
}
Not: İpucu yapısında herhangi bir kural tanımlanmazsa, tüm ipuçları kapatılana veya gösterim sıklığı eşiğini aşana kadar görüntülenir.
Olay Tabanlı Kurallar
Kullanıcı eylemlerini izlemek ve buna göre ipuçlarını görüntülemek için Event kullanılır:
struct EventRuleTip: Tip {
static let didTriggerControlEvent = Event(id: "didTriggerControlEvent")
var rules: [Rule] {
#Rule(Self.didTriggerControlEvent) {
$0.donations.count >= 3
}
}
}
İlişkili bağış değerleriyle olay oluşturma da mümkündür:
struct FoodEventTip: Tip {
struct Item: Codable, Sendable {
var name: String
var isFavorite: Bool
}
static let viewedSpecificFood: Tips.Event<Item> = Tips.Event(id: "viewed-specific-food")
var rules: [Rule] {
#Rule(FoodEventTip.viewedSpecificFood) {
$0.donations.smallestSubset(groupedBy: \.name).count > 1
}
#Rule(FoodEventTip.viewedSpecificFood) {
$0.donations.donatedWithin(.hour)
.filter({ $0.isFavorite == true }).count > 4
}
}
}
Kuralları Birleştirme
Parametreler, olaylar ve seçenekler birleştirilerek karmaşık koşullar oluşturulabilir. rules özelliğindeki kurallar mantıksal VE (AND) ile birleşir:
struct ComboTip: Tip {
@Parameter
static var isLoggedIn: Bool = false
static let enteredView = Event(id: "enteredView")
var rules: [Rule] {
#Rule(Self.$isLoggedIn) { $0 == true }
#Rule(Self.enteredView) { $0.donations.count >= 3 }
}
}
Test İçin İpucu Kurallarını Geçersiz Kılma
Tips.showAllTipsForTesting() // Tüm ipuçlarını göster
Tips.showTipsForTesting([tip1, tip2]) // Belirli ipuçlarını göster
Tips.hideAllTipsForTesting() // Tüm ipuçlarını gizle
try Tips.resetDatastore() // TipKit verilerini sıfırla
Tip Protokolü
Protokol | TipKit
*iOS 17.0+, iPadOS 17.0+, Mac Catalyst 17.0+, macOS 14.0+, tvOS 17.0+, visionOS 1.0+, watchOS 10.0+*
Bir ipucunun içeriğini ve görüntülenme koşullarını belirleyen tip.
protocol Tip : Identifiable, Sendable
İpucu İçeriği Ayarlama
| Özellik | Tip | Açıklama | | --- | --- | --- | | title | Text | İpucunu adlandıran başlık (zorunlu) | | message | Text? | Özelliğin nasıl kullanılacağının kısa açıklaması | | image | Image? | İpucuyla ilişkili görsel; başlık ve mesajın solunda görünür | | id | String | Benzersiz tanımlayıcı; varsayılan olarak tip adı kullanılır |
Özel tanımlayıcı örneği — Yeniden kullanılabilir ipuçları oluşturmak için:
struct NewTrailTip: Tip {
let newTrail: Trail
var id: String {
"NewTrailTip-\(newTrail.id)"
}
}
Görüntülenme Kontrolü
rules: [Self.Rule]— İpucunun görüntülenme uygunluğunu belirleyen kurallar.Rule—Tips.Ruletip takma adı. Görüntülemeden önce karşılanması gereken koşul.Event—Tips.Eventtip takma adı. Tekrarlanabilir kullanıcı tanımlı eylem.
Davranış Özelleştirme
options: [any TipOption]— İpucu için özelleştirmeler.Option—TipOptiontip takma adı.IgnoresDisplayFrequency— Önceden yapılandırılmış gösterim sıklığı aralığına uyup uymayacağını kontrol eder. Varsayılan:false.MaxDisplayCount— İpucu en fazla kaç kez görüntülendikten sonra otomatik geçersiz kılınacağını belirler. Varsayılan: sınırsız.MaxDisplayDuration— İpucu en fazla ne kadar süre görüntülendikten sonra geçersiz kılınacağını belirler (kümülatif). Minimum: 60 saniye. Varsayılan: sınırsız.
struct FavoriteBackyardTip: Tip {
var options: [any Option] {
MaxDisplayCount(3)
MaxDisplayDuration(300.0) // 5 dakika
IgnoresDisplayFrequency(true)
}
}
Eylemler
@Tips.ActionBuilder var actions: [Self.Action] { get }
Eylemler, TipView altında düğme olarak görünür. İsteğe bağlı birincil ve ikincil düğmeler sağlayarak kullanıcıların bir özelliği kullanmaya başlamasına veya daha fazla bilgi edinmesine yardımcı olur.
// Action başlatıcıları:
init(id: String?, title: some StringProtocol, perform: () -> Void)
init(id: String?, perform: () -> Void, () -> Text) // Özel etiketli
Durum İzleme
| Özellik / Yöntem | Tip | Açıklama | | --- | --- | --- | | status | Status | Kurallara ve gösterim sıklığına dayalı mevcut durum | | statusUpdates | AsyncStream<Status> | Durum değişikliklerini izlemek için asenkron akış | | shouldDisplay | Bool | Görüntülenip görüntülenmeyeceğini belirleyen değer | | shouldDisplayUpdates | AsyncMapSequence<...> | Görüntülenme uygunluğunu izlemek için asenkron akış |
Durum değerleri (Tips.Status):
| Durum | Açıklama | | --- | --- | | .available | İpucu görüntülenmeye uygun | | .pending | İpucu görüntülenmeye uygun değil | | .invalidated(reason) | İpucu artık geçerli değil |
Geçersiz kılma nedenleri (Tips.InvalidationReason):
| Neden | Açıklama | | --- | --- | | .actionPerformed | Kullanıcı ipucunun açıkladığı eylemi gerçekleştirdi | | .tipClosed | Kullanıcı ipucu görünümünü açıkça kapattı | | .displayCountExceeded | Maksimum gösterim sayısı aşıldı | | .displayDurationExceeded | Maksimum gösterim süresi aşıldı |
Geçersiz Kılma ve Sıfırlama
// İpucunu kalıcı olarak geçersiz kıl
func invalidate(reason: Self.InvalidationReason)
// Daha önce geçersiz kılınmış bir ipucunu sıfırla (iOS 26+)
func resetEligibility() async
resetEligibility(), geçersiz kılınmış bir ipucunun durumunu .pending veya .available'a geri döndürerek yeniden görüntülenmeye uygun hale getirir.
TipGroup
Sınıf | TipKit
*iOS 18.0+, iPadOS 18.0+, Mac Catalyst 18.0+, macOS 15.0+, tvOS 18.0+, visionOS 2.0+, watchOS 11.0+*
Belirli bir sıra veya uygunluk durumuna göre tek tek sunulabilen ipucu koleksiyonu.
final class TipGroup
İpuçlarını belirli bir sırayla (TipGroup.Priority.ordered) veya uygun ilk ipucunu (TipGroup.Priority.firstAvailable) gösterecek şekilde gruplandırabilirsiniz. Varsayılan öncelik firstAvailable'dır.
struct TrailDetails: View {
let trail: Trail
@State
var trailDetailTips = TipGroup {
FindTrailheadTip()
ExposureRatingTip()
SlopeProfileTip()
}
var body: some View {
ScrollView(.vertical) {
Text(trail.name).font(.title)
NavigateToTrailButton(trailLocation: trail.location)
.popoverTip(trailDetailTips.currentTip as? FindTrailheadTip)
TipView(trailDetailTips.currentTip as? ExposureRatingTip, arrowEdge: .bottom)
Text("Maruziyet Derecesi: \(trail.exposureRating)")
TipView(trailDetailTips.currentTip as? SlopeProfileTip, arrowEdge: .bottom)
Text("Eğim Açısı: \(trail.slopeAngle)°")
}
}
}
API Referansı
// Oluşturma
init(_ priority: TipGroup.Priority = .firstAvailable,
@Tips.GroupBuilder _ builder: () -> [any Tip])
Öncelik:
| Durum | Açıklama | | --- | --- | | .firstAvailable | Uygun olan ilk ipucunu gösterir | | .ordered | Önceki tüm ipuçlar geçersiz kılındığında sıradaki ipucunu gösterir |
Mevcut ipucuna erişim:
@MainActor final var currentTip: (any Tip)? { get }
final var currentTipUpdates: some AsyncSequence<any Tip, Never> { get }
Uyum
Observable,Sendable