Implementing Tooltip Hints for New Features in Mobile Apps
After a major update users don't notice the new button in toolbar. Not because it's poorly designed, but because no one showed it appeared. Tooltip solves this pointwise — without onboarding, without modals.
Technical Implementation
On iOS with SwiftUI — .popover(isPresented:) modifier for simple cases, or custom ViewModifier with ZStack + GeometryReader for positioning bubble relative to target element. System UIToolTip appeared only in iOS 15 and works exclusively with pointer (iPad + Apple Pencil / trackpad), doesn't fit smartphones. So tooltip built via overlay with anchorPreference to compute target coordinates in global space.
In UIKit — UIView bubble with CAShapeLayer for arrow, positioned via convert(_:to:) and window?.addSubview(). Key moment: add to window, not superview — else bubble cut off at clipsToBounds of parent container.
On Android with Compose — Popup + custom composable with measurement via onGloballyPositioned. Material3 doesn't have built-in tooltip with arbitrary positioning; PlainTooltip and RichTooltip appeared in Material3 1.1.0, but work only with TooltipBox and limited in customization. For full control — custom implementation via Popup with alignment = Alignment.TopStart and offset based on target coordinates.
In React Native — library react-native-walkthrough-tooltip or custom Modal with measure() to compute position. Modal with transparent={true} and animationType="fade" gives desired effect.
Managing Display State
Tooltip shown once on first feature discovery. Logic: on every app launch check UserDefaults / SharedPreferences for key tooltip_feature_X_shown. Show — write flag. Repeat show — only on explicit trigger (e.g., "What's new?").
For multiple simultaneous features — queue: tooltipQueue: [TooltipConfig], show one by one with 300–500 ms delay between. Don't show during active animation or screen transition — track navigation state.
Delay before show 500–800 ms after screen load mandatory. Tooltip over not-yet-rendered content looks like bug.
Accessibility
accessibilityLabel on dismiss button. VoiceOver should auto-read tooltip text on appearance via UIAccessibility.post(notification: .announcement, argument: tooltipText). TalkBack — AccessibilityEvent.TYPE_ANNOUNCEMENT via View.announceForAccessibility().
Timeline: 1–3 days depending on number of hints, positioning complexity, and multi-platform support need.







