Created
April 3, 2022 10:31
-
-
Save saltyskip/5981722bd44411101baf69a2ea1f9d6e to your computer and use it in GitHub Desktop.
This file contains 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
// | |
// CollapsibleStackView.swift | |
// TemplateApp | |
// | |
// Created by Andrei Terentiev on 4/3/22. | |
// | |
import Foundation | |
import SwiftUI | |
import UniformTypeIdentifiers | |
struct MyDropDelegate: DropDelegate { | |
let item: String | |
@Binding var items: [String] | |
@Binding var draggedItem: String? | |
func performDrop(info: DropInfo) -> Bool { | |
return true | |
} | |
func dropEntered(info: DropInfo) { | |
guard let draggedItem = self.draggedItem else { | |
return | |
} | |
if draggedItem != item { | |
let from = items.firstIndex(of: draggedItem)! | |
let to = items.firstIndex(of: item)! | |
withAnimation(.default) { | |
self.items.move(fromOffsets: IndexSet(integer: from), toOffset: to > from ? to + 1 : to) | |
} | |
} | |
} | |
} | |
struct CollapsibleStackView<Model>: View where Model: CollapsibleStackViewModelProtocol { | |
@StateObject var viewModel: Model | |
@State var collapsed: Bool = false | |
@State var items = ["Wallet 1", "Wallet 2", "Wallet 3"] | |
@State var draggedItem: String? | |
var body: some View { | |
VStack(spacing: 0) { | |
// Header | |
VStack(spacing: 0) { | |
Text("Header Section") | |
} | |
.frame(maxWidth: .infinity) | |
.onTapGesture { | |
withAnimation { | |
collapsed.toggle() | |
} | |
} | |
.background( | |
Color.white // any non-transparent background | |
.shadow(color: .black.opacity(0.1), radius: 2, x: 0, y: 0) | |
.mask(Rectangle().padding(.bottom, -20)) | |
) | |
// Wallets | |
if collapsed == false { | |
LazyVStack(spacing: 0) { | |
ForEach(items, id: \.self) { item in | |
Text(item) | |
.frame(minWidth: 0, maxWidth: .infinity, minHeight: 50) | |
.onDrag { | |
self.draggedItem = item | |
return NSItemProvider(item: nil, typeIdentifier: item) | |
} | |
.onDrop( | |
of: [UTType.text], | |
delegate: MyDropDelegate(item: item, items: $items, draggedItem: $draggedItem)) | |
} | |
} | |
} | |
// Footer | |
Text("Footer Section") | |
} | |
.frame(maxWidth: .infinity) | |
.padding(.vertical, 16) | |
.padding(.horizontal, 16) | |
.cornerRadius(12) | |
.background( | |
Color.white | |
.padding(.horizontal, 16) | |
.cornerRadius(12) | |
.shadow(color: .black.opacity(0.1), radius: 12, x: 0, y: 0) | |
) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment