Add UIKit component extensions and concept example app#8
Add UIKit component extensions and concept example app#8cruisediary wants to merge 33 commits intohyperconnect:mainfrom
Conversation
…spacing, alignment, layoutMargins modifiers to UIStackView
…te, scroll indicator, contentOffset modifiers to UIScrollView
…ifiers to UIImageView
…d accuracy-based assertions for layout tests
Sets up programmatic navigation with ConceptListViewController as root, and adds UIImageView+Remote for Lorem Picsum async image loading.
Full-screen player with horizontal paging hero (one image per track), page-synced track info via UIScrollViewDelegate, playback controls, real-time elapsed time, shuffle mode, and volume slider.
Profile page with hero image, avatar, follow/unfollow button, equal-width stat columns (ZStack overlay for thin dividers), bio text, notification switch, and 2x3 photo grid.
Grouped settings UI with Dark Mode toggle, Brightness slider (full-width, with live percentage label), Push Notifications toggle, Font Size stepper, Storage progress bar, and iCloud Sync button with activity indicator.
Horizontal destination carousel with hero images, paging cards, page control that syncs to scroll position via UIScrollViewDelegate, star ratings, and category filter chips.
Design-system-style reference page with hero banner, Typography scale, Color System palette chips, Button variants (primary/secondary/destructive/ ghost/pill/gradient), Gradient swatches, and Surfaces/Layout examples.
2-column grid with Fade, Scale, Rotate, and Pulse animation cards (tap-to-trigger), plus a full-width Shake card. Cards use fill-aligned VStack so the preview area renders at full width.
Example/HypeUI-Example/HypeUI-Example/ComponentGalleryViewController.swift
Outdated
Show resolved
Hide resolved
de8a661 to
177c17e
Compare
- Remove previous target before adding in onChange to prevent handler firing N times when called repeatedly on the same control - Change OBJC_ASSOCIATION_COPY_NONATOMIC to OBJC_ASSOCIATION_RETAIN_NONATOMIC for closure storage; Swift closures do not conform to NSCopying - Schedule playback timer with RunLoop .common mode so progress advances during scroll interactions (was pausing in .tracking run loop mode)
Content hugging was missing, allowing views to expand beyond their intrinsic size. Both compression resistance and hugging are now set to .required, matching SwiftUI fixedSize() semantics in both directions.
Example/HypeUI-Example/HypeUI-Example/MusicPlayerViewController.swift
Outdated
Show resolved
Hide resolved
| guard let scrollView = self?.carouselScrollView, let self = self else { return } | ||
| let offset = CGFloat(page) * (self.cardWidth + 16) | ||
| scrollView.setContentOffset(CGPoint(x: offset, y: 0), animated: true) | ||
| } |
There was a problem hiding this comment.
Carousel page offset ignores horizontal content padding
Low Severity
The onChange handler computes the scroll offset as page * (cardWidth + 16), and scrollViewDidScroll computes the page index using the same pageWidth. However, the content HStack has .padding(.horizontal, 24), adding 24pt before the first card. This means the computed offsets don't align with the actual card positions in the content, causing cards to appear slightly misaligned when the user taps a page indicator dot.
Additional Locations (1)
Page control is already updated reactively via .linked($currentTrack, keyPath: \.currentPage); the stored weak reference was never read.
…ndler visibility - Exclude current track from shuffle selection in nextTrack() - Show follower count as integer below 100K to make ±1 changes visible - Mark @objc handler methods as internal to hide from public API
| self.progress = 0 | ||
| let x = CGFloat(page) * UIScreen.main.bounds.width | ||
| self.pagingScrollView?.setContentOffset(CGPoint(x: x, y: 0), animated: true) | ||
| } |
There was a problem hiding this comment.
Track change order inconsistency creates latent state bug
Low Severity
The pageControl.onChange handler sets self.currentTrack = page before self.progress = 0, while all other track-change paths (nextTrack, previousTrack, scrollViewDidEndDecelerating) reset progress first. Since the $progress reactive map closure reads self.currentTrack synchronously, this ordering difference means the elapsed-time label briefly computes against the new track's duration for the old progress value. Currently masked because progress is always set to 0 (making the product zero regardless), but any future change to preserve partial progress across tracks would surface an incorrect time display specifically from the page-control path.


Description
Overview
Adds SwiftUI-style DSL extensions for common UIKit components and redesigns the Example app into a Concept Gallery with six interactive demos.
Tech Spec
New Extensions
UISwitchisOn,onTintColor,onChangeUISlidervalue,minimumValue,maximumValue,minimumTrackTintColor,onChangeUISteppervalue,minimumValue,maximumValue,stepValue,onChangeUIProgressViewprogress,progressTintColor,trackTintColorUIActivityIndicatorViewhidesWhenStopped,color,styleUIPageControlnumberOfPages,currentPage,pageIndicatorTintColor,onChangeUIImageViewmakeContentMode,highlightedImage,animationImagesUIViewhidden,disabled,tag,zIndex,fixedSize,scaleEffect,rotationEffectUIStackViewspacing,alignment,layoutMarginsReactive Binding
@Behaviorproperty wrapper — state management backed byBehaviorRelay<T>.linked(_:keyPath:)— two-way binding betweenUIControlandBehaviorRelayGradient.init(colors:)convenience initializer addedExample App
Restructured from a single view to a ConceptList → detail navigation flow with six concept screens:
UIScrollView,isPagingEnabled) with per-track images, track sync viaUIScrollViewDelegate,real-time elapsed time binding
ZStackoverlay, 2×3 photo gridUISwitch/UISlider/UIStepper/UIProgressViewcomposition with reactive label bindingsUIPageControlsynced to scroll position in real time viaUIScrollViewDelegate.scrollViewDidScrollNote
Medium Risk
Expands the public API surface with new UIKit modifier extensions and event-closure storage via associated objects, plus bumps dependency versions; regressions would primarily affect UI behavior and bindings across the library.
Overview
Adds SwiftUI-style DSL extensions for more UIKit controls. Introduces chainable modifiers for
UISwitch,UISlider,UIStepper,UIProgressView,UIActivityIndicatorView, andUIPageControl(includingonChangecallbacks), plus newUIViewmodifiers (hidden,disabled,tag,zIndex,fixedSize) and extraUIStackView/UIScrollViewconfiguration helpers.Enhances existing primitives and documentation/tests. Adds
Gradient(colors:)convenience init, expandsImagemodifiers (highlighting/animation/symbol config), updates README to document the new APIs, and adds/updates unit tests accordingly.Reworks the Example app into a concept gallery. Switches the root controller to a navigation-driven list and adds multiple demo view controllers (music player, profile, settings, travel carousel, component gallery, animation showcase) along with a small remote-image helper; also updates SPM/CocoaPods dependency constraints and the example’s SwiftPM resolution.
Written by Cursor Bugbot for commit f6cd202. This will update automatically on new commits. Configure here.