Last active
April 13, 2025 10:18
-
-
Save Codelaby/8fbbf50ef965efbb0fa36ff7d6df05d2 to your computer and use it in GitHub Desktop.
Expandable Floating Action Button
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import SwiftUI | |
// MARK: Expandable Floating Action Button | |
struct ExpandableFAB<Content: View>: View { | |
@Binding var isPresented: Bool | |
@ViewBuilder var content: Content | |
var body: some View { | |
VStack { | |
// Sub FABs | |
Group(subviews: content) { collection in | |
ForEach(Array(collection.enumerated()), id: \.element.id) { index, subview in | |
subview | |
.scaleEffect(isPresented ? 1 : 0.1) | |
.opacity(isPresented ? 1.0 : 0.0) | |
.animation( | |
.snappy | |
.delay(isPresented ? Double(collection.count - index) * 0.1 : Double(index) * 0.1), | |
value: isPresented | |
) | |
} | |
} | |
// FAB | |
Button("FAB", systemImage: "plus") { | |
isPresented.toggle() | |
} | |
.buttonStyle(.borderedProminent) | |
.controlSize(.large) | |
.labelStyle(.iconOnly) | |
.clipShape(.circle) | |
.rotationEffect(.degrees(isPresented ? 45 : 0)) | |
.animation(.spring, value: isPresented) | |
.shadow(radius: 5) } | |
} | |
} | |
// MARK: Sub FAB Style | |
struct SubFABStyle: ButtonStyle { | |
func makeBody(configuration: Configuration) -> some View { | |
configuration.label | |
.imageScale(.small) | |
.labelStyle(.iconOnly) | |
.padding(10) | |
.background( | |
Circle() | |
.fill(Color.accentColor) | |
.opacity(configuration.isPressed ? 0.8 : 1.0) | |
) | |
} | |
} | |
// MARK: Playground | |
#Preview("Expand top") { | |
@Previewable @State var isExpanded = false | |
NavigationStack { | |
List(0..<100) { i in | |
Text("Item \(i)") | |
} | |
.navigationTitle("Expandable FAB") | |
} | |
.overlay(alignment: .bottomTrailing) { // FAB placement | |
ExpandableFAB(isPresented: $isExpanded) { | |
Button("edit", systemImage: "pencil") { | |
isExpanded = false | |
print("action prencil") | |
} | |
.buttonStyle(SubFABStyle()) | |
Button("camera", systemImage: "camera") { | |
isExpanded = false | |
print("action camera") | |
} | |
.buttonStyle(SubFABStyle()) | |
Button("trash", systemImage: "trash") { | |
isExpanded = false | |
print("action trash") | |
} | |
.buttonStyle(SubFABStyle()) | |
} | |
.accentColor(.black) | |
.foregroundStyle(.white) | |
//.padding(8) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment