• Stars
    star
    413
  • Rank 104,801 (Top 3 %)
  • Language
    Swift
  • License
    BSD 2-Clause "Sim...
  • Created almost 2 years ago
  • Updated about 1 month ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Bridges UIKit presentation APIs to a SwiftUI API so you can use presentation controllers, interactive transitions and more.

Transmission

Transmission aims to improve SwiftUI view presentations and transitions. It does this by bridging UIKit presentation APIs to a SwiftUI API so you can use presentation controllers, interactive transitions and more.

Built using Engine

Preview

Example Preview

Requirements

  • Deployment target: iOS 13.0, macOS 10.15, tvOS 13.0, or watchOS 6.0
  • Xcode 14.1+

Installation

Xcode Projects

Select File -> Swift Packages -> Add Package Dependency and enter https://github.com/nathantannar4/Transmission.

Swift Package Manager Projects

You can add Transmission as a package dependency in your Package.swift file:

let package = Package(
    //...
    dependencies: [
        .package(url: "https://github.com/nathantannar4/Transmission"),
    ],
    targets: [
        .target(
            name: "YourPackageTarget",
            dependencies: [
                .product(name: "Transmission", package: "Transmission"),
            ],
            //...
        ),
        //...
    ],
    //...
)

Introduction to Transmission

For some sample code to get started with Transmission, build and run the included "Example" project.

PresentationLink

@available(iOS 14.0, *)
public struct PresentationLinkTransition {

    public static var `default`: PresentationLinkTransition

    public static let sheet: PresentationLinkTransition
    public static func sheet(
        selected: Binding<SheetTransitionOptions.Detent.Identifier?>? = nil,
        detents: [SheetTransitionOptions.Detent]
    ) -> PresentationLinkTransition
    
    public static let currentContext: PresentationLinkTransition
    public static let fullscreen: PresentationLinkTransition
    public static let popover: PresentationLinkTransition
    public static let slide: PresentationLinkTransition

    public static func custom<T: PresentationLinkCustomTransition>(_ transition: T) -> PresentationLinkTransition
}

@available(iOS 15.0, *)
extension SheetTransitionOptions.Detent {
    
    /// Creates a large detent.
    public static let large: Detent

    /// Creates a medium detent.
    public static let medium: Detent

    /// Creates a detent with an auto-resolved height of the views ideal size.
    public static let ideal: Detent

    /// Creates a detent with a constant height.
    public static func constant(_ identifier: Identifier, height: CGFloat) -> Detent
    
    /// Creates a detent that's height is lazily resolved.
    public static func custom(
        _ identifier: Identifier,
        resolver: @escaping (ResolutionContext) -> CGFloat?
    ) -> Detent
}

/// A protocol that defines a custom transition for a ``PresentationLinkTransition``
@available(iOS 14.0, *)
public protocol PresentationLinkCustomTransition {

    func presentationController(
        sourceView: UIView,
        presented: UIViewController,
        presenting: UIViewController?
    ) -> UIPresentationController

    func animationController(
        forPresented presented: UIViewController,
        presenting: UIViewController
    ) -> UIViewControllerAnimatedTransitioning?

    func animationController(
        forDismissed dismissed: UIViewController
    ) -> UIViewControllerAnimatedTransitioning?

    func interactionControllerForPresentation(
        using animator: UIViewControllerAnimatedTransitioning
    ) -> UIViewControllerInteractiveTransitioning?

    func interactionControllerForDismissal(
        using animator: UIViewControllerAnimatedTransitioning
    ) -> UIViewControllerInteractiveTransitioning?
}

@available(iOS 14.0, *)
@frozen
public struct PresentationCoordinator {

    public var isPresented: Bool

    @inlinable
    public func dismiss(animation: Animation? = .default)
    
    @inlinable
    public func dismiss(transaction: Transaction)
}

@available(iOS 14.0, *)
extension EnvironmentValues {
    public var presentationCoordinator: PresentationCoordinator { get }
}

/// A button that presents a destination view in a new `UIViewController`.
///
/// The destination view is presented with the provided `transition`.
/// By default, the ``PresentationLinkTransition/default`` transition is used.
///
/// > Tip: You can implement custom transitions with a `UIPresentationController` and/or
/// `UIViewControllerInteractiveTransitioning` with the ``PresentationLinkTransition/custom(_:)``
///  transition.
///
@available(iOS 14.0, *)
@frozen
public struct PresentationLink<
    Label: View,
    Destination: View
>: View {

    public init(
        @ViewBuilder destination: () -> Destination,
        @ViewBuilder label: () -> Label
    )

    public init(
        transition: PresentationLinkTransition = .default,
        @ViewBuilder destination: () -> Destination,
        @ViewBuilder label: () -> Label
    )

    public init(
        isPresented: Binding<Bool>,
        @ViewBuilder destination: () -> Destination,
        @ViewBuilder label: () -> Label
    )

    public init(
        transition: PresentationLinkTransition,
        isPresented: Binding<Bool>,
        @ViewBuilder destination: () -> Destination,
        @ViewBuilder label: () -> Label
    )
}

@available(iOS 14.0, *)
extension PresentationLink {
    public init<ViewController: UIViewController>(
        destination: @escaping () -> ViewController,
        @ViewBuilder label: () -> Label
    )

    public init<ViewController: UIViewController>(
        transition: PresentationLinkTransition,
        destination: @escaping () -> ViewController,
        @ViewBuilder label: () -> Label
    )

    public init<ViewController: UIViewController>(
        isPresented: Binding<Bool>,
        destination: @escaping () -> ViewController,
        @ViewBuilder label: () -> Label
    )

    public init<ViewController: UIViewController>(
        transition: PresentationLinkTransition,
        isPresented: Binding<Bool>,
        destination: @escaping () -> ViewController,
        @ViewBuilder label: () -> Label
    )
}

@available(iOS 14.0, *)
extension PresentationLinkModifier {
    public init(
        transition: PresentationLinkTransition = .default,
        isPresented: Binding<Bool>,
        @ViewBuilder destination: () -> Destination
    )
}

@available(iOS 14.0, *)
extension View {

    /// A modifier that presents a destination view in a new `UIViewController`.
    public func presentation<Destination: View>(
        transition: PresentationLinkTransition = .default,
        isPresented: Binding<Bool>,
        @ViewBuilder destination: () -> Destination
    ) -> some View

    /// A modifier that presents a destination view in a new `UIViewController`.
    public func presentation<T, Destination: View>(
        _ value: Binding<T?>,
        transition: PresentationLinkTransition = .default,
        @ViewBuilder destination: (Binding<T>) -> Destination
    ) -> some View
}

TransitionReader

/// A container view that defines its content as a function of its hosting view's
/// `UIViewControllerTransitionCoordinator` transition progress.
///
/// > Tip: Use a ``TransitionReader`` to build interactive presentation and dismissal
/// transitions
/// 
public struct TransitionReader<Content: View>: View {
    public struct Proxy {
        /// The progress state of the transition from 0 to 1 where 1 is fully presented
        public var progress: CGFloat
    }

    public init(@ViewBuilder content: @escaping (Proxy) -> Content)
}

StatusBar Style/Hidden

@available(iOS 14.0, *)
extension View {

    /// Sets the preferred status bar style of the hosting views `UIViewController`
    public func preferredStatusBarStyle(_ style: UIStatusBarStyle) -> some View

    /// Sets the preferred status bar visibility of the hosting views `UIViewController`
    public func prefersStatusBarHidden(_ isHidden: Bool = true) -> some View
}

WindowLink

@available(iOS 14.0, *)
public struct WindowLinkLevel {

    public static var `default`: WindowLinkLevel

    public static var overlay: WindowLinkLevel

    public static var background: WindowLinkLevel
    
    public static let alert: WindowLinkLevel

    public static func custom(_ level: CGFloat) -> WindowLinkLevel
}

@available(iOS 14.0, *)
public struct WindowLinkTransition {

    public static let identity: WindowLinkTransition

    public static let opacity: WindowLinkTransition

    public static func move(edge: Edge) -> WindowLinkTransition

    public static func scale(_ multiplier: CGFloat) -> WindowLinkTransition
}

extension WindowLinkTransition {
    public func combined(with other: WindowLinkTransition) -> WindowLinkTransition
}

/// A button that presents a destination view in a new `UIWindow`.
@available(iOS 14.0, *)
@frozen
public struct WindowLink<
    Label: View,
    Destination: View
>: View {

    public init(
        level: WindowLinkLevel = .default,
        transition: WindowLinkTransition = .opacity,
        @ViewBuilder destination: () -> Destination,
        @ViewBuilder label: () -> Label
    )

    public init(
        level: WindowLinkLevel = .default,
        transition: WindowLinkTransition = .opacity,
        isPresented: Binding<Bool>,
        @ViewBuilder destination: () -> Destination,
        @ViewBuilder label: () -> Label
    )
}

@available(iOS 14.0, *)
extension View {

    /// A modifier that presents a destination view in a new `UIWindow`
    public func window<Destination: View>(
        level: WindowLinkLevel = .default,
        transition: WindowLinkTransition = .opacity,
        isPresented: Binding<Bool>,
        @ViewBuilder destination: () -> Destination
    ) -> some View

    /// A modifier that presents a destination view in a new `UIWindow`
    public func window<T, D: View>(
        _ value: Binding<T?>,
        level: WindowLinkLevel = .default,
        transition: WindowLinkTransition = .opacity,
        @ViewBuilder destination: (Binding<T>) -> D
    ) -> some View
}

ShareSheetLink

/// A protocol that defines an interface for creating activities for a `UIActivityViewController`
@available(iOS 14.0, *)
public protocol ShareSheetItemProvider {
    func makeUIActivityItemSource(context: Context) -> UIActivityItemSource
    func makeUIActivity(context: Context) -> UIActivity?

    typealias Context = ShareSheetItemProviderContext
}

/// A share sheet provider for a string.
@available(iOS 14.0, *)
extension String: ShareSheetItemProvider {
    public func makeUIActivityItemSource(context: Context) -> UIActivityItemSource
}

/// A share sheet provider for a url.
@available(iOS 14.0, *)
extension URL: ShareSheetItemProvider {
    public func makeUIActivityItemSource(context: Context) -> UIActivityItemSource
}

/// A share sheet provider for generating an image from a view.
@available(iOS 14.0, *)
@frozen
public struct SnapshotItemProvider<Content: View>: ShareSheetItemProvider {

    public init(label: LocalizedStringKey, content: Content) {
        self.label = Text(label)
        self.content = content
    }
}

/// A button that presents a `UIActivityViewController`
@available(iOS 14.0, *)
@frozen
public struct ShareSheetLink<
    Label: View
>: View {

    public init(
        items: [ShareSheetItemProvider],
        action: ((Result<UIActivity.ActivityType?, Error>) -> Void)? = nil,
        @ViewBuilder label: () -> Label
    )

    public init(
        items: [ShareSheetItemProvider],
        action: ((Result<UIActivity.ActivityType?, Error>) -> Void)? = nil,
        isPresented: Binding<Bool>,
        @ViewBuilder label: () -> Label
    )
}

@available(iOS 14.0, *)
extension View {
    
    /// A modifier that presents a `UIActivityViewController`
    public func share(
        items: [ShareSheetItemProvider],
        isPresented: Binding<Bool>,
        action: ((Result<UIActivity.ActivityType?, Error>) -> Void)? = nil
    ) -> some View
}

License

Distributed under the BSD 2-Clause License. See LICENSE.md for more information.

More Repositories

1

InputBarAccessoryView

A simple and easily customizable InputAccessoryView for making powerful input bars with autocomplete and attachments
Swift
1,167
star
2

Engine

Engine makes it easier to create idiomatic APIs and Views that feel natural in SwiftUI without sacrificing performance
Swift
173
star
3

TypingIndicator

A replica of iMessage's typing indicator bubble with support for a variety of animations
Swift
173
star
4

Parse-Dashboard-for-iOS

A beautiful mobile client for managing your Parse apps while you are on the go! Now you can easily view and modify your data in the same way you would on the offical desktop client.
Swift
100
star
5

Turbocharger

Turbocharger aims accelerate SwiftUI development by providing commonly desired views and view modifiers
Swift
70
star
6

DynamicTabBarController

An improved UITabBarController that is dynamic and has a scroll indicator line
Swift
39
star
7

the.phoenix.project

A deployment ready Vapor 3 API template with support for authentication, real-time chat, push notifications, files, email verification
Swift
32
star
8

Ignition

Ignition aims to help make your SwiftUI views feel more interactive. It does this by providing API that makes it easier to run animations.
Swift
22
star
9

MVVM-ViewInjection-Template

MVVM Template that utilizes RxSwift, Generics and more
Swift
14
star
10

NTComponents

An all in one framework for everything I find useful! Improved classes and extensions to accelerate development.
Swift
10
star
11

Safety-Beacon

Term project for CMPT 275: Software Engineering I
Swift
9
star
12

Engage

Engage was my first project utilizing Swift to create a social networking application. I have since removed it from the App Store and no longer work on it.
Swift
6
star
13

AlertHUDKit

A collection of alerts for toasting, pinging and progress messages
Swift
5
star
14

SwiftMiniProjects

Inspired by the many "30 Swift Projects" I thought it best to break create a single workspace and repo for all mini projects I start. These are not projects focused on building an app but rather classes built to be easily integratable with future apps.
Swift
4
star
15

UIKitExtension

UIPageTabBarController & UIDrawerController
Swift
2
star
16

NTToolKit

A collection of extensions I find helpful
Swift
2
star
17

nathantannar.me

My personal website build on top of Vapor using Swift
JavaScript
2
star
18

Contacts-RxSwift-Realm

A contact app using the MVVM architecture, RxSwift and RxCocoa.
Swift
2
star
19

StockApp

Just a simple stock app I threw together to learn SwiftStock and consume some external API information
Swift
2
star
20

StyleKit

Easily apply and keep track of color and font defaults. Includes predefined Google Material Design icons and colors as well as FontAwesome icons
Swift
2
star
21

WEC2018

Swift
1
star
22

ParseServer

A modified parse-server-example fork that I use
JavaScript
1
star
23

Count-on-Us

2016 SAP Hackathon
Swift
1
star
24

XModemFileTransfer

ENSC 351 XModem File Transfer Protocal in C++
C++
1
star
25

Afterburner

UIKit components wrapped in SwiftUI
Swift
1
star
26

VHDL-Code-Parser

Final Project for ENSC 251
C++
1
star
27

EM-2016

Website for the WESST Executives Meeting 2016
PHP
1
star
28

DormHub

Find roommates, places to rent and reviews. CMPT 354 - Database Systems 1 Project
JavaScript
1
star
29

VGA-Controller

A VHDL datapath I implemented to drive a VGA controller to print diagonal lines and triangles from an FPGA
Verilog
1
star
30

Xcode-Templates

1
star
31

WEC2017-Website-and-Delegate-Portal

JavaScript
1
star
32

NTKeyboard

Simple 3rd party keyboard for learning the basic functionality
Swift
1
star