create a bottom expanding view like the one in apple music in swiftui in swift

Here's an example of how you can create a bottom expanding view like the one in Apple Music in SwiftUI. This example uses a combination of GeometryReader and animations to create the expanding and collapsing effect.

main.swift
enum BottomSheetState {
    case minimized
    case half
    case full
}

struct ContentView: View {
    @State private var bottomSheetState: BottomSheetState = .minimized

    var body: some View {
        VStack {
            Spacer()
            BottomSheetView(bottomSheetState: $bottomSheetState)
        }
        .edgesIgnoringSafeArea(.bottom)
    }
}

struct BottomSheetView: View {
    @Binding var bottomSheetState: BottomSheetState
    @GestureState private var translation: CGFloat = 0

    private let maxY = UIScreen.main.bounds.height - 100
    private let minHeight: CGFloat = 100

    var body: some View {
        VStack {
            RoundedRectangle(cornerRadius: 10)
                .frame(width: 60, height: 5)
                .padding()

            Text("Bottom sheet content goes here.")
                .frame(maxWidth: .infinity, minHeight: minHeight)
        }
        .background(Color.white)
        .cornerRadius(10)
        .frame(height: getHeight())
        .gesture(bottomSheetDragGesture)
        .animation(.spring())
    }

    private var bottomSheetDragGesture: some Gesture {
        DragGesture()
            .updating($translation) { value, state, _ in
                state = value.translation.height
            }
            .onEnded(onDragEnded)
    }

    private func onDragEnded(drag: DragGesture.Value) {
        let offset = drag.predictedEndTranslation.height + translation
        let containerHeight = getHeight()

        switch bottomSheetState {
        case .minimized:
            bottomSheetState = offset > containerHeight / 4 ? .half : .minimized
        case .half:
            bottomSheetState = offset > containerHeight / 2 ? .full : .minimized
        case .full:
            bottomSheetState = offset > containerHeight / 4 * 3 ? .full : .half
        }
    }

    private func getHeight() -> CGFloat {
        switch bottomSheetState {
        case .minimized:
            return minHeight
        case .half:
            return maxY / 2
        case .full:
            return maxY
        }
    }
}
2069 chars
75 lines

This will create a ContentView that has a BottomSheetView that can be expanded and collapsed by dragging it up and down.

Note that this is just a basic example and you might need to adjust it based on your specific requirements.

related categories

gistlibby LogSnag