|
1 | | -# poptip-swiftui |
| 1 | +# PopTip SwiftUI |
| 2 | + |
| 3 | +The popTip-SwiftUI provides a flexible and customizable way to display tooltips (PopTips) in SwiftUI applications. It integrates a UIKit-based PopTip component (from [AmPoptip](https://github.com/andreamazz/AMPopTip)) with SwiftUI, allowing you to present text-based or custom SwiftUI content in a tooltip with configurable appearance and behavior. This wrapper uses a view modifier (`PopTipViewModifier`) to attach PopTips to SwiftUI views, with styling managed via `PopTipTheme` and behavior controlled through environment values. |
| 4 | + |
| 5 | +## Features |
| 6 | + |
| 7 | +- **UIKit + SwiftUI Integration** |
| 8 | + Wraps [AMPopTip](https://github.com/andreamazz/AMPopTip) for easy use in SwiftUI views. |
| 9 | +- **Target Highlighting** |
| 10 | + Supports transparent overlay cutouts to draw focus to the tooltip’s anchor view. |
| 11 | +- **Custom SwiftUI Content** |
| 12 | + Display any SwiftUI view inside the PopTip. |
| 13 | +- **Customizable** |
| 14 | + Full control over theme, behavior, positioning, dismissal, and interactivity. |
| 15 | + |
| 16 | +- **Target View Highlighting**: |
| 17 | + Ability to use a transparent cutout in the overlay (via popTipHasOverlayTargetHole), which draws attention to the target view. |
| 18 | + |
| 19 | +## Installation |
| 20 | + |
| 21 | +### With Xcode |
| 22 | + |
| 23 | +1. In Xcode, go to `File > Add Packages`. |
| 24 | +2. Use the URL: https://github.com/Commencis/poptip-SwiftUI |
| 25 | +3. Choose the latest version or specify a range. |
| 26 | +4. Add `"PopTipSwiftUI"` to your app target. |
| 27 | + |
| 28 | +### With `Package.swift` |
| 29 | + |
| 30 | +Add this package as dependency: |
| 31 | + |
| 32 | +```swift |
| 33 | +.package(url: "https://github.com/Commencis/poptip-SwiftUI", from: "x.y.z") |
| 34 | +``` |
| 35 | + |
| 36 | +And in your target dependencies: |
| 37 | + |
| 38 | +```swift |
| 39 | +.target( |
| 40 | + name: "YourApp", |
| 41 | + dependencies: [ |
| 42 | + .product(name: "PopTipSwiftUI", package: "poptip-SwiftUI") |
| 43 | + ] |
| 44 | +) |
| 45 | +``` |
| 46 | + |
| 47 | +## Usage |
| 48 | + |
| 49 | +Attach a PopTip to any SwiftUI view using the `.popTip` modifier. You control: |
| 50 | + |
| 51 | +- Presentation via `Binding<Bool>` |
| 52 | +- Appearance via `PopTipTheme` |
| 53 | +- Content: simple text or any SwiftUI view |
| 54 | + |
| 55 | +### Plain Text PopTip |
| 56 | + |
| 57 | +Shows a basic tooltip with a message and a custom theme. |
| 58 | + |
| 59 | +```swift |
| 60 | +Button("Show Plain PopTip") { |
| 61 | + showPlainTip.toggle() |
| 62 | +} |
| 63 | +.popTip( |
| 64 | + isPresented: $showPlainTip, |
| 65 | + message: "This is a simple PopTip!", |
| 66 | + theme: previewTipTheme |
| 67 | +) |
| 68 | +.padding() |
| 69 | +.background(Color.gray.opacity(0.2)) |
| 70 | +.cornerRadius(8) |
| 71 | +``` |
| 72 | + |
| 73 | +### Timed PopTip with Auto-Dismiss |
| 74 | + |
| 75 | +Automatically dismisses the tooltip after 2 seconds, and highlights the target view. |
| 76 | + |
| 77 | +```swift |
| 78 | +Button("Show Timed PopTip") { |
| 79 | + showTimerTip.toggle() |
| 80 | +} |
| 81 | +.popTip( |
| 82 | + isPresented: $showTimerTip, |
| 83 | + message: "This will dismiss in 2 seconds!", |
| 84 | + theme: previewTipTheme2, |
| 85 | + autoDismissDuration: 2.0 |
| 86 | +) |
| 87 | +.popTipHasOverlayTargetHole(true) |
| 88 | +.padding() |
| 89 | +.background(Color.gray.opacity(0.2)) |
| 90 | +.cornerRadius(8) |
| 91 | +``` |
| 92 | + |
| 93 | +### Custom SwiftUI Content PopTip |
| 94 | + |
| 95 | +Displays a fully customized SwiftUI view inside the tooltip. |
| 96 | + |
| 97 | +```swift |
| 98 | +Button("Show Custom PopTip") { |
| 99 | + showCustomTip.toggle() |
| 100 | +} |
| 101 | +.popTip( |
| 102 | + isPresented: $showCustomTip, |
| 103 | + theme: previewTipTheme3 |
| 104 | +) { |
| 105 | + HStack { |
| 106 | + Image(systemName: "star.fill") |
| 107 | + .foregroundColor(.yellow) |
| 108 | + Text("Custom Content!") |
| 109 | + .font(.headline) |
| 110 | + .foregroundColor(.white) |
| 111 | + } |
| 112 | + .padding(8) |
| 113 | +} |
| 114 | +.padding() |
| 115 | +.background(Color.gray.opacity(0.2)) |
| 116 | +.cornerRadius(8) |
| 117 | +``` |
| 118 | + |
| 119 | +## Theming & Behavior |
| 120 | + |
| 121 | +### Customize Appearance |
| 122 | + |
| 123 | +You can style the tooltip using `PopTipTheme`: |
| 124 | + |
| 125 | +```swift |
| 126 | +let customTheme = PopTipTheme( |
| 127 | + bubbleColor: .purple.opacity(0.9), |
| 128 | + textColor: .white, |
| 129 | + font: .systemFont(ofSize: 15, weight: .bold), |
| 130 | + cornerRadius: 12, |
| 131 | + textAlignment: .center, |
| 132 | + overlayColor: .black.opacity(0.5), |
| 133 | + edgeInsets: EdgeInsets(top: 10, leading: 10, bottom: 10, trailing: 10), |
| 134 | + arrowSize: CGSize(width: 14, height: 7) |
| 135 | +) |
| 136 | + |
| 137 | +Button("Show Custom PopTip") { /* Action */ } |
| 138 | + .popTip( |
| 139 | + isPresented: .constant(true), |
| 140 | + message: "Custom styled PopTip!", |
| 141 | + theme: customTheme |
| 142 | + ) |
| 143 | +``` |
| 144 | + |
| 145 | +### Customizing Behavior |
| 146 | + |
| 147 | +Use view modifiers to configure the PopTip’s behavior and positioning. These modifiers set environment values that the PopTipViewModifier reads. You may also use `configurePopTip` API to directly access PopTip just before presented. |
| 148 | + |
| 149 | +```swift |
| 150 | +Button("Show PopTip") |
| 151 | + .popTip( |
| 152 | + isPresented: .constant(true), |
| 153 | + message: "Interactive PopTip", |
| 154 | + theme: .previewTipTheme |
| 155 | + ) |
| 156 | + .popTipDismissOnScroll(true) // Dismiss on scroll |
| 157 | + .popTipMaxWidth(250) // Limit width to 250 points |
| 158 | + .popTipOnTapInside { print("PopTip tapped!") } // Custom tap handler |
| 159 | + .popTipDismissOnTap(false) // Prevent dismissal on tap |
| 160 | + .popTipDirection(.down) // Show PopTip below target |
| 161 | + .popTipEdgeMargin(20) // 20-point screen edge margin |
| 162 | + .popTipOffset(5) // 5-point offset from anchor |
| 163 | + .popTipHasOverlayTargetHole(true) // Transparent cutout over target |
| 164 | + .configurePopTip { popTip in // Custom PopTip configuration |
| 165 | + popTip.animationIn = 0.8 |
| 166 | + popTip.animationOut = 0.4 |
| 167 | + popTip.shouldBounce = true |
| 168 | + popTip.borderWidth = 1.0 |
| 169 | + popTip.borderColor = .white |
| 170 | + } |
| 171 | +``` |
0 commit comments