SwiftUIMaterialTabs
SwiftUIMaterialTabs copied to clipboard
content doesn't animate when header size changes. Header animation is janky
- Add some toggle to trigger header height change
- Add .animation or change the toggle value using withAnimation {}
- Header size change animation is janky. Content (with yellow background) doesn't respect the animation and instantly moves to a new position
Environment: iOS18, iPhone 16 pro max simulator. Latest main branch, commit bb97ec4
https://github.com/user-attachments/assets/578e7d92-9ceb-4f3a-b816-2b243444d05f
Code
import SwiftUI
import SwiftUIMaterialTabs
enum Tab: String, Hashable, CaseIterable {
case first
case second
}
struct ContentView: View {
@State var selectedTab: Tab = .first
@State var showMoreHeaderContent = false
var body: some View {
MaterialTabs(
selectedTab: $selectedTab,
headerTitle: { context in
VStack {
Text("Material Tabs")
.font(.title)
if showMoreHeaderContent {
Color.red.frame(height: 130)
}
Text("Some long long description bla\nsecond line of text bla bla bal")
.font(.callout)
.foregroundStyle(.secondary)
}
.animation(.bouncy, value: context.height)
.frame(maxWidth: .infinity)
.geometryGroup()
.padding()
.headerStyle(OffsetHeaderStyle(fade: true), context: context)
},
headerTabBar: { context in
MaterialTabBar(selectedTab: $selectedTab, sizing: .equalWidth, context: context)
},
headerBackground: { context in
Color.white
},
content: {
firstTabContent()
secondTabContent()
}
)
.animation(.default, value: showMoreHeaderContent)
}
@ViewBuilder private func firstTabContent() -> some View {
MaterialTabsScroll(tab: Tab.first) { _ in
LazyVStack {
Button("Show more content in header") {
showMoreHeaderContent.toggle()
}
.padding()
ForEach(0..<100) { index in
Text("Row \(index)")
.padding()
}
}
.background(Color.yellow.opacity(0.2))
}
.materialTabItem(tab: Tab.first, label: .secondary("First"))
}
@ViewBuilder private func secondTabContent() -> some View {
MaterialTabsScroll(tab: Tab.second) { _ in
LazyVStack {
ForEach(0..<100) { index in
Text("Row \(index)")
.padding()
}
}
}
.materialTabItem(tab: Tab.second, label: .secondary("Second"))
}
}