Skip to content

Latest commit

 

History

History
 
 

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 

FloatingPanel

A floating panel is a view that overlays a view and supplies view-related content. For a map view, for instance, it could display a legend, bookmarks, search results, etc.. Apple Maps, Google Maps, Windows 10, and Collector have floating panel implementations, sometimes referred to as a "bottom sheet".

Floating panels are non-modal and primarily simple containers that clients will fill with their own content. They can be transient where they only display information for a short period of time, like identify results. Or they can be persistent, where the information is always displayed, such as a dedicated search panel.

The floating panel allows for interaction with background content, unlike native sheets or popovers.

The following images are of a simple list of numbers in a floating panel.

iPhone iPad
image image

Features:

FloatingPanel:

  • Can display any custom content.
  • Can be resized by dragging the panel's handle.
  • Has three predefined height settings, called "detents", that the panel will snap to when the user drags and releases the handle.
  • Can be configured with a custom detent, specifying either a fraction of the maximum height or a fixed value.
  • Is displayed using the .floatingPanel view modifier.

Key properties

FloatingPanel exposes the following view modifier:

    /// - Parameters:
    ///   - backgroundColor: The background color of the floating panel.
    ///   - selectedDetent: A binding to the currently selected detent.
    ///   - horizontalAlignment: The horizontal alignment of the floating panel.
    ///   - isPresented: A binding to a Boolean value that determines whether the view is presented.
    ///   - maxWidth: The maximum width of the floating panel.
    ///   - content: A closure that returns the content of the floating panel.
    /// - Returns: A dynamic view with a presentation style similar to that of a sheet in compact
    /// environments and a popover otherwise.
    func floatingPanel<Content>(
        backgroundColor: Color = Color(uiColor: .systemBackground),
        selectedDetent: Binding<FloatingPanelDetent> = .constant(.half),
        horizontalAlignment: HorizontalAlignment = .trailing,
        isPresented: Binding<Bool> = .constant(true),
        maxWidth: CGFloat = 400,
        _ content: @escaping () -> Content
    ) -> some View where Content: View

Behavior:

Content in a floating panel can be resized using a “handle” on the bottom (for regular-width environments) or on the top (compact-width environments).

The height of the floating panel is determined by a selected “detent”. There are pre-defined detents for full screen height, half screen height, and a “summary” height, along with the ability to set custom detent heights. Dragging and releasing the handle will snap the floating panel height to the nearest detent.

The floating panel is displayed via a view modifier that allows you to set the content of the floating panel along with a number of other properties, including:

  • backgroundColor: The background color of the floating panel.
  • selectedDetent: A binding to the currently selected detent.
  • horizontalAlignment: The horizontal alignment of the floating panel.
  • maxWidth: The maximum width of the floating panel.

Usage

MapView(
    map: map
)
.floatingPanel() {
    List(1..<21) { Text("\($0)") }
        .listStyle(.plain)
}

To see it in action, try out the Examples and refer to FloatingPanelExampleView.swift in the project.