DynamicOverlay 1.1.0-beta.2

DynamicOverlay 1.1.0-beta.2

Gaétan Zanella 维护。



DynamicOverlay 1.1.0-beta.2

  • gaetanzanella

DynamicOverlay

DynamicOverlay 是一个 SwiftUI 库。它使得开发基于覆盖层的界面更加容易,例如在 Apple Maps、Stocks 或 Shortcuts 应用中展示的界面。

Platform Swift5 CocoaPods Carthage Build Status License


要求

DynamicOverlay 使用 Swift 5 编写。兼容 iOS 13.0+。

开始使用

动态叠加层是一种动态显示或隐藏其下方内容的叠加层。

您可以使用视图修饰符将动态叠加层作为一个普通叠加层添加。

Color.blue.dynamicOverlay(Color.red)

如果与它关联的,其行为由DynamicOverlayBehavior定义。

Color.blue
    .dynamicOverlay(Color.red)
    .dynamicOverlayBehavior(myOverlayBehavior)

var myOverlayBehavior: some DynamicOverlayBehavior {
    ...
}

如果您在叠加层视图层次结构中没有指定行为,它将使用默认行为。

示例

最小值 最大值

磁性凹槽叠加

MagneticNotchOverlayBehavior是一个DynamicOverlayBehavior实例。是目前唯一可用的行为。

它描述了一个可以沿着预定义的凹槽上下拖动的叠加层。每次拖动手势结束,叠加层的运动将继续,直到它到达其中之一。

指定凹槽

定义凹槽的最佳方式是声明一个CaseIterable枚举。

enum Notch: CaseIterable, Equatable {
    case min, max
}

创建一个MagneticNotchOverlayBehavior实例时,您指定每个凹槽的尺寸。

@State var isCompact = false

var myOverlayBehavior: some DynamicOverlayBehavior {
    MagneticNotchOverlayBehavior<Notch> { notch in
        switch notch {
        case .max:
            return isCompact ? .fractional(0.5) : .fractional(0.8)
        case .min:
            return .fractional(0.3)
        }
    }
}

有两种尺寸类型

extension NotchDimension {

    /// Creates a dimension with an absolute point value.
    static func absolute(_ value: Double) -> NotchDimension

    /// Creates a dimension that is computed as a fraction of the height of the overlay parent view.
    static func fractional(_ value: Double) -> NotchDimension
}

支持拖拽手势

默认情况下,覆盖层中的所有内容都可以拖拽,但您可以使用draggable视图修饰符限制此行为。

在这种情况下,仅列表标题可拖拽。

var body: some View {
    Color.green
        .dynamicOverlay(myOverlayContent)
        .dynamicOverlayBehavior(myOverlayBehavior)
}

var myOverlayContent: some View {
    VStack {
        Text("Header").draggable()
        List {
            Text("Row 1")
            Text("Row 2")
            Text("Row 3")
        }
    }
}

var myOverlayBehavior: some DynamicOverlayBehavior {
    MagneticNotchOverlayBehavior<Notch> { ... }
}

在此处完全禁用拖拽手势。

var myOverlayContent: some View {
    VStack {
        Text("Header")
        List {
            Text("Row 1")
            Text("Row 2")
            Text("Row 3")
        }
    }
    .draggable(false)
}

支持滑动视图

磁性凹口覆盖层可以与其滑动视图的滚动同步运动。

使用drivingScrollView()标记应指派覆盖层运动的ScrollView或列表。

var myOverlayContent: some View {
    VStack {
        Text("Header").draggable()
        List {
            Text("Row 1")
            Text("Row 2")
            Text("Row 3")
        }
        .drivingScrollView()
    }
}

对覆盖层更新的响应

您可以使用onTranslation(_:)视图修饰符跟踪覆盖层运动。这是根据当前覆盖层状态更新UI的好时机。

在此我们定义一个应位于覆盖层正上方的控件。

struct ControlView: View {

    let height: CGFloat
    let action: () -> Void

    var body: some View {
        VStack {
            Button("Action", action: action)
            Spacer().frame(height: height)
        }
    }
}

通过使用转换参数,确保控件始终可见。

@State var height: CGFloat = 0.0

var body: some View {
    ZStack {
        Color.blue
        ControlView(height: height, action: {})
    }
    .dynamicOverlay(Color.red)
    .dynamicOverlayBehavior(myOverlayBehavior)
}

var myOverlayBehavior: some DynamicOverlayBehavior {
    MagneticNotchOverlayBehavior<Notch> { ... }
    .onTranslation { translation in
        height = translation.height
    }
}

您还可以使用绑定来通知凹口已到达。

@State var notch: Notch = .min

var body: some View {
    Color.blue
        .dynamicOverlay(Text("\(notch)"))
        .dynamicOverlayBehavior(myOverlayBehavior)
}

var myOverlayBehavior: some DynamicOverlayBehavior {
    MagneticNotchOverlayBehavior<Notch> { ... }
    .notchChange($notch)
}

移动覆盖层

您可以使用凹口绑定显式移动覆盖层。

@State var notch: Notch = .min

var body: some View {
    ZStack {
        Color.green
        Button("Move to top") {
            notch = .max
        }
    }
    .dynamicOverlay(Color.red)
    .dynamicOverlayBehavior(myOverlayBehavior)
}

var myOverlayBehavior: some DynamicOverlayBehavior {
    MagneticNotchOverlayBehavior<Notch> { ... }
    .notchChange($notch)
}

将更改封装在动画块中,以使更改动画化。

Button("Move to top") {
    withAnimation {
        notch = .max
    }
}

禁用凹口

当禁用凹口时,覆盖层将忽略它。这里我们在其min位置上阻塞覆盖层

@State var notch: Notch = .max

var myOverlayBehavior: some DynamicOverlayBehavior {
    MagneticNotchOverlayBehavior<Notch> { ... }
    .notchChange($notch)
    .disable(.max, notch == .min)
}

在下面的小节中

DynamicOverlay构建在OverlayContainer之上。如果您需要更多的控制,请考虑使用它或创建一个问题。

安装

DynamicOverlay通过CocoaPods可用。要安装它,只需将以下行添加到您的Podfile中即可

Cocoapods

pod 'DynamicOverlay'

Carthage

将以下内容添加到您的Cartfile中

github "https://github.com/fabernovel/DynamicOverlay"

Swift 包管理器

DynamicOverlay 可以通过 Xcode 11 或更高版本安装。要安装它,请使用 Xcode 添加包,或将依赖关系添加到您的 Package.swift 文件中。

.package(url: "https://github.com/fabernovel/DynamicOverlay.git")

发布

  • 为新版本创建发布分支(release/#版本#)
  • 更新 CHANGELOG.md(请确保您发布的版本拼写正确)
  • 推送您的发布分支
  • 从您的发布分支运行 发布工作流

作者

@gaetanzanella[email protected]

许可证

DynamicOverlay 在 MIT 许可证下可用。有关更多信息,请参阅 LICENSE 文件。