### Implementing a Custom Blur Header Style Source: https://context7.com/swiftkickmobile/swiftuimaterialtabs/llms.txt Create a reusable sticky header effect by implementing the HeaderStyle protocol. This example applies a blur and opacity effect based on scroll offset. ```swift // Custom dim-and-blur effect struct BlurHeaderStyle: HeaderStyle { func makeBody(context: HeaderContext, content: Content) -> some View { content .blur(radius: context.unitOffset * 6) .opacity(1 - context.unitOffset * 0.5) } } // Usage Text("Header Title") .padding() .headerStyle(BlurHeaderStyle(), context: context) ``` -------------------------------- ### Basic Material Tabs Usage in SwiftUI Source: https://github.com/swiftkickmobile/swiftuimaterialtabs/blob/main/README.md Demonstrates the fundamental setup for MaterialTabs, including defining tabs, managing the selected state, and configuring header and content views. Ensure the `MaterialTabs` component is imported. ```swift struct BasicTabView: View { // Tabs are identified by some `Hashable` type. enum Tab: Hashable { case first case second } // The selected tab state variable is owned by your view. @State var selectedTab: Tab = .first var body: some View { // The main conainer view. MaterialTabs( // A binding to the currently selected tab. selectedTab: $selectedTab, // A view builder for the header title that takes a `MaterialTabsContext`. This can be anything. headerTitle: { context in Text("Header Title") .padding() }, // A view builder for the tab bar that takes a `MaterialTabsContext`. headerTabBar: { context in // Use the `MaterialTabBar` or provide your own implementation. MaterialTabBar(selectedTab: $selectedTab, sizing: .equalWidth, context: context) }, headerBackground: { context in // The background can be anything, but is typically a `Color`, `Gradient` or scalable `Image`. // The background spans the entire header and top safe area. Color.yellow }, // The tab contents. content: { Text("First Tab Content") // Identify tabs using the `.materialTabItem()` view modifier. .materialTabItem( tab: Tab.first, // Using Material 3 primary tab style. label: .primary("First", icon: Image(systemName: "car")) ) Text("Second Tab Content") .materialTabItem( tab: Tab.second, label: .primary("Second", icon: Image(systemName: "sailboat")) ) } ) } } ``` -------------------------------- ### MaterialTabs Container Example Source: https://context7.com/swiftkickmobile/swiftuimaterialtabs/llms.txt Implement a tabbed interface with a collapsible sticky header using `MaterialTabs`. Configure header title, tab bar, background, and content for each tab. Use `.materialTabItem()` to register tabs. ```swift import SwiftUI import SwiftUIMaterialTabs struct ContentView: View { enum Tab: Hashable { case feed, profile, settings } @State private var selectedTab: Tab = .feed var body: some View { MaterialTabs( selectedTab: $selectedTab, config: MaterialTabsConfig(crossTabSyncMode: .resetTitleOnScroll()), headerTitle: { context in Text("My App") .font(.largeTitle.bold()) .padding() .headerStyle(ShrinkHeaderStyle(), context: context) }, headerTabBar: { context in MaterialTabBar( selectedTab: $selectedTab, sizing: .equalWidth, context: context ) }, headerBackground: { _ in LinearGradient( colors: [.blue, .purple], startPoint: .topLeading, endPoint: .bottomTrailing ) }, content: { MaterialTabsScroll(tab: Tab.feed) { scrollContext in LazyVStack(spacing: 0) { ForEach(0..<30) { i in Text("Feed item \(i)") .frame(maxWidth: .infinity) .padding() .background(i.isMultiple(of: 2) ? Color(.systemBackground) : Color(.secondarySystemBackground)) } } } .materialTabItem(tab: Tab.feed, label: .primary("Feed", icon: Image(systemName: "house"))) MaterialTabsScroll(tab: Tab.profile) { _ in VStack(spacing: 16) { Image(systemName: "person.circle.fill") .resizable() .frame(width: 80, height: 80) Text("Jane Doe") .font(.title2) } .padding() } .materialTabItem(tab: Tab.profile, label: .primary("Profile", icon: Image(systemName: "person"))) Text("Settings coming soon") .materialTabItem(tab: Tab.settings, label: .primary("Settings", icon: Image(systemName: "gear"))) } ) } } ``` -------------------------------- ### Import SwiftUIMaterialTabs Source: https://context7.com/swiftkickmobile/swiftuimaterialtabs/llms.txt Import the library to use its components. ```swift import SwiftUIMaterialTabs ``` -------------------------------- ### Initialize MaterialTabBar with Equal or Proportional Width Source: https://github.com/swiftkickmobile/swiftuimaterialtabs/blob/main/README.md Instantiate MaterialTabBar with either .equalWidth or .proportionalWidth sizing. The selectedTab binding and context are required. ```swift MaterialTabBar(selectedTab: $selectedTab, sizing: .equalWidth, context: context) MaterialTabBar(selectedTab: $selectedTab, sizing: .proportionalWidth, context: context) ``` -------------------------------- ### MaterialTabBar Sizing Options Source: https://context7.com/swiftkickmobile/swiftuimaterialtabs/llms.txt Configure `MaterialTabBar` for equal-width or proportional-width sizing. Adjust spacing and fill behavior as needed. ```swift // Equal-width sizing — all tabs share the same width MaterialTabBar(selectedTab: $selectedTab, sizing: .equalWidth, context: context) ``` ```swift // Proportional sizing — tabs sized to fit their content MaterialTabBar( selectedTab: $selectedTab, sizing: .proportionalWidth, spacing: 8, // gap between selectors fillAvailableSpace: true, context: context ) ``` -------------------------------- ### Configure Secondary MaterialTabItem with Custom Configurations Source: https://github.com/swiftkickmobile/swiftuimaterialtabs/blob/main/README.md Use the .secondary label style with optional config and deselectedConfig parameters for custom styling of secondary tab items. ```swift Text("Second Tab Content") .materialTabItem( tab: Tab.first, label: .secondary("First", config: customLabelConfig, deselectedConfig: custonDeselectedLabelConfig) ) ``` -------------------------------- ### Basic Sticky Header Usage in SwiftUI Source: https://github.com/swiftkickmobile/swiftuimaterialtabs/blob/main/README.md Demonstrates the fundamental structure for a sticky header view. The header title, background, and content are defined using view builders. The content area uses `StickyHeaderScroll` to manage scrollable content. ```swift struct BasicStickyHeaderView: View { var body: some View { // The main conainer view. StickyHeader( // A view builder for the header title that takes a `StickyHeaderContext`. This can be anything. headerTitle: { context in Text("Header Title") .padding() }, headerBackground: { context in // The background can be anything, but is typically a `Color`, `Gradient` or scalable `Image`. // The background spans the entire header and top safe area. Color.yellow }, // The tab contents. content: { StickyHeaderScroll() { _ in LazyVStack(spacing: 0) { ForEach(0..<10) { index in Text("Row \(index)") .padding() } } .scrollTargetLayout() } } ) } } ``` -------------------------------- ### Configure Material Tab Items Source: https://context7.com/swiftkickmobile/swiftuimaterialtabs/llms.txt Use `.materialTabItem` to register views with `MaterialTabBar`. Supports primary (icon+text), secondary (text only), or custom label views. ```swift scrollView .materialTabItem( tab: Tab.feed, label: .primary("Feed", icon: Image(systemName: "house.fill")) ) ``` ```swift scrollView .materialTabItem( tab: Tab.profile, label: .secondary( "Profile", config: SecondaryTab.Config( font: .system(size: 14, weight: .bold), titleStyle: Color.indigo, underlineThickness: 3 ), deselectedConfig: SecondaryTab.Config( font: .system(size: 14, weight: .regular), titleStyle: Color.secondary ) ) ) ``` ```swift scrollView .materialTabItem(tab: Tab.settings) { tab, context, tapped in HStack { Image(systemName: "gear") Text("Settings") .fontWeight(tab == context.selectedTab ? .bold : .regular) } .foregroundColor(tab == context.selectedTab ? .blue : .gray) .frame(maxWidth: .infinity, maxHeight: .infinity) .onTapGesture(perform: tapped) } ``` -------------------------------- ### Configure MaterialTabBar Label Filling and Spacing Source: https://github.com/swiftkickmobile/swiftuimaterialtabs/blob/main/CHANGELOG.md Add two new configuration options to MaterialTabBar for custom tab labels: fillAvailableSpace to control label width expansion and spacing for horizontal spacing between labels. ```swift /// fillAvailableSpace: Applicable when tab labels don't inherently fill the width of the tab bar. When `true` (the default), the label widths are expanded proportionally to fill the tab bar. When `false`, the labels are not expanded and centered horizontally within the tab bar. /// spacing: The amount of horizontal spacing to use between tab labels. Primary and Secondary tabs should use the default spacing of 0 to form a continuous line across the bottom of the tab bar. ``` -------------------------------- ### Configure Primary MaterialTabItem Source: https://github.com/swiftkickmobile/swiftuimaterialtabs/blob/main/README.md Apply the .materialTabItem modifier to tab content to define its tab and label. Use .primary for the default primary tab style, providing a label and an optional system image. ```swift Text("First Tab Content") .materialTabItem( tab: Tab.first, label: .primary("First", icon: Image(systemName: "car")) ) ``` -------------------------------- ### Setting Minimum Title Height with .minTitleHeight() Source: https://context7.com/swiftkickmobile/swiftuimaterialtabs/llms.txt Configure the minimum visible portion of a title view when the header is collapsed using .minTitleHeight(). Supports auto-measurement, scaling, absolute, and relative heights. ```swift // Measure the receiving view's actual height Text("Pinned Element") .padding() .headerStyle(FixedHeaderStyle(), context: context) .minTitleHeight(.content()) // auto-measure // Scaled-down element — pass the scale factor so the height is computed correctly Text("Shrinking Pinned Element") .padding() .headerStyle(ShrinkHeaderStyle(fade: false, minimumScale: 0.5, offsetFactor: 0), context: context) .headerStyle(FixedHeaderStyle(), context: context) .minTitleHeight(.content(scale: 0.5)) // accounts for scale // Absolute fixed height someView .minTitleHeight(.absolute(44)) // Relative to the full title height someView .minTitleHeight(.relative(0.25)) // keep 25% of title visible ``` -------------------------------- ### Implement a Collapsible Sticky Header Source: https://context7.com/swiftkickmobile/swiftuimaterialtabs/llms.txt Use `StickyHeader` for a header-only container with a collapsible sticky header. Its API is similar to `MaterialTabs` but without tab bar functionality. ```swift struct ArticleView: View { var body: some View { StickyHeader( headerTitle: { context in VStack(alignment: .leading) { Text("SWIFT WEEKLY") .font(.caption.bold()) .foregroundStyle(.secondary) Text("Issue #42") .font(.title.bold()) } .frame(maxWidth: .infinity, alignment: .leading) .padding() .headerStyle(OffsetHeaderStyle(fade: true), context: context) }, headerBackground: { context in Image(.heroBackground) .resizable() .aspectRatio(contentMode: .fill) .headerStyle(ParallaxHeaderStyle(amount: 0.4), context: context) }, content: { StickyHeaderScroll { LazyVStack(alignment: .leading, spacing: 12) { ForEach(articleParagraphs, id: \.self) { Text(paragraph).padding(.horizontal) } } .padding(.top) } } ) } } ``` -------------------------------- ### Define Custom MaterialTabItem Label Source: https://github.com/swiftkickmobile/swiftuimaterialtabs/blob/main/README.md Provide a custom closure to .materialTabItem to create a fully custom tab selector label. The closure receives the tab, context, and a tap action closure. ```swift Text("Second Tab Content") .materialTabItem( tab: Tab.first, label: { tab, context, tapped in Text(tab.description) .foregroundColor(tab == context.selectedTab ? .blue : .black) .onTapGesture(perform: tapped) } ) ``` -------------------------------- ### Create Scrollable Content for Tabs Source: https://context7.com/swiftkickmobile/swiftuimaterialtabs/llms.txt Use `MaterialTabsScroll` as a `ScrollView` wrapper for sticky header effects within `MaterialTabs`. Do not apply `.scrollPosition()` directly. ```swift MaterialTabsScroll(tab: Tab.feed) { // scrollContext.safeHeight — total safe height under the header LazyVStack(spacing: 0) { ForEach(items) { ItemRow(item: item) } } } ``` ```swift @State private var scrollPosition = ScrollPosition(idType: Int.self) MaterialTabsScroll(tab: Tab.feed, scrollPosition: $scrollPosition) { _ in LazyVStack(spacing: 0) { ForEach(0..<50) { Text("Row \(i)").id(i).padding() } } .scrollTargetLayout() } ``` ```swift @State private var scrollItem: Int? @State private var scrollUnitPoint: UnitPoint = .top MaterialTabsScroll( tab: Tab.feed, reservedItem: -1, // any unique ID not used in your content scrollItem: $scrollItem, scrollUnitPoint: $scrollUnitPoint ) { LazyVStack(spacing: 0) { ForEach(0..<50) { Text("Row \(i)").id(i).padding() } } .scrollTargetLayout() } ``` -------------------------------- ### Configure Cross-Tab Synchronization Mode Source: https://github.com/swiftkickmobile/swiftuimaterialtabs/blob/main/CHANGELOG.md When creating MaterialTabsScroll, provide an optional MaterialTabsConfig and specify the crossTabSyncMode. The default is resetTitleOnScroll(). ```swift public enum CrossTabSyncMode: Equatable { /// Preserves the scroll position relative to the header. If the header has moved up, the scroll view is moved up. If the header is moved down, the scroll /// view is moved down. The benefit of this approach is preserving the user's scroll position. The down side is that the header is expanded when it /// should be collapsed and will remain expanded if the user scrolls up, which could severely limit the space for scroll view content if the header /// is unusually tall. case preserveScrollPosition /// Resets the scroll position to align the top of the scroll view content is aligned with the bottom of the header. This is how many apps behave and /// it ensures that scroll position and title collapse state are always in sync. The down side is that the user's previous scroll position is lost. case resetScrollPosition /// Initially preserves the scroll position the same as `preserveContentOffset`. However, if the user scrolls, the title collapse state is /// animated to where match the scroll position. This option introduces a title view animation, but eliminates the down sides of other options. /// This is the default behavior. case resetTitleOnScroll(_ animation: Animation = .snappy(duration: 0.3)) } ``` -------------------------------- ### Accessing Scroll Metrics in Header Views Source: https://context7.com/swiftkickmobile/swiftuimaterialtabs/llms.txt Use HeaderContext within header view builders to access real-time scroll metrics like offset, unitOffset, and heights for custom animations. ```swift headerTitle: { context in VStack { Text("Title") } .onAppear { // context.offset — current scroll offset (0 → maxOffset) // context.unitOffset — normalized 0.0 (expanded) → 1.0 (collapsed) // context.maxOffset — offset at fully collapsed state // context.titleHeight — measured height of the title view // context.tabBarHeight — measured height of the tab bar // context.height — titleHeight + tabBarHeight // context.backgroundHeight — height including top safe area // context.selectedTab — currently selected tab } } ``` -------------------------------- ### StickyHeader Source: https://context7.com/swiftkickmobile/swiftuimaterialtabs/llms.txt A header-only container for a single scroll view with a collapsible sticky header. Its API is similar to MaterialTabs but without the tab bar. ```APIDOC ## StickyHeader A header-only container (no tabs) for a single scroll view with a collapsible sticky header. API is identical to `MaterialTabs` minus the tab bar and tab selection binding. ### Example Usage: ```swift struct ArticleView: View { var body: some View { StickyHeader( headerTitle: { context in VStack(alignment: .leading) { Text("SWIFT WEEKLY") .font(.caption.bold()) .foregroundStyle(.secondary) Text("Issue #42") .font(.title.bold()) } .frame(maxWidth: .infinity, alignment: .leading) .padding() .headerStyle(OffsetHeaderStyle(fade: true), context: context) }, headerBackground: { context in Image(.heroBackground) .resizable() .aspectRatio(contentMode: .fill) .headerStyle(ParallaxHeaderStyle(amount: 0.4), context: context) }, content: { StickyHeaderScroll { // scrollContext.safeHeight — height of the device safe area // scrollContext.contentHeight — height available below the header LazyVStack(alignment: .leading, spacing: 12) { ForEach(articleParagraphs, id: \.self) { Text(paragraph).padding(.horizontal) } } .padding(.top) } } ) } } ``` ``` -------------------------------- ### MaterialTabsConfig Cross-Tab Sync Modes Source: https://context7.com/swiftkickmobile/swiftuimaterialtabs/llms.txt Configure how the header scroll position is synchronized when switching tabs. Options include resetting the title on scroll, immediately resetting the scroll position, or preserving the scroll offset. ```swift MaterialTabs( selectedTab: $selectedTab, config: MaterialTabsConfig(crossTabSyncMode: .resetTitleOnScroll(.snappy(duration: 0.3))), ... ) ``` ```swift MaterialTabs( selectedTab: $selectedTab, config: MaterialTabsConfig(crossTabSyncMode: .resetScrollPosition), ... ) ``` ```swift MaterialTabs( selectedTab: $selectedTab, config: MaterialTabsConfig(crossTabSyncMode: .preserveScrollPosition), ... ) ``` -------------------------------- ### Set Minimum Collapsed Height for Title View Source: https://github.com/swiftkickmobile/swiftuimaterialtabs/blob/main/README.md Informs the library about the minimum height the title view should maintain when collapsed. Use `.content()` to automatically determine height based on the view's intrinsic size. ```swift VStack() { Text("Top Title Element"). .padding() Text("Bottom Title Element") .padding() .minTitleHeight(.content()) } ``` -------------------------------- ### Applying ShrinkHeaderStyle for Scaling and Fading Source: https://context7.com/swiftkickmobile/swiftuimaterialtabs/llms.txt Utilize ShrinkHeaderStyle to scale down and optionally fade header elements as they scroll. Supports minimum scale, offset factor, and anchor point. ```swift headerTitle: { context in Text("Big Title") .font(.system(size: 34, weight: .black)) .padding() .headerStyle( ShrinkHeaderStyle( fade: true, minimumScale: 0.6, offsetFactor: 0.3, anchor: .leading ), context: context ) } ``` -------------------------------- ### .materialTabItem(tab:label:) Source: https://context7.com/swiftkickmobile/swiftuimaterialtabs/llms.txt A view modifier to register tab content with MaterialTabBar and configure its label. It supports primary (icon + text), secondary (text only), or custom view builders. ```APIDOC ## .materialTabItem(tab:label:) A view modifier applied to each top-level tab content view to register it with `MaterialTabBar` and configure its selector label. Supports `.primary` (icon + text), `.secondary` (text only), or a fully custom view builder. ### Usage Examples: #### Primary style — icon above label ```swift scrollView .materialTabItem( tab: Tab.feed, label: .primary("Feed", icon: Image(systemName: "house.fill")) ) ``` #### Secondary style with custom selected/deselected configs ```swift scrollView .materialTabItem( tab: Tab.profile, label: .secondary( "Profile", config: SecondaryTab.Config( font: .system(size: 14, weight: .bold), titleStyle: Color.indigo, underlineThickness: 3 ), deselectedConfig: SecondaryTab.Config( font: .system(size: 14, weight: .regular), titleStyle: Color.secondary ) ) ) ``` #### Fully custom label ```swift scrollView .materialTabItem(tab: Tab.settings) { tab, context, tapped in HStack { Image(systemName: "gear") Text("Settings") .fontWeight(tab == context.selectedTab ? .bold : .regular) } .foregroundColor(tab == context.selectedTab ? .blue : .gray) .frame(maxWidth: .infinity, maxHeight: .infinity) .onTapGesture(perform: tapped) } ``` ``` -------------------------------- ### Fixed Header Style with Scaled Minimum Height Source: https://github.com/swiftkickmobile/swiftuimaterialtabs/blob/main/README.md Combines a shrinking header title with a fixed header style and a scaled minimum height. The `minimumScale` parameter is used to calculate the minimum height based on the scaled size of the title element. ```swift VStack() { Text("Top Title Element"). .padding() .headerStyle( ShrinkHeaderStyle( fade: false, minimumScale: 0.5, offsetFactor: 0, anchor: .top ), context: context ) .headerStyle(FixedHeaderStyle(), context: context) .minTitleHeight(.content(scale: 0.5)) Text("Bottom Title Element") .padding() } ``` -------------------------------- ### Provide Context to View Builders in MaterialTabsScroll Source: https://github.com/swiftkickmobile/swiftuimaterialtabs/blob/main/CHANGELOG.md Add a context argument to the MaterialTabsScroll and StickyHeaderScroll view builders, providing useful metrics, such as the available safe height for content under the header. ```swift Add a context argument to the `MaterialTabsScroll` and `StickyHeaderScroll` view builders, providing useful metrics, such as the available safe height for content under the header. ``` -------------------------------- ### MaterialTabsScroll Source: https://context7.com/swiftkickmobile/swiftuimaterialtabs/llms.txt A ScrollView wrapper for sticky header effects within MaterialTabs. It manages scroll position internally and requires a tab identifier and content. ```APIDOC ## MaterialTabsScroll A lightweight `ScrollView` wrapper required for sticky header scroll effects inside `MaterialTabs`. Pass the associated tab identifier and supply content in a `VStack` or `LazyVStack`. Do not apply `.scrollPosition()` to this view—it is managed internally. ### Basic Usage: ```swift MaterialTabsScroll(tab: Tab.feed) { // scrollContext.safeHeight — total safe height under the header LazyVStack(spacing: 0) { ForEach(items) { ItemRow(item: item) } } } ``` ### With Programmatic Scroll Control (iOS 18+): ```swift @State private var scrollPosition = ScrollPosition(idType: Int.self) MaterialTabsScroll(tab: Tab.feed, scrollPosition: $scrollPosition) { LazyVStack(spacing: 0) { ForEach(0..<50) { Text("Row \(i)").id(i).padding() } } .scrollTargetLayout() } ``` ### Legacy Programmatic Scroll (iOS 17): ```swift @State private var scrollItem: Int? @State private var scrollUnitPoint: UnitPoint = .top MaterialTabsScroll( tab: Tab.feed, reservedItem: -1, // any unique ID not used in your content scrollItem: $scrollItem, scrollUnitPoint: $scrollUnitPoint ) { LazyVStack(spacing: 0) { ForEach(0..<50) { Text("Row \(i)").id(i).padding() } } .scrollTargetLayout() } ``` ``` -------------------------------- ### Track Content Offset for Header Animation Source: https://context7.com/swiftkickmobile/swiftuimaterialtabs/llms.txt Use `StickyHeaderScroll` within `StickyHeader` to track content offset for header animations. It provides `StickyHeaderScrollContext` with `safeHeight` and `contentHeight`. ```swift StickyHeaderScroll { scrollContext in // scrollContext.safeHeight — height of the device safe area // scrollContext.contentHeight — height available below the header VStack(spacing: 8) { ForEach(rows) { RowView(row: row) } // Pin content to full screen height when short Spacer(minLength: scrollContext.contentHeight - CGFloat(rows.count) * 60) } } ``` -------------------------------- ### Applying ParallaxHeaderStyle for Depth Effect Source: https://context7.com/swiftkickmobile/swiftuimaterialtabs/llms.txt Implement ParallaxHeaderStyle to move header elements at a fraction of the scroll speed, creating a parallax depth effect. Commonly used for background images. ```swift headerBackground: { context in Image(.heroPhoto) .resizable() .aspectRatio(contentMode: .fill) .headerStyle( ParallaxHeaderStyle(amount: 0.35, fade: false), context: context ) } ``` -------------------------------- ### Shrink and Fade Out Header Title Source: https://github.com/swiftkickmobile/swiftuimaterialtabs/blob/main/README.md Applies a style that shrinks and fades out the header title as it scrolls. This is useful for a more compact header appearance. ```swift Text("Header Title") .padding() .headerStyle(ShrinkHeaderStyle(), context: context) ``` -------------------------------- ### StickyHeaderScroll Source: https://context7.com/swiftkickmobile/swiftuimaterialtabs/llms.txt Used within StickyHeader to track content offset for header animations. It provides scroll context including safe height and content height. ```APIDOC ## StickyHeaderScroll Analogous to `MaterialTabsScroll` but for use inside `StickyHeader`. Tracks content offset to drive header animation. Receives a `StickyHeaderScrollContext` providing `safeHeight` and `contentHeight` metrics. ### Usage Example: ```swift StickyHeaderScroll { // scrollContext.safeHeight — height of the device safe area // scrollContext.contentHeight — height available below the header VStack(spacing: 8) { ForEach(rows) { RowView(row: row) } // Pin content to full screen height when short Spacer(minLength: scrollContext.contentHeight - CGFloat(rows.count) * 60) } } ``` ``` -------------------------------- ### Using FixedHeaderStyle for Pinned Elements Source: https://context7.com/swiftkickmobile/swiftuimaterialtabs/llms.txt Apply FixedHeaderStyle to pin a header element in place while the rest scrolls away. Combine with .minTitleHeight() for persistent navigation bar-like titles. ```swift headerTitle: { context in VStack(spacing: 0) { // This element stays fixed at the top HStack { Image(systemName: "arrow.left") Spacer() Text("Details") .font(.headline) Spacer() } .padding() .headerStyle(FixedHeaderStyle(), context: context) .minTitleHeight(.content(scale: 1)) // This element scrolls away Text("Long Scrollable Subtitle") .font(.subheadline) .padding([.horizontal, .bottom]) .headerStyle(OffsetHeaderStyle(fade: true), context: context) } } ``` -------------------------------- ### MaterialTabsScroll with Scroll Position Control Source: https://github.com/swiftkickmobile/swiftuimaterialtabs/blob/main/README.md Utilize MaterialTabsScroll with scrollItem and scrollUnitPoint bindings for joint manipulation of scroll position across tabs. A reservedItem identifier is required for precise control. ```swift @State var scrollItem: Int? @State var scrollUnitPoint: UnitPoint = .top ... content: { MaterialTabsScroll(tab: Tab.first, reservedItem: -1, scrollItem: $scrollItem, scrollUnitPoint: $scrollUnitPoint) { _ in LazyVStack(spacing: 0) { ForEach(0..<10) { Text("Row \(index)") .padding() } } .scrollTargetLayout() } .materialTabItem(tab: Tab.first, label: .secondary("First")) } ``` -------------------------------- ### Embed Scrollable Content in MaterialTabsScroll Source: https://github.com/swiftkickmobile/swiftuimaterialtabs/blob/main/README.md Wrap scrollable content within MaterialTabsScroll to enable sticky header effects. The content is typically placed in a VStack or LazyVStack. ```swift content: { MaterialTabsScroll(tab: Tab.first) { _ in LazyVStack { ForEach(0..<10) { Text("Row \(index)") .padding() } } } .materialTabItem(tab: Tab.first, label: .secondary("First")) } ``` -------------------------------- ### Applying OffsetHeaderStyle for Fading Effect Source: https://context7.com/swiftkickmobile/swiftuimaterialtabs/llms.txt Use OffsetHeaderStyle to track header offset and optionally fade the view as it scrolls out of sight. Typically applied to title text. ```swift headerTitle: { context in Text("Article Title") .font(.largeTitle.bold()) .padding() .headerStyle(OffsetHeaderStyle(fade: true), context: context) } ``` -------------------------------- ### Parallax Effect for Header Background Image Source: https://github.com/swiftkickmobile/swiftuimaterialtabs/blob/main/README.md Applies a parallax scrolling effect to a background image within the header. This creates a sense of depth as the user scrolls. ```swift Image(.coolBackground) .resizable() .aspectRatio(contentMode: .fill) .headerStyle(ParallaxHeaderStyle(), context: context) ``` -------------------------------- ### Fade Out Header Title with OffsetHeaderStyle Source: https://github.com/swiftkickmobile/swiftuimaterialtabs/blob/main/README.md Applies a fade-out effect to the header title as it scrolls off-screen. This modifier should be applied to the header title view. ```swift Text("Header Title") .padding() .headerStyle(OffsetHeaderStyle(fade: true), context: context) ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.