Skip to content

Instantly share code, notes, and snippets.

@robb
Created October 9, 2023 13:54
Show Gist options
  • Save robb/b262fe83baabace03cfd65581d1a01bd to your computer and use it in GitHub Desktop.
Save robb/b262fe83baabace03cfd65581d1a01bd to your computer and use it in GitHub Desktop.
import SwiftUI
struct Item: Identifiable {
let id = UUID()
let title = "Hello"
}
let items = [
Item(),
Item(),
Item(),
Item(),
Item(),
Item(),
Item(),
Item(),
Item(),
Item(),
Item(),
Item(),
Item(),
Item(),
Item(),
Item(),
Item(),
Item(),
]
struct ContentView: View {
@State private var animated = true
var body: some View {
NavigationStack {
Toggle("Animated", isOn: $animated).padding()
List {
ForEach(items) { item in
Cell(item: item, animated: animated)
}
}
}
}
struct Cell : View {
@State private var isExpanded = false
let item : Item
let animated : Bool
private func toggle() {
if animated {
withAnimation { isExpanded.toggle() }
}
else {
isExpanded.toggle()
}
}
var body: some View {
Label {
VStack {
HStack {
Text(verbatim: item.title)
Spacer()
Image(systemName: "battery.75percent")
}
.transaction { t in
t.animation = nil
}
if isExpanded {
VStack {
Text("More")
Text("Info")
Text("on item")
}
}
}
} icon: {
Image(systemName: "lightswitch.on.square")
}
.contentShape(Rectangle())
.onTapGesture(perform: toggle)
.labelStyle(CustomLabelStyle())
}
}
}
struct CustomLabelStyle: LabelStyle {
struct CustomLayout: Layout {
func sizeThatFits(proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) -> CGSize {
if proposal.height == 36 {
return subviews.first?.sizeThatFits(proposal) ??
proposal.replacingUnspecifiedDimensions()
} else {
var size = subviews.first?.sizeThatFits(proposal) ??
proposal.replacingUnspecifiedDimensions()
size.height -= 14
return size
}
}
func placeSubviews(in bounds: CGRect, proposal: ProposedViewSize, subviews: Subviews, cache: inout ()) {
}
}
func makeBody(configuration: Configuration) -> some View {
CustomLayout {
HStack(alignment: .firstTextBaseline, spacing: 16) {
configuration.icon
.frame(minWidth: 28, minHeight: 36)
.imageScale(.large)
.foregroundColor(.accentColor)
.transaction { t in
t.animation = nil
}
configuration.title
}
}
}
}
#Preview {
ContentView()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment