Repository: MAJKFL/Welcome-Sheet
Branch: main
Commit: 93332013d325
Files: 61
Total size: 166.2 KB
Directory structure:
gitextract_z12ur_l3/
├── .gitignore
├── .swiftpm/
│ └── xcode/
│ └── package.xcworkspace/
│ └── xcshareddata/
│ └── IDEWorkspaceChecks.plist
├── Demo/
│ ├── UIKit-Storyboard-WelcomeSheetDemo/
│ │ ├── Readme.md
│ │ ├── UIKit-Storyboard-WelcomeSheetDemo/
│ │ │ ├── AppDelegate.swift
│ │ │ ├── Assets.xcassets/
│ │ │ │ ├── AccentColor.colorset/
│ │ │ │ │ └── Contents.json
│ │ │ │ ├── AppIcon.appiconset/
│ │ │ │ │ └── Contents.json
│ │ │ │ ├── Contents.json
│ │ │ │ └── gears.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── Base.lproj/
│ │ │ │ ├── LaunchScreen.storyboard
│ │ │ │ └── Main.storyboard
│ │ │ ├── Info.plist
│ │ │ ├── SceneDelegate.swift
│ │ │ └── ViewController.swift
│ │ └── UIKit-Storyboard-WelcomeSheetDemo.xcodeproj/
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── UIKit-WelcomeSheetDemo/
│ │ ├── UIKit-WelcomeSheetDemo/
│ │ │ ├── AppDelegate.swift
│ │ │ ├── Assets.xcassets/
│ │ │ │ ├── AccentColor.colorset/
│ │ │ │ │ └── Contents.json
│ │ │ │ ├── AppIcon.appiconset/
│ │ │ │ │ └── Contents.json
│ │ │ │ ├── Contents.json
│ │ │ │ └── gears.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── Base.lproj/
│ │ │ │ ├── LaunchScreen.storyboard
│ │ │ │ └── Main.storyboard
│ │ │ ├── Info.plist
│ │ │ ├── SceneDelegate.swift
│ │ │ └── ViewController.swift
│ │ └── UIKit-WelcomeSheetDemo.xcodeproj/
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── WelcomeSheetDemo/
│ ├── Shared/
│ │ ├── Assets.xcassets/
│ │ │ ├── AccentColor.colorset/
│ │ │ │ └── Contents.json
│ │ │ ├── AppIcon.appiconset/
│ │ │ │ └── Contents.json
│ │ │ ├── Contents.json
│ │ │ └── gears.imageset/
│ │ │ └── Contents.json
│ │ ├── ContentView.swift
│ │ ├── WelcomeSheetDemoApp.swift
│ │ └── demo.json
│ ├── WelcomeSheetDemo.xcodeproj/
│ │ └── project.pbxproj
│ └── macOS/
│ └── macOS.entitlements
├── Documentation/
│ └── UIKit/
│ └── Readme.md
├── LICENSE
├── Package.swift
├── README.md
└── Sources/
└── WelcomeSheet/
├── Dimensions/
│ ├── iPadSheetDimensions.swift
│ └── iPhoneDimensions.swift
├── Extensions/
│ ├── AnyView+Extensitons.swift
│ ├── Color+Extensions.swift
│ ├── UIColor+Extensions.swift
│ └── UIImage+Extensions.swift
├── Models/
│ ├── UIWelcomeSheetPage.swift
│ ├── UIWelcomeSheetPageRow.swift
│ ├── WelcomeSheetPage.swift
│ └── WelcomeSheetPageRow.swift
├── Views/
│ ├── HorizontalAlignment.swift
│ ├── OptionalButtonView.swift
│ ├── ScrollOnlyOnOverflow.swift
│ ├── WelcomeSheetModal.swift
│ ├── WelcomeSheetPageView.swift
│ └── WelcomeSheetView.swift
├── WelcomeSheet.swift
├── WelcomeSheetController.swift
└── WelcomeSheetStoryboardController.swift
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
.DS_Store
/.build
/Packages
/*.xcodeproj
xcuserdata/
DerivedData/
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
================================================
FILE: .swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
================================================
FILE: Demo/UIKit-Storyboard-WelcomeSheetDemo/Readme.md
================================================
# UIKit Storyboard WelcomeSheet Demo
For a step-by-step guide on how to configure by storyboards, please see the [Documentation](../../Documentation/UIKit/Readme.md)
================================================
FILE: Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo/AppDelegate.swift
================================================
//
// AppDelegate.swift
// UIKit-Storyboard-WelcomeSheetDemo
//
// Created by Eskil Gjerde Sviggum on 18/01/2023.
//
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}
================================================
FILE: Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo/Assets.xcassets/AccentColor.colorset/Contents.json
================================================
{
"colors" : [
{
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.769",
"green" : "0.682",
"red" : "0.353"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo/Assets.xcassets/AppIcon.appiconset/Contents.json
================================================
{
"images" : [
{
"filename" : "1024.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo/Assets.xcassets/Contents.json
================================================
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo/Assets.xcassets/gears.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "settings-gears.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo/Base.lproj/LaunchScreen.storyboard
================================================
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>
================================================
FILE: Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo/Base.lproj/Main.storyboard
================================================
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21507" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
<capability name="Image references" minToolsVersion="12.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="UIKit_Storyboard_WelcomeSheetDemo" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="aZk-kz-NN5">
<rect key="frame" x="140" y="421" width="113" height="35"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="plain" title="Show sheet"/>
<connections>
<segue destination="wSc-U9-mbO" kind="show" id="Dav-6d-i9Z"/>
</connections>
</button>
</subviews>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="aZk-kz-NN5" firstAttribute="centerX" secondItem="6Tk-OE-BBY" secondAttribute="centerX" id="Ntg-ty-FqX"/>
<constraint firstItem="aZk-kz-NN5" firstAttribute="centerY" secondItem="6Tk-OE-BBY" secondAttribute="centerY" id="laf-ey-900"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-474" y="-9"/>
</scene>
<!--Welcome Sheet Storyboard Controller-->
<scene sceneID="g5V-Rl-cAY">
<objects>
<viewController id="wSc-U9-mbO" customClass="WelcomeSheetStoryboardController" customModule="WelcomeSheet" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="hYR-T5-H5T">
<rect key="frame" x="0.0" y="0.0" width="393" height="783"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<viewLayoutGuide key="safeArea" id="wpQ-6y-NkU"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
</view>
<navigationItem key="navigationItem" id="cz2-V1-5ZD"/>
<connections>
<outletCollection property="pages" destination="w5l-MJ-fFT" collectionClass="NSMutableArray" id="0BP-Vc-Kh4"/>
<outletCollection property="pages" destination="xQK-Qv-ynw" collectionClass="NSMutableArray" id="wih-KP-Fyu"/>
<outletCollection property="pages" destination="3P9-yZ-Obt" collectionClass="NSMutableArray" id="oQJ-qQ-t2D"/>
<outletCollection property="pages" destination="uEx-Tk-d3j" collectionClass="NSMutableArray" id="b5e-J6-3qd"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Qfn-oK-HbK" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
<customObject id="w5l-MJ-fFT" customClass="UIWelcomeSheetPage" customModule="WelcomeSheet">
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="title" value="Welcome to Welcome Sheet"/>
<userDefinedRuntimeAttribute type="color" keyPath="accentColor">
<color key="value" systemColor="systemPurpleColor"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="string" keyPath="optionalButtonTitle" value="About Welcome Sheet..."/>
<userDefinedRuntimeAttribute type="string" keyPath="optionalButtonURL" value="https://github.com/MAJKFL/Welcome-Sheet"/>
</userDefinedRuntimeAttributes>
<connections>
<outletCollection property="rows" destination="VMc-pg-0aM" collectionClass="NSMutableArray" id="CTb-UH-6aO"/>
<outletCollection property="rows" destination="Mx5-HU-xig" collectionClass="NSMutableArray" id="lb8-Hd-qbT"/>
<outletCollection property="rows" destination="gqg-iL-fVk" collectionClass="NSMutableArray" id="fon-1L-hpS"/>
</connections>
</customObject>
<customObject id="VMc-pg-0aM" customClass="UIWelcomeSheetPageRow" customModule="WelcomeSheet">
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="color" keyPath="accentColor">
<color key="value" systemColor="systemMintColor"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="string" keyPath="title" value="Quick Creation"/>
<userDefinedRuntimeAttribute type="string" keyPath="content" value="It's incredibly intuitive. Simply declare an array of pages filled with content."/>
<userDefinedRuntimeAttribute type="image" keyPath="image">
<imageReference key="value" image="rectangle.stack.fill.badge.plus" catalog="system" symbolScale="default"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</customObject>
<customObject id="Mx5-HU-xig" customClass="UIWelcomeSheetPageRow" customModule="WelcomeSheet">
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="color" keyPath="accentColor">
<color key="value" systemColor="systemIndigoColor"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="string" keyPath="title" value="Highly Customisable"/>
<userDefinedRuntimeAttribute type="string" keyPath="content" value="Match sheet's appearance to your app, link buttons, perform actions after dismissal."/>
<userDefinedRuntimeAttribute type="image" keyPath="image" value="gears"/>
</userDefinedRuntimeAttributes>
</customObject>
<customObject id="gqg-iL-fVk" customClass="UIWelcomeSheetPageRow" customModule="WelcomeSheet">
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="color" keyPath="accentColor">
<color key="value" systemColor="systemGreenColor"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="string" keyPath="title" value="Works out of the box"/>
<userDefinedRuntimeAttribute type="string" keyPath="content" value="Don't worry about various screen sizes. It will look gorgeous on every iOS device."/>
<userDefinedRuntimeAttribute type="image" keyPath="image">
<imageReference key="value" image="ipad.and.iphone" catalog="system" symbolScale="default"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</customObject>
<customObject id="xQK-Qv-ynw" customClass="UIWelcomeSheetPage" customModule="WelcomeSheet">
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="title" value="What's New in Translate"/>
<userDefinedRuntimeAttribute type="string" keyPath="mainButtonTitle" value="Wassup?"/>
</userDefinedRuntimeAttributes>
<connections>
<outletCollection property="rows" destination="eek-ZA-X6h" collectionClass="NSMutableArray" id="dq5-Yd-e2h"/>
<outletCollection property="rows" destination="7JK-8p-Gwq" collectionClass="NSMutableArray" id="4eo-Qu-hGd"/>
<outletCollection property="rows" destination="7ec-m2-wg8" collectionClass="NSMutableArray" id="DIf-A6-g1m"/>
</connections>
</customObject>
<customObject id="eek-ZA-X6h" customClass="UIWelcomeSheetPageRow" customModule="WelcomeSheet">
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="image" keyPath="image">
<imageReference key="value" image="platter.2.filled.iphone" catalog="system" symbolScale="default"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="string" keyPath="content" value="Choose a side-by-side or face-to-face conversation view."/>
<userDefinedRuntimeAttribute type="string" keyPath="title" value="Conversation Views"/>
</userDefinedRuntimeAttributes>
</customObject>
<customObject id="7JK-8p-Gwq" customClass="UIWelcomeSheetPageRow" customModule="WelcomeSheet">
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="image" keyPath="image">
<imageReference key="value" image="mic.badge.plus" catalog="system" symbolScale="default"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="string" keyPath="content" value="Respond in conversations without tapping the microphone button."/>
<userDefinedRuntimeAttribute type="string" keyPath="title" value="Auto Translate"/>
</userDefinedRuntimeAttributes>
</customObject>
<customObject id="7ec-m2-wg8" customClass="UIWelcomeSheetPageRow" customModule="WelcomeSheet">
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="image" keyPath="image">
<imageReference key="value" image="iphone" catalog="system" symbolScale="default"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="string" keyPath="content" value="Translate selected text anywhere on your iPhone."/>
<userDefinedRuntimeAttribute type="string" keyPath="title" value="System-Wide Translation"/>
</userDefinedRuntimeAttributes>
</customObject>
<customObject id="3P9-yZ-Obt" customClass="UIWelcomeSheetPage" customModule="WelcomeSheet">
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="title" value="Welcome to Reminders"/>
<userDefinedRuntimeAttribute type="color" keyPath="accentColor">
<color key="value" systemColor="systemBlueColor"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
<connections>
<outletCollection property="rows" destination="Qtg-f6-rtp" collectionClass="NSMutableArray" id="xFY-ou-4Pj"/>
<outletCollection property="rows" destination="SnT-cV-GNR" collectionClass="NSMutableArray" id="gZ2-sN-rYi"/>
<outletCollection property="rows" destination="3ku-ur-HfQ" collectionClass="NSMutableArray" id="wIs-4M-kk9"/>
</connections>
</customObject>
<customObject id="Qtg-f6-rtp" customClass="UIWelcomeSheetPageRow" customModule="WelcomeSheet">
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="color" keyPath="accentColor">
<color key="value" systemColor="systemGreenColor"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="string" keyPath="title" value="Quick Creation"/>
<userDefinedRuntimeAttribute type="string" keyPath="content" value="Simply type, ask Siri, or use the quick toolbar to create reminders."/>
<userDefinedRuntimeAttribute type="image" keyPath="image">
<imageReference key="value" image="note.text.badge.plus" catalog="system" symbolScale="default"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</customObject>
<customObject id="SnT-cV-GNR" customClass="UIWelcomeSheetPageRow" customModule="WelcomeSheet">
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="color" keyPath="accentColor">
<color key="value" red="0.0" green="0.69803921568627447" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="string" keyPath="title" value="Easy Organizing"/>
<userDefinedRuntimeAttribute type="string" keyPath="content">
<string key="value">Create lists to match your needs and categorize reminders with tags. Collaborate with others by sharing lists and assigning individual tasks.</string>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="image" keyPath="image">
<imageReference key="value" image="rectangle.grid.2x2.fill" catalog="system" symbolScale="default"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</customObject>
<customObject id="3ku-ur-HfQ" customClass="UIWelcomeSheetPageRow" customModule="WelcomeSheet">
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="color" keyPath="accentColor">
<color key="value" systemColor="systemOrangeColor"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="string" keyPath="title" value="Suggestions and Smart Lists"/>
<userDefinedRuntimeAttribute type="string" keyPath="content" value="Suggestions help you organize quickly, and smart lists automatically group reminders."/>
<userDefinedRuntimeAttribute type="image" keyPath="image">
<imageReference key="value" image="lightbulb.fill" catalog="system" symbolScale="default"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</customObject>
<customObject id="uEx-Tk-d3j" customClass="UIWelcomeSheetPage" customModule="WelcomeSheet">
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="string" keyPath="title" value="What’s New in Maps"/>
<userDefinedRuntimeAttribute type="color" keyPath="accentColor">
<color key="value" systemColor="systemPinkColor"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="string" keyPath="mainButtonTitle" value="Let’s go!"/>
<userDefinedRuntimeAttribute type="string" keyPath="optionalButtonTitle" value="About Apple Maps & Privacy..."/>
<userDefinedRuntimeAttribute type="string" keyPath="optionalButtonURL" value="https://apple.com"/>
</userDefinedRuntimeAttributes>
<connections>
<outletCollection property="rows" destination="2eI-i6-v16" collectionClass="NSMutableArray" id="93Q-Dr-Yuo"/>
<outletCollection property="rows" destination="dng-gJ-e0k" collectionClass="NSMutableArray" id="1am-C6-DGO"/>
<outletCollection property="rows" destination="7Zk-Z4-udS" collectionClass="NSMutableArray" id="ePo-mI-6eN"/>
</connections>
</customObject>
<customObject id="2eI-i6-v16" customClass="UIWelcomeSheetPageRow" customModule="WelcomeSheet">
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="color" keyPath="accentColor">
<color key="value" systemColor="systemGreenColor"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="string" keyPath="title" value="Updated Map Style"/>
<userDefinedRuntimeAttribute type="string" keyPath="content" value="An improved design makes it easier to navigate and explore the map."/>
<userDefinedRuntimeAttribute type="image" keyPath="image">
<imageReference key="value" image="map.fill" catalog="system" symbolScale="default"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</customObject>
<customObject id="dng-gJ-e0k" customClass="UIWelcomeSheetPageRow" customModule="WelcomeSheet">
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="color" keyPath="accentColor">
<color key="value" systemColor="systemRedColor"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="string" keyPath="title" value="All-New Place Cards"/>
<userDefinedRuntimeAttribute type="string" keyPath="content" value="Completely redesigned place cards make it easier to learn about and interact with places."/>
<userDefinedRuntimeAttribute type="image" keyPath="image">
<imageReference key="value" image="mappin.and.ellipse" catalog="system" symbolScale="default"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</customObject>
<customObject id="7Zk-Z4-udS" customClass="UIWelcomeSheetPageRow" customModule="WelcomeSheet">
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="color" keyPath="accentColor">
<color key="value" systemColor="systemBlueColor"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="string" keyPath="title" value="Improved Search"/>
<userDefinedRuntimeAttribute type="string" keyPath="content" value="Finding places is now easier with filters and automatic updates when you're browsing results on the map."/>
<userDefinedRuntimeAttribute type="image" keyPath="image">
<imageReference key="value" image="magnifyingglass" catalog="system" symbolScale="default"/>
</userDefinedRuntimeAttribute>
</userDefinedRuntimeAttributes>
</customObject>
</objects>
<point key="canvasLocation" x="369" y="-9"/>
</scene>
</scenes>
<resources>
<image name="gears" width="512" height="512"/>
<image name="ipad.and.iphone" catalog="system" width="128" height="87"/>
<image name="iphone" catalog="system" width="112" height="128"/>
<image name="lightbulb.fill" catalog="system" width="92" height="128"/>
<image name="magnifyingglass" catalog="system" width="128" height="117"/>
<image name="map.fill" catalog="system" width="128" height="110"/>
<image name="mappin.and.ellipse" catalog="system" width="117" height="128"/>
<image name="mic.badge.plus" catalog="system" width="121" height="128"/>
<image name="note.text.badge.plus" catalog="system" width="128" height="108"/>
<image name="platter.2.filled.iphone" catalog="system" width="114" height="128"/>
<image name="rectangle.grid.2x2.fill" catalog="system" width="128" height="97"/>
<image name="rectangle.stack.fill.badge.plus" catalog="system" width="128" height="118"/>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
<systemColor name="systemBlueColor">
<color red="0.0" green="0.47843137254901963" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemGreenColor">
<color red="0.20392156862745098" green="0.7803921568627451" blue="0.34901960784313724" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemIndigoColor">
<color red="0.34509803921568627" green="0.33725490196078434" blue="0.83921568627450982" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemMintColor">
<color red="0.0" green="0.7803921568627451" blue="0.74509803921568629" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemOrangeColor">
<color red="1" green="0.58431372549019611" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemPinkColor">
<color red="1" green="0.17647058823529413" blue="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemPurpleColor">
<color red="0.68627450980392157" green="0.32156862745098042" blue="0.87058823529411766" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemRedColor">
<color red="1" green="0.23137254901960785" blue="0.18823529411764706" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
</resources>
</document>
================================================
FILE: Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
</dict>
</dict>
</dict>
</plist>
================================================
FILE: Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo/SceneDelegate.swift
================================================
//
// SceneDelegate.swift
// UIKit-Storyboard-WelcomeSheetDemo
//
// Created by Eskil Gjerde Sviggum on 18/01/2023.
//
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let _ = (scene as? UIWindowScene) else { return }
}
func sceneDidDisconnect(_ scene: UIScene) {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
}
func sceneDidBecomeActive(_ scene: UIScene) {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}
func sceneWillResignActive(_ scene: UIScene) {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}
func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}
func sceneDidEnterBackground(_ scene: UIScene) {
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
}
}
================================================
FILE: Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo/ViewController.swift
================================================
//
// ViewController.swift
// UIKit-Storyboard-WelcomeSheetDemo
//
// Created by Eskil Gjerde Sviggum on 18/01/2023.
//
import UIKit
import WelcomeSheet
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let welcomeSheetController = segue.destination as? WelcomeSheetStoryboardController {
welcomeSheetController.delegate = self
}
}
}
extension ViewController: WelcomeSheetDelegate {
func welcomeSheetController(didDismiss welcomeSheetController: UIViewController) {
print("Did dismiss")
}
}
================================================
FILE: Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 56;
objects = {
/* Begin PBXBuildFile section */
7B5F339A2978166000E957C1 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5F33992978166000E957C1 /* AppDelegate.swift */; };
7B5F339C2978166000E957C1 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5F339B2978166000E957C1 /* SceneDelegate.swift */; };
7B5F339E2978166000E957C1 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7B5F339D2978166000E957C1 /* ViewController.swift */; };
7B5F33A12978166000E957C1 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7B5F339F2978166000E957C1 /* Main.storyboard */; };
7B5F33A32978166100E957C1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7B5F33A22978166100E957C1 /* Assets.xcassets */; };
7B5F33A62978166100E957C1 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7B5F33A42978166100E957C1 /* LaunchScreen.storyboard */; };
7B5F33B12978170500E957C1 /* WelcomeSheet in Frameworks */ = {isa = PBXBuildFile; productRef = 7B5F33B02978170500E957C1 /* WelcomeSheet */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
7B5F33962978166000E957C1 /* UIKit-Storyboard-WelcomeSheetDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "UIKit-Storyboard-WelcomeSheetDemo.app"; sourceTree = BUILT_PRODUCTS_DIR; };
7B5F33992978166000E957C1 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7B5F339B2978166000E957C1 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
7B5F339D2978166000E957C1 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
7B5F33A02978166000E957C1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
7B5F33A22978166100E957C1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
7B5F33A52978166100E957C1 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
7B5F33A72978166100E957C1 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
7B5F33AE297816BB00E957C1 /* Welcome-Sheet */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = "Welcome-Sheet"; path = ../..; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
7B5F33932978166000E957C1 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
7B5F33B12978170500E957C1 /* WelcomeSheet in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
7B5F338D2978166000E957C1 = {
isa = PBXGroup;
children = (
7B5F33AD297816BB00E957C1 /* Packages */,
7B5F33982978166000E957C1 /* UIKit-Storyboard-WelcomeSheetDemo */,
7B5F33972978166000E957C1 /* Products */,
7B5F33AF2978170500E957C1 /* Frameworks */,
);
sourceTree = "<group>";
};
7B5F33972978166000E957C1 /* Products */ = {
isa = PBXGroup;
children = (
7B5F33962978166000E957C1 /* UIKit-Storyboard-WelcomeSheetDemo.app */,
);
name = Products;
sourceTree = "<group>";
};
7B5F33982978166000E957C1 /* UIKit-Storyboard-WelcomeSheetDemo */ = {
isa = PBXGroup;
children = (
7B5F33992978166000E957C1 /* AppDelegate.swift */,
7B5F339B2978166000E957C1 /* SceneDelegate.swift */,
7B5F339D2978166000E957C1 /* ViewController.swift */,
7B5F339F2978166000E957C1 /* Main.storyboard */,
7B5F33A22978166100E957C1 /* Assets.xcassets */,
7B5F33A42978166100E957C1 /* LaunchScreen.storyboard */,
7B5F33A72978166100E957C1 /* Info.plist */,
);
path = "UIKit-Storyboard-WelcomeSheetDemo";
sourceTree = "<group>";
};
7B5F33AD297816BB00E957C1 /* Packages */ = {
isa = PBXGroup;
children = (
7B5F33AE297816BB00E957C1 /* Welcome-Sheet */,
);
name = Packages;
sourceTree = "<group>";
};
7B5F33AF2978170500E957C1 /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
7B5F33952978166000E957C1 /* UIKit-Storyboard-WelcomeSheetDemo */ = {
isa = PBXNativeTarget;
buildConfigurationList = 7B5F33AA2978166100E957C1 /* Build configuration list for PBXNativeTarget "UIKit-Storyboard-WelcomeSheetDemo" */;
buildPhases = (
7B5F33922978166000E957C1 /* Sources */,
7B5F33932978166000E957C1 /* Frameworks */,
7B5F33942978166000E957C1 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "UIKit-Storyboard-WelcomeSheetDemo";
packageProductDependencies = (
7B5F33B02978170500E957C1 /* WelcomeSheet */,
);
productName = "UIKit-Storyboard-WelcomeSheetDemo";
productReference = 7B5F33962978166000E957C1 /* UIKit-Storyboard-WelcomeSheetDemo.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
7B5F338E2978166000E957C1 /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 1420;
LastUpgradeCheck = 1420;
TargetAttributes = {
7B5F33952978166000E957C1 = {
CreatedOnToolsVersion = 14.2;
};
};
};
buildConfigurationList = 7B5F33912978166000E957C1 /* Build configuration list for PBXProject "UIKit-Storyboard-WelcomeSheetDemo" */;
compatibilityVersion = "Xcode 14.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 7B5F338D2978166000E957C1;
productRefGroup = 7B5F33972978166000E957C1 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
7B5F33952978166000E957C1 /* UIKit-Storyboard-WelcomeSheetDemo */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
7B5F33942978166000E957C1 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7B5F33A62978166100E957C1 /* LaunchScreen.storyboard in Resources */,
7B5F33A32978166100E957C1 /* Assets.xcassets in Resources */,
7B5F33A12978166000E957C1 /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
7B5F33922978166000E957C1 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
7B5F339E2978166000E957C1 /* ViewController.swift in Sources */,
7B5F339A2978166000E957C1 /* AppDelegate.swift in Sources */,
7B5F339C2978166000E957C1 /* SceneDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
7B5F339F2978166000E957C1 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
7B5F33A02978166000E957C1 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
7B5F33A42978166100E957C1 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
7B5F33A52978166100E957C1 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
7B5F33A82978166100E957C1 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 16.2;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
7B5F33A92978166100E957C1 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 16.2;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
7B5F33AB2978166100E957C1 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = EUKTZ7725R;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "UIKit-Storyboard-WelcomeSheetDemo/Info.plist";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
INFOPLIST_KEY_UIMainStoryboardFile = Main;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.jakubflorek.UIKit-WelcomeSheetDemo.UIKit-Storyboard-WelcomeSheetDemo";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
7B5F33AC2978166100E957C1 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = EUKTZ7725R;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "UIKit-Storyboard-WelcomeSheetDemo/Info.plist";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
INFOPLIST_KEY_UIMainStoryboardFile = Main;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.jakubflorek.UIKit-WelcomeSheetDemo.UIKit-Storyboard-WelcomeSheetDemo";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
7B5F33912978166000E957C1 /* Build configuration list for PBXProject "UIKit-Storyboard-WelcomeSheetDemo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
7B5F33A82978166100E957C1 /* Debug */,
7B5F33A92978166100E957C1 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
7B5F33AA2978166100E957C1 /* Build configuration list for PBXNativeTarget "UIKit-Storyboard-WelcomeSheetDemo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
7B5F33AB2978166100E957C1 /* Debug */,
7B5F33AC2978166100E957C1 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCSwiftPackageProductDependency section */
7B5F33B02978170500E957C1 /* WelcomeSheet */ = {
isa = XCSwiftPackageProductDependency;
productName = WelcomeSheet;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 7B5F338E2978166000E957C1 /* Project object */;
}
================================================
FILE: Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
================================================
FILE: Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
================================================
FILE: Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo/AppDelegate.swift
================================================
//
// AppDelegate.swift
// UIKit-WelcomeSheetDemo
//
// Created by Kevin Romero Peces-Barba on 6/10/22.
//
import UIKit
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
// MARK: UISceneSession Lifecycle
func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
// Called when a new scene session is being created.
// Use this method to select a configuration to create the new scene with.
return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
}
func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set<UISceneSession>) {
// Called when the user discards a scene session.
// If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions.
// Use this method to release any resources that were specific to the discarded scenes, as they will not return.
}
}
================================================
FILE: Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo/Assets.xcassets/AccentColor.colorset/Contents.json
================================================
{
"colors" : [
{
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.769",
"green" : "0.682",
"red" : "0.353"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo/Assets.xcassets/AppIcon.appiconset/Contents.json
================================================
{
"images" : [
{
"filename" : "40.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "60.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
},
{
"filename" : "29.png",
"idiom" : "iphone",
"scale" : "1x",
"size" : "29x29"
},
{
"filename" : "58.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "87.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
},
{
"filename" : "80.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
},
{
"filename" : "120.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
},
{
"filename" : "57.png",
"idiom" : "iphone",
"scale" : "1x",
"size" : "57x57"
},
{
"filename" : "114.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "57x57"
},
{
"filename" : "120.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
},
{
"filename" : "180.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
},
{
"filename" : "20.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "20x20"
},
{
"filename" : "40.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "29.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
},
{
"filename" : "58.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "40.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
},
{
"filename" : "80.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "40x40"
},
{
"filename" : "50.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "50x50"
},
{
"filename" : "100.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "50x50"
},
{
"filename" : "72.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "72x72"
},
{
"filename" : "144.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "72x72"
},
{
"filename" : "76.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
},
{
"filename" : "152.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
},
{
"filename" : "167.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"
},
{
"filename" : "1024.png",
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
},
{
"filename" : "16.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "16x16"
},
{
"filename" : "32.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "16x16"
},
{
"filename" : "32.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "32x32"
},
{
"filename" : "64.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "32x32"
},
{
"filename" : "128.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "128x128"
},
{
"filename" : "256.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "128x128"
},
{
"filename" : "256.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "256x256"
},
{
"filename" : "512.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "256x256"
},
{
"filename" : "512.png",
"idiom" : "mac",
"scale" : "1x",
"size" : "512x512"
},
{
"filename" : "1024.png",
"idiom" : "mac",
"scale" : "2x",
"size" : "512x512"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo/Assets.xcassets/Contents.json
================================================
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo/Assets.xcassets/gears.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "settings-gears.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo/Base.lproj/LaunchScreen.storyboard
================================================
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13122.16" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13104.12"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="EHf-IW-A2E">
<objects>
<viewController id="01J-lp-oVM" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" xcode11CocoaTouchSystemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="53" y="375"/>
</scene>
</scenes>
</document>
================================================
FILE: Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo/Base.lproj/Main.storyboard
================================================
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21506" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina6_12" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21504"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" customModule="UIKit_WelcomeSheetDemo" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
<rect key="frame" x="0.0" y="0.0" width="393" height="852"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="cQc-3d-P2P">
<rect key="frame" x="140" y="408.66666666666669" width="113" height="35"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="plain" title="Show sheet"/>
</button>
</subviews>
<viewLayoutGuide key="safeArea" id="6Tk-OE-BBY"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="cQc-3d-P2P" firstAttribute="centerY" secondItem="8bC-Xf-vdC" secondAttribute="centerY" id="C9C-v5-Skf"/>
<constraint firstItem="cQc-3d-P2P" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="RKp-Ce-Uly"/>
</constraints>
</view>
<connections>
<outlet property="showSheetButton" destination="cQc-3d-P2P" id="VW8-zl-tL4"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="21" y="4"/>
</scene>
</scenes>
<resources>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>
================================================
FILE: Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo/Info.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default Configuration</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
</dict>
</dict>
</dict>
</plist>
================================================
FILE: Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo/SceneDelegate.swift
================================================
//
// SceneDelegate.swift
// UIKit-WelcomeSheetDemo
//
// Created by Kevin Romero Peces-Barba on 6/10/22.
//
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let _ = (scene as? UIWindowScene) else { return }
}
func sceneDidDisconnect(_ scene: UIScene) {
// Called as the scene is being released by the system.
// This occurs shortly after the scene enters the background, or when its session is discarded.
// Release any resources associated with this scene that can be re-created the next time the scene connects.
// The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead).
}
func sceneDidBecomeActive(_ scene: UIScene) {
// Called when the scene has moved from an inactive state to an active state.
// Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive.
}
func sceneWillResignActive(_ scene: UIScene) {
// Called when the scene will move from an active state to an inactive state.
// This may occur due to temporary interruptions (ex. an incoming phone call).
}
func sceneWillEnterForeground(_ scene: UIScene) {
// Called as the scene transitions from the background to the foreground.
// Use this method to undo the changes made on entering the background.
}
func sceneDidEnterBackground(_ scene: UIScene) {
// Called as the scene transitions from the foreground to the background.
// Use this method to save data, release shared resources, and store enough scene-specific state information
// to restore the scene back to its current state.
}
}
================================================
FILE: Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo/ViewController.swift
================================================
//
// ViewController.swift
// UIKit-WelcomeSheetDemo
//
// Created by Kevin Romero Peces-Barba on 6/10/22.
//
import UIKit
import WelcomeSheet
class ViewController: UIViewController {
@IBOutlet weak var showSheetButton: UIButton!
let pages = [
WelcomeSheetPage(title: "Welcome to Welcome Sheet",
rows: [
WelcomeSheetPageRow(imageSystemName: "rectangle.stack.fill.badge.plus",
accentColor: .mint,
title: "Quick Creation",
content: "It's incredibly intuitive. Simply declare an array of pages filled with content."),
WelcomeSheetPageRow(imageNamed: "gears",
accentColor: .indigo,
title: "Highly Customisable",
content: "Match sheet's appearance to your app, link buttons, perform actions after dismissal."),
WelcomeSheetPageRow(imageSystemName: "ipad.and.iphone",
accentColor: .green,
title: "Works out of the box",
content: "Don't worry about various screen sizes. It will look gorgeous on every iOS device.")
],
accentColor: .purple,
optionalButtonTitle: "About Welcome Sheet...",
optionalButtonURL: URL(string: "https://github.com/MAJKFL/Welcome-Sheet")),
WelcomeSheetPage(title: "What's New in Translate",
rows: [
WelcomeSheetPageRow(imageSystemName: "platter.2.filled.iphone",
title: "Conversation Views",
content: "Choose a side-by-side or face-to-face conversation view."),
WelcomeSheetPageRow(imageSystemName: "mic.badge.plus",
title: "Auto Translate",
content: "Respond in conversations without tapping the microphone button."),
WelcomeSheetPageRow(imageSystemName: "iphone",
title: "System-Wide Translation",
content: "Translate selected text anywhere on your iPhone.")
],
mainButtonTitle: "Wassup?"),
WelcomeSheetPage(title: "Welcome to Reminders",
rows: [
WelcomeSheetPageRow(imageSystemName: "note.text.badge.plus",
accentColor: .green,
title: "Quick Creation",
content: "Simply type, ask Siri, or use the quick toolbar to create reminders."),
WelcomeSheetPageRow(imageSystemName: "rectangle.grid.2x2.fill",
accentColor: .init(red: 0.00, green: 0.70, blue: 1.00),
title: "Easy Organizing", content: "Create lists to match your needs and categorize reminders with tags. Collaborate with others by sharing lists and assigning individual tasks."),
WelcomeSheetPageRow(imageSystemName: "lightbulb.fill",
accentColor: .orange,
title: "Suggestions and Smart Lists",
content: "Suggestions help you organize quickly, and smart lists automatically group reminders.")
],
accentColor: .blue),
WelcomeSheetPage(title: "What's New in Maps",
rows: [
WelcomeSheetPageRow(imageSystemName: "map.fill",
accentColor: .green,
title: "Updated Map Style",
content: "An improved design makes it easier to navigate and explore the map."),
WelcomeSheetPageRow(imageSystemName: "mappin.and.ellipse",
accentColor: .red,
title: "All-New Place Cards",
content: "Completely redesigned place cards make it easier to learn about and interact with places."),
WelcomeSheetPageRow(imageSystemName: "magnifyingglass",
accentColor: .blue,
title: "Improved Search",
content: "Finding places is now easier with filters and automatic updates when you're browsing results on the map.")
],
accentColor: .pink,
mainButtonTitle: "Let's go!",
optionalButtonTitle: "About Apple Maps & Privacy...",
optionalButtonURL: URL(string: "https://apple.com"))
]
override func viewDidLoad() {
super.viewDidLoad()
showSheetButton.addTarget(self, action: #selector(showSheet), for: .touchUpInside)
}
@objc func showSheet() {
let sheetVC = WelcomeSheetController()
sheetVC.pages = pages
sheetVC.onDismiss = sheetDismissed
present(sheetVC, animated: true)
}
func sheetDismissed() {
print("Sheet dismissed")
}
}
================================================
FILE: Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 56;
objects = {
/* Begin PBXBuildFile section */
7B01CE742986A9B40044CE1E /* WelcomeSheet in Frameworks */ = {isa = PBXBuildFile; productRef = 7B01CE732986A9B40044CE1E /* WelcomeSheet */; };
D757A23328EEB0CD00056497 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D757A23228EEB0CD00056497 /* AppDelegate.swift */; };
D757A23528EEB0CD00056497 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D757A23428EEB0CD00056497 /* SceneDelegate.swift */; };
D757A23728EEB0CD00056497 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D757A23628EEB0CD00056497 /* ViewController.swift */; };
D757A23A28EEB0CD00056497 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D757A23828EEB0CD00056497 /* Main.storyboard */; };
D757A23C28EEB0CE00056497 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D757A23B28EEB0CE00056497 /* Assets.xcassets */; };
D757A23F28EEB0CE00056497 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D757A23D28EEB0CE00056497 /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
3A867362296E08A700ED9C49 /* WelcomeSheet */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = WelcomeSheet; path = ../..; sourceTree = "<group>"; };
D757A22F28EEB0CD00056497 /* UIKit-WelcomeSheetDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "UIKit-WelcomeSheetDemo.app"; sourceTree = BUILT_PRODUCTS_DIR; };
D757A23228EEB0CD00056497 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
D757A23428EEB0CD00056497 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
D757A23628EEB0CD00056497 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
D757A23928EEB0CD00056497 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
D757A23B28EEB0CE00056497 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
D757A23E28EEB0CE00056497 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
D757A24028EEB0CE00056497 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
D757A24928EEB2F000056497 /* Welcome-Sheet */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = "Welcome-Sheet"; path = ../..; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
D757A22C28EEB0CD00056497 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
7B01CE742986A9B40044CE1E /* WelcomeSheet in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
D757A22628EEB0CC00056497 = {
isa = PBXGroup;
children = (
D757A23128EEB0CD00056497 /* UIKit-WelcomeSheetDemo */,
D757A24828EEB2F000056497 /* Packages */,
D757A23028EEB0CD00056497 /* Products */,
D757A24A28EEB31000056497 /* Frameworks */,
);
sourceTree = "<group>";
};
D757A23028EEB0CD00056497 /* Products */ = {
isa = PBXGroup;
children = (
D757A22F28EEB0CD00056497 /* UIKit-WelcomeSheetDemo.app */,
);
name = Products;
sourceTree = "<group>";
};
D757A23128EEB0CD00056497 /* UIKit-WelcomeSheetDemo */ = {
isa = PBXGroup;
children = (
D757A23228EEB0CD00056497 /* AppDelegate.swift */,
D757A23428EEB0CD00056497 /* SceneDelegate.swift */,
D757A23628EEB0CD00056497 /* ViewController.swift */,
D757A23828EEB0CD00056497 /* Main.storyboard */,
D757A23B28EEB0CE00056497 /* Assets.xcassets */,
D757A23D28EEB0CE00056497 /* LaunchScreen.storyboard */,
D757A24028EEB0CE00056497 /* Info.plist */,
);
path = "UIKit-WelcomeSheetDemo";
sourceTree = "<group>";
};
D757A24828EEB2F000056497 /* Packages */ = {
isa = PBXGroup;
children = (
D757A24928EEB2F000056497 /* Welcome-Sheet */,
3A867362296E08A700ED9C49 /* WelcomeSheet */,
);
name = Packages;
sourceTree = "<group>";
};
D757A24A28EEB31000056497 /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
D757A22E28EEB0CD00056497 /* UIKit-WelcomeSheetDemo */ = {
isa = PBXNativeTarget;
buildConfigurationList = D757A24328EEB0CE00056497 /* Build configuration list for PBXNativeTarget "UIKit-WelcomeSheetDemo" */;
buildPhases = (
D757A22B28EEB0CD00056497 /* Sources */,
D757A22C28EEB0CD00056497 /* Frameworks */,
D757A22D28EEB0CD00056497 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "UIKit-WelcomeSheetDemo";
packageProductDependencies = (
7B01CE732986A9B40044CE1E /* WelcomeSheet */,
);
productName = "UIKit-WelcomeSheetDemo";
productReference = D757A22F28EEB0CD00056497 /* UIKit-WelcomeSheetDemo.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
D757A22728EEB0CC00056497 /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 1410;
LastUpgradeCheck = 1410;
TargetAttributes = {
D757A22E28EEB0CD00056497 = {
CreatedOnToolsVersion = 14.1;
};
};
};
buildConfigurationList = D757A22A28EEB0CC00056497 /* Build configuration list for PBXProject "UIKit-WelcomeSheetDemo" */;
compatibilityVersion = "Xcode 14.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = D757A22628EEB0CC00056497;
productRefGroup = D757A23028EEB0CD00056497 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
D757A22E28EEB0CD00056497 /* UIKit-WelcomeSheetDemo */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
D757A22D28EEB0CD00056497 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
D757A23F28EEB0CE00056497 /* LaunchScreen.storyboard in Resources */,
D757A23C28EEB0CE00056497 /* Assets.xcassets in Resources */,
D757A23A28EEB0CD00056497 /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
D757A22B28EEB0CD00056497 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
D757A23728EEB0CD00056497 /* ViewController.swift in Sources */,
D757A23328EEB0CD00056497 /* AppDelegate.swift in Sources */,
D757A23528EEB0CD00056497 /* SceneDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
D757A23828EEB0CD00056497 /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
D757A23928EEB0CD00056497 /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
D757A23D28EEB0CE00056497 /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
D757A23E28EEB0CE00056497 /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
D757A24128EEB0CE00056497 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 16.1;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
D757A24228EEB0CE00056497 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 16.1;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SDKROOT = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
D757A24428EEB0CE00056497 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = T23P54M8LP;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "UIKit-WelcomeSheetDemo/Info.plist";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
INFOPLIST_KEY_UIMainStoryboardFile = Main;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.jakubflorek.UIKit-WelcomeSheetDemo";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
D757A24528EEB0CE00056497 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = T23P54M8LP;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_FILE = "UIKit-WelcomeSheetDemo/Info.plist";
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
INFOPLIST_KEY_UIMainStoryboardFile = Main;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = "com.jakubflorek.UIKit-WelcomeSheetDemo";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
D757A22A28EEB0CC00056497 /* Build configuration list for PBXProject "UIKit-WelcomeSheetDemo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
D757A24128EEB0CE00056497 /* Debug */,
D757A24228EEB0CE00056497 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
D757A24328EEB0CE00056497 /* Build configuration list for PBXNativeTarget "UIKit-WelcomeSheetDemo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
D757A24428EEB0CE00056497 /* Debug */,
D757A24528EEB0CE00056497 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCSwiftPackageProductDependency section */
7B01CE732986A9B40044CE1E /* WelcomeSheet */ = {
isa = XCSwiftPackageProductDependency;
productName = WelcomeSheet;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = D757A22728EEB0CC00056497 /* Project object */;
}
================================================
FILE: Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata
================================================
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
================================================
FILE: Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
================================================
FILE: Demo/WelcomeSheetDemo/Shared/Assets.xcassets/AccentColor.colorset/Contents.json
================================================
{
"colors" : [
{
"color" : {
"color-space" : "display-p3",
"components" : {
"alpha" : "1.000",
"blue" : "0.769",
"green" : "0.682",
"red" : "0.353"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Demo/WelcomeSheetDemo/Shared/Assets.xcassets/AppIcon.appiconset/Contents.json
================================================
{"images":[{"size":"60x60","expected-size":"180","filename":"180.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"40x40","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"60x60","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"57x57","expected-size":"57","filename":"57.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"87","filename":"87.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"57x57","expected-size":"114","filename":"114.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"60","filename":"60.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"1024x1024","filename":"1024.png","expected-size":"1024","idiom":"ios-marketing","folder":"Assets.xcassets/AppIcon.appiconset/","scale":"1x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"72x72","expected-size":"72","filename":"72.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"76x76","expected-size":"152","filename":"152.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"50x50","expected-size":"100","filename":"100.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"76x76","expected-size":"76","filename":"76.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"50x50","expected-size":"50","filename":"50.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"72x72","expected-size":"144","filename":"144.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"40x40","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"83.5x83.5","expected-size":"167","filename":"167.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"20x20","expected-size":"20","filename":"20.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"128x128","expected-size":"128","filename":"128.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"256x256","expected-size":"256","filename":"256.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"128x128","expected-size":"256","filename":"256.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"256x256","expected-size":"512","filename":"512.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"32x32","expected-size":"32","filename":"32.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"512x512","expected-size":"512","filename":"512.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"16x16","expected-size":"16","filename":"16.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"1x"},{"size":"16x16","expected-size":"32","filename":"32.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"32x32","expected-size":"64","filename":"64.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"},{"size":"512x512","expected-size":"1024","filename":"1024.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"mac","scale":"2x"}]}
================================================
FILE: Demo/WelcomeSheetDemo/Shared/Assets.xcassets/Contents.json
================================================
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Demo/WelcomeSheetDemo/Shared/Assets.xcassets/gears.imageset/Contents.json
================================================
{
"images" : [
{
"filename" : "settings-gears.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
================================================
FILE: Demo/WelcomeSheetDemo/Shared/ContentView.swift
================================================
//
// ContentView.swift
// Shared
//
// Created by Jakub Florek on 27/11/2021.
//
import SwiftUI
import WelcomeSheet
struct ContentView: View {
@State private var showSheet = false
var body: some View {
Button("Show sheet") {
showSheet.toggle()
}
.padding()
.welcomeSheet(isPresented: $showSheet, onDismiss: { sheetDismissed() }, isSlideToDismissDisabled: true, pages: getPages()) // Sheet from page array
// .welcomeSheet(isPresented: $showSheet, onDismiss: { sheetDismissed() }, isSlideToDismissDisabled: true, pages: getPagesFromJSON()) // Sheet from JSON
}
func sheetDismissed() {
print("Sheet dismissed")
}
func getPages() -> [WelcomeSheetPage] {
[WelcomeSheetPage(title: "Welcome to Welcome Sheet", rows: [
WelcomeSheetPageRow(imageSystemName: "rectangle.stack.fill.badge.plus",
accentColor: Color.mint,
title: "Quick Creation",
content: "It's incredibly intuitive. Simply declare an array of pages filled with content."),
WelcomeSheetPageRow(imageNamed: "gears",
accentColor: Color.indigo,
title: "Highly Customisable", content: "Match sheet's appearance to your app, link buttons, perform actions after dismissal."),
WelcomeSheetPageRow(imageSystemName: "ipad.and.iphone",
accentColor: Color.green,
title: "Works out of the box",
content: "Don't worry about various screen sizes. It will look gorgeous on every iOS device.")
], accentColor: Color.purple, optionalButtonTitle: "About Welcome Sheet...", optionalButtonURL: URL(string: "https://github.com/MAJKFL/Welcome-Sheet")),
WelcomeSheetPage(title: "What's New in Translate", rows: [
WelcomeSheetPageRow(imageSystemName: "platter.2.filled.iphone",
title: "Conversation Views",
content: "Choose a side-by-side or face-to-face conversation view."),
WelcomeSheetPageRow(imageSystemName: "mic.badge.plus",
title: "Auto Translate",
content: "Respond in conversations without tapping the microphone button."),
WelcomeSheetPageRow(imageSystemName: "iphone",
title: "System-Wide Translation",
content: "Translate selected text anywhere on your iPhone.")
], mainButtonTitle: "Wassup?"),
WelcomeSheetPage(title: "Welcome to Reminders", rows: [
WelcomeSheetPageRow(imageSystemName: "note.text.badge.plus",
accentColor: Color.green,
title: "Quick Creation",
content: "Simply type, ask Siri, or use the quick toolbar to create reminders."),
WelcomeSheetPageRow(imageSystemName: "rectangle.grid.2x2.fill",
accentColor: Color(red: 0.00, green: 0.70, blue: 1.00),
title: "Easy Organizing", content: "Create lists to match your needs and categorize reminders with tags. Collaborate with others by sharing lists and assigning individual tasks."),
WelcomeSheetPageRow(imageSystemName: "lightbulb.fill",
accentColor: Color.orange,
title: "Suggestions and Smart Lists",
content: "Suggestions help you organize quickly, and smart lists automatically group reminders.")
], accentColor: Color.blue, optionalButtonTitle: "Show Terms and Conditions", optionalButtonView: { Text("Terms and Conditions") }),
WelcomeSheetPage(title: "What's New in Maps", rows: [
WelcomeSheetPageRow(imageSystemName: "map.fill",
accentColor: Color.green,
title: "Updated Map Style",
content: "An improved design makes it easier to navigate and explore the map."),
WelcomeSheetPageRow(imageSystemName: "mappin.and.ellipse",
accentColor: Color.red,
title: "All-New Place Cards",
content: "Completely redesigned place cards make it easier to learn about and interact with places."),
WelcomeSheetPageRow(imageSystemName: "magnifyingglass",
accentColor: Color.blue,
title: "Improved Search",
content: "Finding places is now easier with filters and automatic updates when you're browsing results on the map.")
], accentColor: Color.pink, mainButtonTitle: "Let's go!", optionalButtonTitle: "About Apple Maps & Privacy...", optionalButtonURL: URL(string: "https://apple.com"))
]
}
func getPagesFromJSON() -> [WelcomeSheetPage] {
if let url = Bundle.main.url(forResource: "demo", withExtension: "json") {
do {
let jsonData = try Data(contentsOf: url)
let decoder = JSONDecoder()
return try decoder.decode([WelcomeSheetPage].self, from: jsonData)
} catch {
print(error)
}
}
return []
}
}
================================================
FILE: Demo/WelcomeSheetDemo/Shared/WelcomeSheetDemoApp.swift
================================================
//
// WelcomeSheetDemoApp.swift
// Shared
//
// Created by Jakub Florek on 27/11/2021.
//
import SwiftUI
@main
struct WelcomeSheetDemoApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
================================================
FILE: Demo/WelcomeSheetDemo/Shared/demo.json
================================================
[
{
"optionalButtonURL":"https:\/\/github.com\/MAJKFL\/Welcome-Sheet",
"accentColor":"BF5AF2",
"isShowingOptionalButton":true,
"title":"Welcome to Welcome Sheet",
"rows":[
{
"accentColor":"63E6E1",
"title":"Quick Creation",
"content":"Sheet creation is incredibly intuitive. Simply create an array of pages filled with your content.",
"imageName":"rectangle.stack.fill.badge.plus"
},
{
"accentColor":"5E5CE6",
"title":"Highly Customizable",
"content":"Set accent colors, add optional buttons, disable dismiss gestures, perform actions after button taps or sheet dismissal and more!",
"imageName":"gears"
},
{
"accentColor":"30D158",
"title":"Works out of the box",
"content":"Don't worry about different screen sizes. Your Welcome Sheet will look gorgeous on every iOS device!",
"imageName":"ipad.and.iphone"
}
],
"optionalButtonTitle":"About Welcome Sheet...",
"mainButtonTitle":"Continue"
}
]
================================================
FILE: Demo/WelcomeSheetDemo/WelcomeSheetDemo.xcodeproj/project.pbxproj
================================================
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 55;
objects = {
/* Begin PBXBuildFile section */
3A1EC3972752B0E70005F216 /* WelcomeSheetDemoApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A1EC3872752B0E70005F216 /* WelcomeSheetDemoApp.swift */; };
3A1EC3982752B0E70005F216 /* WelcomeSheetDemoApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A1EC3872752B0E70005F216 /* WelcomeSheetDemoApp.swift */; };
3A1EC3992752B0E70005F216 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A1EC3882752B0E70005F216 /* ContentView.swift */; };
3A1EC39A2752B0E70005F216 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A1EC3882752B0E70005F216 /* ContentView.swift */; };
3A1EC39B2752B0E70005F216 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3A1EC3892752B0E70005F216 /* Assets.xcassets */; };
3A1EC39C2752B0E70005F216 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3A1EC3892752B0E70005F216 /* Assets.xcassets */; };
3A75F403275D1E30009E94E6 /* demo.json in Resources */ = {isa = PBXBuildFile; fileRef = 3A75F402275D1E30009E94E6 /* demo.json */; };
3A75F404275D1E30009E94E6 /* demo.json in Resources */ = {isa = PBXBuildFile; fileRef = 3A75F402275D1E30009E94E6 /* demo.json */; };
D74557F528EEBA6E0025C195 /* WelcomeSheet in Frameworks */ = {isa = PBXBuildFile; productRef = D74557F428EEBA6E0025C195 /* WelcomeSheet */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
3A1EC3872752B0E70005F216 /* WelcomeSheetDemoApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeSheetDemoApp.swift; sourceTree = "<group>"; };
3A1EC3882752B0E70005F216 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
3A1EC3892752B0E70005F216 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
3A1EC38E2752B0E70005F216 /* WelcomeSheetDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WelcomeSheetDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
3A1EC3942752B0E70005F216 /* WelcomeSheetDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = WelcomeSheetDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
3A1EC3962752B0E70005F216 /* macOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = macOS.entitlements; sourceTree = "<group>"; };
3A75F402275D1E30009E94E6 /* demo.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = demo.json; sourceTree = "<group>"; };
D74557F228EEBA560025C195 /* Welcome-Sheet */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = "Welcome-Sheet"; path = ../..; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
3A1EC38B2752B0E70005F216 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
D74557F528EEBA6E0025C195 /* WelcomeSheet in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
3A1EC3912752B0E70005F216 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
3A1EC3812752B0E70005F216 = {
isa = PBXGroup;
children = (
3A1EC3862752B0E70005F216 /* Shared */,
3A1EC3952752B0E70005F216 /* macOS */,
D74557F128EEBA560025C195 /* Packages */,
3A1EC38F2752B0E70005F216 /* Products */,
D74557F328EEBA6E0025C195 /* Frameworks */,
);
sourceTree = "<group>";
};
3A1EC3862752B0E70005F216 /* Shared */ = {
isa = PBXGroup;
children = (
3A75F402275D1E30009E94E6 /* demo.json */,
3A1EC3872752B0E70005F216 /* WelcomeSheetDemoApp.swift */,
3A1EC3882752B0E70005F216 /* ContentView.swift */,
3A1EC3892752B0E70005F216 /* Assets.xcassets */,
);
path = Shared;
sourceTree = "<group>";
};
3A1EC38F2752B0E70005F216 /* Products */ = {
isa = PBXGroup;
children = (
3A1EC38E2752B0E70005F216 /* WelcomeSheetDemo.app */,
3A1EC3942752B0E70005F216 /* WelcomeSheetDemo.app */,
);
name = Products;
sourceTree = "<group>";
};
3A1EC3952752B0E70005F216 /* macOS */ = {
isa = PBXGroup;
children = (
3A1EC3962752B0E70005F216 /* macOS.entitlements */,
);
path = macOS;
sourceTree = "<group>";
};
D74557F128EEBA560025C195 /* Packages */ = {
isa = PBXGroup;
children = (
D74557F228EEBA560025C195 /* Welcome-Sheet */,
);
name = Packages;
sourceTree = "<group>";
};
D74557F328EEBA6E0025C195 /* Frameworks */ = {
isa = PBXGroup;
children = (
);
name = Frameworks;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
3A1EC38D2752B0E70005F216 /* WelcomeSheetDemo (iOS) */ = {
isa = PBXNativeTarget;
buildConfigurationList = 3A1EC39F2752B0E70005F216 /* Build configuration list for PBXNativeTarget "WelcomeSheetDemo (iOS)" */;
buildPhases = (
3A1EC38A2752B0E70005F216 /* Sources */,
3A1EC38B2752B0E70005F216 /* Frameworks */,
3A1EC38C2752B0E70005F216 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "WelcomeSheetDemo (iOS)";
packageProductDependencies = (
D74557F428EEBA6E0025C195 /* WelcomeSheet */,
);
productName = "WelcomeSheetDemo (iOS)";
productReference = 3A1EC38E2752B0E70005F216 /* WelcomeSheetDemo.app */;
productType = "com.apple.product-type.application";
};
3A1EC3932752B0E70005F216 /* WelcomeSheetDemo (macOS) */ = {
isa = PBXNativeTarget;
buildConfigurationList = 3A1EC3A22752B0E70005F216 /* Build configuration list for PBXNativeTarget "WelcomeSheetDemo (macOS)" */;
buildPhases = (
3A1EC3902752B0E70005F216 /* Sources */,
3A1EC3912752B0E70005F216 /* Frameworks */,
3A1EC3922752B0E70005F216 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "WelcomeSheetDemo (macOS)";
productName = "WelcomeSheetDemo (macOS)";
productReference = 3A1EC3942752B0E70005F216 /* WelcomeSheetDemo.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
3A1EC3822752B0E70005F216 /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = 1;
LastSwiftUpdateCheck = 1310;
LastUpgradeCheck = 1320;
TargetAttributes = {
3A1EC38D2752B0E70005F216 = {
CreatedOnToolsVersion = 13.1;
};
3A1EC3932752B0E70005F216 = {
CreatedOnToolsVersion = 13.1;
};
};
};
buildConfigurationList = 3A1EC3852752B0E70005F216 /* Build configuration list for PBXProject "WelcomeSheetDemo" */;
compatibilityVersion = "Xcode 13.0";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 3A1EC3812752B0E70005F216;
packageReferences = (
);
productRefGroup = 3A1EC38F2752B0E70005F216 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
3A1EC38D2752B0E70005F216 /* WelcomeSheetDemo (iOS) */,
3A1EC3932752B0E70005F216 /* WelcomeSheetDemo (macOS) */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
3A1EC38C2752B0E70005F216 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3A75F403275D1E30009E94E6 /* demo.json in Resources */,
3A1EC39B2752B0E70005F216 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
3A1EC3922752B0E70005F216 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3A75F404275D1E30009E94E6 /* demo.json in Resources */,
3A1EC39C2752B0E70005F216 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
3A1EC38A2752B0E70005F216 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3A1EC3992752B0E70005F216 /* ContentView.swift in Sources */,
3A1EC3972752B0E70005F216 /* WelcomeSheetDemoApp.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
3A1EC3902752B0E70005F216 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
3A1EC39A2752B0E70005F216 /* ContentView.swift in Sources */,
3A1EC3982752B0E70005F216 /* WelcomeSheetDemoApp.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin XCBuildConfiguration section */
3A1EC39D2752B0E70005F216 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
MTL_FAST_MATH = YES;
ONLY_ACTIVE_ARCH = YES;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
3A1EC39E2752B0E70005F216 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++17";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_ENABLE_OBJC_WEAK = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu11;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
MTL_ENABLE_DEBUG_INFO = NO;
MTL_FAST_MATH = YES;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
};
name = Release;
};
3A1EC3A02752B0E70005F216 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 9RS6NWG958;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.florekjakub.WelcomeSheetDemo;
PRODUCT_NAME = WelcomeSheetDemo;
SDKROOT = iphoneos;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
3A1EC3A12752B0E70005F216 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 9RS6NWG958;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.florekjakub.WelcomeSheetDemo;
PRODUCT_NAME = WelcomeSheetDemo;
SDKROOT = iphoneos;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
3A1EC3A32752B0E70005F216 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = macOS/macOS.entitlements;
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 9RS6NWG958;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.florekjakub.WelcomeSheetDemo;
PRODUCT_NAME = WelcomeSheetDemo;
SDKROOT = macosx;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
};
name = Debug;
};
3A1EC3A42752B0E70005F216 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = macOS/macOS.entitlements;
CODE_SIGN_IDENTITY = "-";
CODE_SIGN_STYLE = Automatic;
COMBINE_HIDPI_IMAGES = YES;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = 9RS6NWG958;
ENABLE_HARDENED_RUNTIME = YES;
ENABLE_PREVIEWS = YES;
GENERATE_INFOPLIST_FILE = YES;
INFOPLIST_KEY_NSHumanReadableCopyright = "";
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 12.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.florekjakub.WelcomeSheetDemo;
PRODUCT_NAME = WelcomeSheetDemo;
SDKROOT = macosx;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_VERSION = 5.0;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
3A1EC3852752B0E70005F216 /* Build configuration list for PBXProject "WelcomeSheetDemo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
3A1EC39D2752B0E70005F216 /* Debug */,
3A1EC39E2752B0E70005F216 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
3A1EC39F2752B0E70005F216 /* Build configuration list for PBXNativeTarget "WelcomeSheetDemo (iOS)" */ = {
isa = XCConfigurationList;
buildConfigurations = (
3A1EC3A02752B0E70005F216 /* Debug */,
3A1EC3A12752B0E70005F216 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
3A1EC3A22752B0E70005F216 /* Build configuration list for PBXNativeTarget "WelcomeSheetDemo (macOS)" */ = {
isa = XCConfigurationList;
buildConfigurations = (
3A1EC3A32752B0E70005F216 /* Debug */,
3A1EC3A42752B0E70005F216 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
/* Begin XCSwiftPackageProductDependency section */
D74557F428EEBA6E0025C195 /* WelcomeSheet */ = {
isa = XCSwiftPackageProductDependency;
productName = WelcomeSheet;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = 3A1EC3822752B0E70005F216 /* Project object */;
}
================================================
FILE: Demo/WelcomeSheetDemo/macOS/macOS.entitlements
================================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.files.user-selected.read-only</key>
<true/>
</dict>
</plist>
================================================
FILE: Documentation/UIKit/Readme.md
================================================
# Configuring from Storyboards
You can set up the pages of your Welcome Sheet from a Storyboard or XIB file—without writing a single line of code. Check out the [demo](../../Demo/UIKit-Storyboard-WelcomeSheetDemo/) for more details.
## Creating a WelcomeSheetStoryboardController
Drag out a new UIViewController and set the class to `WelcomeSheetStoryboardController`.
<div style="display: flex; align-items: center">
<img alt="A new UIViewController" src="Resources/ViewController.png" width="300px"/>
<img alt="Set class of the controller to WelcomeSheetStoryboardController" src="Resources/SetClassOfViewController.png" width="300px"/>
</div>
## Creating a page
- Create a new object and set the class to `UIWelcomeSheetPage`.
<div style="display: flex; align-items: center">
<img alt="A new Object" src="Resources/Object.png" width="300px"/>
<img alt="Set class of the object to UIWelcomeSheetPage" src="Resources/SetClassOfObjectToPage.png" width="300px"/>
</div>
- Go to the *Attributes* tab and configure the page.
<img alt="Configure the attributes of a page" src="Resources/ConfigurePage.png" width="300px"/>
### Adding a row to the page
- Create a new object and set the class to `UIWelcomeSheetPageRow`.
<div style="display: flex; align-items: center">
<img alt="A new Object" src="Resources/Object.png" width="300px"/>
<img alt="Set class of the object to UIWelcomeSheetPageRow" src="Resources/SetClassOfObjectToRow.png" width="300px"/>
</div>
- Go to the *Attributes* tab and configure the row.
<img alt="Configure the attributes of a page row" src="Resources/ConfigureRow.png" width="300px"/>
- Go to the *Connections* tab of your *page* and connect the `rows` outlet collection to all of the rows for the page.
<img alt="Connect the rows for your page" src="Resources/ConnectRows.png" width="300px"/>
### Connecting a page to the controller
- On your controller, go to the *Connections* tab and make a connection for each of your pages.
<img alt="Connect the pages for your welcome sheet" src="Resources/ConnectPages.png" width="300px"/>
## Summary
To configure your Welcome sheet from a storyboard do as follows:
- Drag out a new UIViewController and set the class to `WelcomeSheetStoryboardController`.
- For each of your pages:
- Drag out a new Object and set the class to `UIWelcomeSheetPage`.
- Configure the attributes
- For each of the rows in your page:
- Drag out a new Object and set the class to `UIWelcomeSheetPageRow`.
- Configure the attributes
- Connect the row to your page by draging out a connection to the `rows` outlet.
- Connect the page to your sheet by draging out a connection to the `pages` outlet.
- You now have a Welcome Sheet without writing a single line of code!
You should end up with a lot of objects like so:
<img alt="Objects connected to your sheet" src="Resources/WelcomeSheetScene.png" width="300px"/>
# Using a System Symbol in a UIImage
Due to conversion issues between `UIImage` and SwiftUI’s `Image`, system symbols will have a squashed appearance. Welcome Sheet overcomes this issue by obtaining the name of the system symbol from the `UIImage` and creating a new `Image` from the system name.
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2021 Jakub Florek
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: Package.swift
================================================
// swift-tools-version:5.5
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription
let package = Package(
name: "WelcomeSheet",
platforms: [.iOS(.v13)],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "WelcomeSheet",
targets: ["WelcomeSheet"]),
],
dependencies: [
// Dependencies declare other packages that this package depends on.
// .package(url: /* package url */, from: "1.0.0"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "WelcomeSheet",
dependencies: []),
]
)
================================================
FILE: README.md
================================================
# Welcome Sheet

Welcome sheet for iOS enables incredibly easy way for creating onboarding screens, update notes, or whatever you imagine! The main idea standing behind this project was to follow the design of Apple’s native onboarding screens as much as possible, that’s why you can be always sure they will look gorgeous on iPhone SE screen as well as on iPad Pro’s massive 12,9” display!
<p align="center">
<img src="Documentation/WelcomeSheetPromo.gif">
</p>
# SwiftUI
To create a welcome sheet in SwiftUI simply add .welcomeSheet view modifier to your view and pass page array as an argument.
```swift
import SwiftUI
import WelcomeSheet
struct ContentView: View {
@State private var showSheet = false
let pages = [
WelcomeSheetPage(title: "Welcome to Welcome Sheet", rows: [
WelcomeSheetPageRow(imageSystemName: "rectangle.stack.fill.badge.plus",
title: "Quick Creation",
content: "It's incredibly intuitive. Simply declare an array of pages filled with content."),
WelcomeSheetPageRow(imageSystemName: "slider.horizontal.3",
title: "Highly Customisable",
content: "Match sheet's appearance to your app, link buttons, perform actions after dismissal."),
WelcomeSheetPageRow(imageSystemName: "ipad.and.iphone",
title: "Works out of the box",
content: "Don't worry about various screen sizes. It will look gorgeous on every iOS device.")
])
]
var body: some View {
Button("Show sheet") {
showSheet.toggle()
}
.welcomeSheet(isPresented: $showSheet, pages: pages)
}
}
```
## .welcomeSheet
`.welcomeSheet` presents welcome sheet with given pages when a binding to a Boolean value that you provide is true.
```swift
.welcomeSheet(isPresented: $showSheet,
onDismiss: { /* Run this code when sheet is dismissed */ },
isSlideToDismissDisabled: true,
preferredColorScheme = .dark,
pages: pages)
```
- `isPresented` - `bool` binding. When set to `true` presents sheet.
- `onDismiss` - Closure called after sheet's dismissal.
- `isSlideToDismissDisabled` - When set to `true` disables sheet's swipe to dismiss gesture.
- `preferredColorScheme` - Overrides the default color scheme.
- `pages` - Array of pages to be displayed chronologically.
# UIKit
To create a welcome sheet in UIKit create `WelcomeSheetController` and present it from your ViewController.
```Swift
class ViewController: UIViewController {
@IBOutlet weak var showSheetButton: UIButton!
let pages = [
WelcomeSheetPage(title: "Welcome to Welcome Sheet", rows: [
WelcomeSheetPageRow(imageSystemName: "rectangle.stack.fill.badge.plus",
title: "Quick Creation",
content: "It's incredibly intuitive. Simply declare an array of pages filled with content."),
WelcomeSheetPageRow(imageSystemName: "slider.horizontal.3",
title: "Highly Customisable",
content: "Match sheet's appearance to your app, link buttons, perform actions after dismissal."),
WelcomeSheetPageRow(imageSystemName: "ipad.and.iphone",
title: "Works out of the box",
content: "Don't worry about various screen sizes. It will look gorgeous on every iOS device.")
])
]
override func viewDidLoad() {
super.viewDidLoad()
showSheetButton.addTarget(self, action: #selector(showSheet), for: .touchUpInside)
}
@objc func showSheet() {
let sheetVC = WelcomeSheetController()
sheetVC.pages = pages
sheetVC.onDismiss = sheetDismissed
present(sheetVC, animated: true)
}
func sheetDismissed() {
print("Sheet dismissed")
}
}
```
## WelcomeSheetController
`WelcomeSheetController` controller used to create, configure and present the sheet.
```Swift
let sheetVC = WelcomeSheetController()
sheetVC.pages = pages
sheetVC.onDismiss = { /* Run this code when sheet is dismissed */ }
sheetVC.isModalInPresentation = true
present(sheetVC, animated: true)
```
- `pages` - Array of pages to be displayed chronologically.
- `onDismiss` - Closure called after sheet's dismissal.
- `isModalInPresentation` - When set to `true` disables sheet's swipe to dismiss gesture.
# Models
Objects used to configure sheets. Each model has also a set of UIKit data initializers.
## WelcomeSheetPage
`WelcomeSheetPage` type that describes page's content.
```swift
WelcomeSheetPage(title: "Welcome to Welcome Sheet", rows: [
// Rows
],
mainButtonTitle: "Let's go!",
accentColor: Color.purple,
optionalButtonTitle: "About Welcome Sheet...",
optionalButtonURL: URL(string: "https://github.com/MAJKFL/Welcome-Sheet"))
```
- `title` - Large title displayed on the top.
- `rows` - Rows of content inside a body
- `mainButtonTitle` - Optional title for a main button. Set to `"Continue"` by default.
- `accentColor` - Color used for buttons. When set to `nil`, uses default accent colour.
- `optionalButtonTitle` - Title for an optional button.
- `optionalButtonURL` - `URL` to open when an optional button is pressed.
## WelcomeSheetPageRow
`WelcomeSheetPageRow` describes row's content.
```swift
WelcomeSheetPageRow(imageSystemName: "ipad.and.iphone", // Or `image: Image("ExampleImageName")`
accentColor: Color.green,
title: "Works out of the box",
content: "Don't worry about various screen sizes. It will look gorgeous on every iOS device.")
```
- `imageSystemName` - SF Symbol name for image displayed at the beginning of a row.
- `image` - Image displayed at the beginning of a row.
- `accentColor` - Color used for an image. When set to `nil`, uses default accent colour.
- `title` - Title displayed over a content.
- `content` - Text displayed beneath a title.
## Decodable support
You can decode pages from JSON.
```JSON
[
{
"optionalButtonURL":"https:\/\/github.com\/MAJKFL\/Welcome-Sheet",
"accentColor":"BF5AF2",
"isShowingOptionalButton":true,
"title":"Welcome to Welcome Sheet",
"rows":[
{
"accentColor":"63E6E1",
"title":"Quick Creation",
"content":"Sheet creation is incredibly intuitive. Simply create an array of pages filled with your content.",
"imageName":"rectangle.stack.fill.badge.plus"
},
{
"accentColor":"5E5CE6",
"title":"Highly Customizable",
"content":"Set accent colors, add optional buttons, disable dismiss gestures, perform actions after button taps or sheet dismissal and more!",
"imageName":"gears"
},
{
"accentColor":"30D158",
"title":"Works out of the box",
"content":"Don't worry about different screen sizes. Your Welcome Sheet will look gorgeous on every iOS device!",
"imageName":"ipad.and.iphone"
}
],
"optionalButtonTitle":"About Welcome Sheet...",
"mainButtonTitle":"Continue"
}
]
```
**Note:** `imageName` can store asset catalogue image name or SF Symbol name.
## UIKit Storyboards support
You can configure your Welcome Sheet without writing a single line of code.

For a step-by-step guide on how to configure by storyboards, please see the [Documentation](Documentation/UIKit/Readme.md)
## Installation
Using Swift Package Manager
```
.package(url: "https://github.com/MAJKFL/Welcome-Sheet", from: "0.1.1"),
```
## Example
``` Swift
import SwiftUI
import WelcomeSheet
struct ContentView: View {
@State private var showSheet = false
let pages = [
WelcomeSheetPage(title: "Welcome to Welcome Sheet", rows: [
WelcomeSheetPageRow(imageSystemName: "rectangle.stack.fill.badge.plus",
accentColor: Color.mint,
title: "Quick Creation",
content: "It's incredibly intuitive. Simply declare an array of pages filled with content."),
WelcomeSheetPageRow(imageSystemName: "slider.horizontal.3",
accentColor: Color.indigo,
title: "Highly Customisable", content: "Match sheet's appearance to your app, link buttons, perform actions after dismissal."),
WelcomeSheetPageRow(imageSystemName: "ipad.and.iphone",
accentColor: Color.green,
title: "Works out of the box",
content: "Don't worry about various screen sizes. It will look gorgeous on every iOS device.")
], accentColor: Color.purple, optionalButtonTitle: "About Welcome Sheet...", optionalButtonURL: URL(string: "https://github.com/MAJKFL/Welcome-Sheet")),
WelcomeSheetPage(title: "What's New in Translate", rows: [
WelcomeSheetPageRow(imageSystemName: "platter.2.filled.iphone",
title: "Conversation Views",
content: "Choose a side-by-side or face-to-face conversation view."),
WelcomeSheetPageRow(imageSystemName: "mic.badge.plus",
title: "Auto Translate",
content: "Respond in conversations without tapping the microphone button."),
WelcomeSheetPageRow(imageSystemName: "iphone",
title: "System-Wide Translation",
content: "Translate selected text anywhere on your iPhone.")
], mainButtonTitle: "Wassup?")
]
var body: some View {
Button("Show sheet") {
showSheet.toggle()
}
.welcomeSheet(isPresented: $showSheet, onDismiss: { print("Sheet dismissed") }, isSlideToDismissDisabled: true, pages: pages)
}
}
```
================================================
FILE: Sources/WelcomeSheet/Dimensions/iPadSheetDimensions.swift
================================================
//
// iPadSheetDimensions.swift
//
//
// Created by Jakub Florek on 29/11/2021.
//
import SwiftUI
struct iPadSheetDimensions {
static var width: CGFloat {
let width = UIScreen.main.bounds.width
if width >= 1024 { // iPad pro 12.9"
return width / 1.65
} else if width == 744 || width == 768 { // iPad mini (6th gen), older iPads
return width / 1.2
} else if width > 810 { // iPads bigger than standard iPad
return width / 1.35
} else { // The rest
return width / 1.3
}
}
static var height: CGFloat {
let height = UIScreen.main.bounds.height
if height >= 1366 { // iPad pro 12.9"
return height / 1.65
} else if height == 1133 { // iPad mini (6th gen)
return height / 1.7
} else if height > 1080 { // iPads bigger than standard iPad
return height / 1.6
} else { // The rest
return height / 1.5
}
}
}
================================================
FILE: Sources/WelcomeSheet/Dimensions/iPhoneDimensions.swift
================================================
//
// iPhoneDimensions.swift
//
//
// Created by Jakub Florek on 29/11/2021.
//
import SwiftUI
struct iPhoneDimensions {
static let screenHeight = UIScreen.main.bounds.height
static var spacing: CGFloat {
if UIScreen.main.nativeBounds.height == 2340 || screenHeight < 736 { // iPhone mini, Smaller than iPhone plus
return 30
} else { // The rest
return 60
}
}
static var topPadding: CGFloat {
if screenHeight == 568 { // iPhone SE 1st gen
return 50
} else if screenHeight <= 736 { // Smaller than iPhone plus
return 60
} else { // The rest
return 80
}
}
static var horizontalPaddingAddend: CGFloat {
if screenHeight * UIScreen.main.nativeScale >= 896 * 3 || screenHeight == 736 { // iPhone pro max, iPhone plus
return 20
} else if screenHeight == 568 { // iPhone SE 1st gen
return -10
} else { // The rest
return 0
}
}
}
================================================
FILE: Sources/WelcomeSheet/Extensions/AnyView+Extensitons.swift
================================================
//
// File.swift
//
//
// Created by Jakub Florek on 14/01/2023.
//
import SwiftUI
extension AnyView: Identifiable {
public var id: UUID {
UUID()
}
}
================================================
FILE: Sources/WelcomeSheet/Extensions/Color+Extensions.swift
================================================
//
// Color+Extensions.swift
//
//
// Created by Jakub Florek on 05/12/2021.
//
import SwiftUI
extension Color {
init(hex: String) {
let hex = hex.trimmingCharacters(in: CharacterSet.alphanumerics.inverted)
var int: UInt64 = 0
Scanner(string: hex).scanHexInt64(&int)
let a, r, g, b: UInt64
switch hex.count {
case 3: // RGB (12-bit)
(a, r, g, b) = (255, (int >> 8) * 17, (int >> 4 & 0xF) * 17, (int & 0xF) * 17)
case 6: // RGB (24-bit)
(a, r, g, b) = (255, int >> 16, int >> 8 & 0xFF, int & 0xFF)
case 8: // ARGB (32-bit)
(a, r, g, b) = (int >> 24, int >> 16 & 0xFF, int >> 8 & 0xFF, int & 0xFF)
default:
(a, r, g, b) = (1, 1, 1, 0)
}
self.init(
.sRGB,
red: Double(r) / 255,
green: Double(g) / 255,
blue: Double(b) / 255,
opacity: Double(a) / 255
)
}
}
================================================
FILE: Sources/WelcomeSheet/Extensions/UIColor+Extensions.swift
================================================
//
// File.swift
//
//
// Created by Jakub Florek on 18/01/2023.
//
import SwiftUI
extension UIColor {
func toColor() -> Color {
Color(self)
}
}
================================================
FILE: Sources/WelcomeSheet/Extensions/UIImage+Extensions.swift
================================================
//
// UIImage+Extensions.swift
//
//
// Created by Eskil Gjerde Sviggum on 30/01/2023.
//
import UIKit
extension UIImage {
func systemSymbolName() -> String? {
guard let imageAsset = self.imageAsset else {
return nil
}
let systemSymbolAssetManagerName = "CoreGlyphs"
// Get the assetName, and assetManagerName.
guard
imageAsset.responds(to: NSSelectorFromString("assetName")),
let assetName = imageAsset.value(forKey: "_assetName") as? String,
imageAsset.responds(to: NSSelectorFromString("_assetManager")),
let assetManager = imageAsset.value(forKey: "_assetManager") as? NSObject,
let assetManagerName = assetManager.value(forKey: "_assetManagerName") as? String
else {
assertionFailure("assetName or assetManagerName is not available.")
return nil
}
// Check if image is a system symbol.
if assetManagerName != systemSymbolAssetManagerName {
return nil
}
return assetName
}
}
================================================
FILE: Sources/WelcomeSheet/Models/UIWelcomeSheetPage.swift
================================================
//
// UIWelcomeSheetPage.swift
//
//
// Created by Eskil Gjerde Sviggum on 18/01/2023.
//
import UIKit
@objc
public class UIWelcomeSheetPage: NSObject {
/// Large title displayed on the top.
@IBInspectable
public var title: String = ""
/// Rows of content inside body.
@IBOutlet
public var rows: [UIWelcomeSheetPageRow] = []
/// Title for the main button. Set to `"Continue"` by
@IBInspectable
public var mainButtonTitle: String = "Continue"
/// Color used for main buttons. When `nil`, uses default accent color.
@IBInspectable
public var accentColor: UIColor?
/// Background color. When `nil`, uses default system background.
@IBInspectable
public var backgroundColor: UIColor?
/// Specifies whether to show the optional button.
@IBInspectable
public var isShowingOptionalButton = false
/// Optional button title.
@IBInspectable
public var optionalButtonTitle: String?
/// URL to open after optional button is tapped.
@IBInspectable
public var optionalButtonURL: String?
/// Clousure executed after optional button is tapped.
public var optionalButtonAction: (() -> ())?
/// Clousure executed after optional button is tapped.
public var optionalButtonView: UIView?
func welcomeSheetPage() -> WelcomeSheetPage {
WelcomeSheetPage(title: title, rows: rows.map { $0.welcomeSheetPageRow() }, accentUIColor: accentColor, backgroundUIColor: backgroundColor, mainButtonTitle: mainButtonTitle, optionalButtonTitle: optionalButtonTitle, optionalButtonURL: URL(string: optionalButtonURL ?? ""), optionalButtonAction: optionalButtonAction, optionalButtonUIView: optionalButtonView)
}
}
================================================
FILE: Sources/WelcomeSheet/Models/UIWelcomeSheetPageRow.swift
================================================
//
// UIWelcomeSheetPageRow.swift
//
//
// Created by Eskil Gjerde Sviggum on 18/01/2023.
//
import UIKit
@objc
public class UIWelcomeSheetPageRow: NSObject {
/// Title displayed above the content.
@IBInspectable
public var title: String = ""
/// Text displayed beneath the title.
@IBInspectable
public var content: String = ""
/// Image displayed at the beginning of a row.
@IBInspectable
public var image: UIImage = UIImage()
/// Color used for image. When `nil`, uses default accent color.
@IBInspectable
public var accentColor: UIColor?
func welcomeSheetPageRow() -> WelcomeSheetPageRow {
WelcomeSheetPageRow(uiImage: image, accentUIColor: accentColor, title: title, content: content)
}
}
================================================
FILE: Sources/WelcomeSheet/Models/WelcomeSheetPage.swift
================================================
//
// WelcomeSheetPage.swift
//
//
// Created by Jakub Florek on 27/11/2021.
//
import SwiftUI
/// Describes Welcome Sheet page's content.
public struct WelcomeSheetPage: Identifiable, Decodable {
private enum CodingKeys : String, CodingKey {
case title, rows, mainButtonTitle, accentColor, backgroundColor, isShowingOptionalButton, optionalButtonTitle, optionalButtonURL
}
public var id = UUID()
/// Large title displayed on the top.
public var title: String
/// Rows of content inside body.
public var rows: [WelcomeSheetPageRow]
/// Title for the main button. Set to `"Continue"` by default.
public var mainButtonTitle: String
/// Color used for main buttons. When `nil`, uses default accent color.
public var accentColor: Color?
/// Background color. When `nil`, uses default system background.
public var backgroundColor: Color?
/// Specifies whether to show the optional button.
public var isShowingOptionalButton = false
/// Optional button title.
public var optionalButtonTitle: String?
/// URL to open after optional button is tapped.
public var optionalButtonURL: URL?
/// Clousure executed after optional button is tapped.
public var optionalButtonAction: (() -> ())?
/// View shown after optional button is tapped.
public var optionalButtonView: AnyView?
private init(title: String, rows: [WelcomeSheetPageRow], accentColor: Color? = nil, backgroundColor: Color? = nil, mainButtonTitle: String? = nil, optionalButtonTitle: String? = nil, optionalButtonURL: URL? = nil, optionalButtonAction: (() -> ())? = nil, optionalButtonView: AnyView? = nil) {
self.title = title
self.rows = rows
self.mainButtonTitle = mainButtonTitle ?? "Continue"
self.accentColor = accentColor
self.backgroundColor = backgroundColor
self.isShowingOptionalButton = true
self.optionalButtonTitle = optionalButtonTitle
self.optionalButtonURL = optionalButtonURL
self.optionalButtonAction = optionalButtonAction
self.optionalButtonView = optionalButtonView
}
/// Creates Welcome Sheet page.
public init(title: String, rows: [WelcomeSheetPageRow], mainButtonTitle: String? = nil, optionalButtonTitle: String? = nil, optionalButtonURL: URL? = nil, optionalButtonAction: (() -> ())? = nil, optionalButtonUIView: UIView? = nil) {
self.init(title: title, rows: rows, accentColor: nil, backgroundColor: nil, mainButtonTitle: mainButtonTitle, optionalButtonTitle: optionalButtonTitle, optionalButtonURL: optionalButtonURL, optionalButtonAction: optionalButtonAction, optionalButtonView: Self.getAnyViewFrom(uiVIew: optionalButtonUIView))
}
// V SwiftUI Initializers V
/// Creates Welcome Sheet page.
public init(title: String, rows: [WelcomeSheetPageRow], accentColor: Color?, backgroundColor: Color?, mainButtonTitle: String? = nil, optionalButtonTitle: String? = nil, optionalButtonURL: URL? = nil, optionalButtonAction: (() -> ())? = nil, optionalButtonView: (() -> any View)? = nil) {
self.init(title: title, rows: rows, accentColor: accentColor, backgroundColor: backgroundColor, mainButtonTitle: mainButtonTitle, optionalButtonTitle: optionalButtonTitle, optionalButtonURL: optionalButtonURL, optionalButtonAction: optionalButtonAction, optionalButtonView: Self.getAnyViewFrom(view: optionalButtonView))
}
/// Creates Welcome Sheet page.
public init(title: String, rows: [WelcomeSheetPageRow], accentColor: Color?, mainButtonTitle: String? = nil, optionalButtonTitle: String? = nil, optionalButtonURL: URL? = nil, optionalButtonAction: (() -> ())? = nil, optionalButtonView: (() -> any View)? = nil) {
self.init(title: title, rows: rows, accentColor: accentColor, backgroundColor: nil, mainButtonTitle: mainButtonTitle, optionalButtonTitle: optionalButtonTitle, optionalButtonURL: optionalButtonURL, optionalButtonAction: optionalButtonAction, optionalButtonView: Self.getAnyViewFrom(view: optionalButtonView))
}
/// Creates Welcome Sheet page.
public init(title: String, rows: [WelcomeSheetPageRow], backgroundColor: Color?, mainButtonTitle: String? = nil, optionalButtonTitle: String? = nil, optionalButtonURL: URL? = nil, optionalButtonAction: (() -> ())? = nil, optionalButtonView: (() -> any View)? = nil) {
self.init(title: title, rows: rows, accentColor: nil, backgroundColor: backgroundColor, mainButtonTitle: mainButtonTitle, optionalButtonTitle: optionalButtonTitle, optionalButtonURL: optionalButtonURL, optionalButtonAction: optionalButtonAction, optionalButtonView: Self.getAnyViewFrom(view: optionalButtonView))
}
// V UIKit initializer V
/// Creates Welcome Sheet page.
public init(title: String, rows: [WelcomeSheetPageRow], accentUIColor: UIColor?, backgroundUIColor: UIColor?, mainButtonTitle: String? = nil, optionalButtonTitle: String? = nil, optionalButtonURL: URL? = nil, optionalButtonAction: (() -> ())? = nil, optionalButtonUIView: UIView? = nil) {
self.init(title: title, rows: rows, accentColor: accentUIColor?.toColor(), backgroundColor: backgroundUIColor?.toColor(), mainButtonTitle: mainButtonTitle, optionalButtonTitle: optionalButtonTitle, optionalButtonURL: optionalButtonURL, optionalButtonAction: optionalButtonAction, optionalButtonView: Self.getAnyViewFrom(uiVIew: optionalButtonUIView))
}
/// Creates Welcome Sheet page.
public init(title: String, rows: [WelcomeSheetPageRow], accentUIColor: UIColor?, mainButtonTitle: String? = nil, optionalButtonTitle: String? = nil, optionalButtonURL: URL? = nil, optionalButtonAction: (() -> ())? = nil, optionalButtonUIView: UIView? = nil) {
self.init(title: title, rows: rows, accentColor: accentUIColor?.toColor(), backgroundColor: nil, mainButtonTitle: mainButtonTitle, optionalButtonTitle: optionalButtonTitle, optionalButtonURL: optionalButtonURL, optionalButtonAction: optionalButtonAction, optionalButtonView: Self.getAnyViewFrom(uiVIew: optionalButtonUIView))
}
/// Creates Welcome Sheet page.
public init(title: String, rows: [WelcomeSheetPageRow], backgroundUIColor: UIColor?, mainButtonTitle: String? = nil, optionalButtonTitle: String? = nil, optionalButtonURL: URL? = nil, optionalButtonAction: (() -> ())? = nil, optionalButtonUIView: UIView? = nil) {
self.init(title: title, rows: rows, accentColor: nil, backgroundColor: backgroundUIColor?.toColor(), mainButtonTitle: mainButtonTitle, optionalButtonTitle: optionalButtonTitle, optionalButtonURL: optionalButtonURL, optionalButtonAction: optionalButtonAction, optionalButtonView: Self.getAnyViewFrom(uiVIew: optionalButtonUIView))
}
// V Codable initializer V
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
title = try container.decode(String.self, forKey: .title)
rows = try container.decode([WelcomeSheetPageRow].self, forKey: .rows)
do {
mainButtonTitle = try container.decode(String.self, forKey: .mainButtonTitle)
} catch {
mainButtonTitle = "Continue"
}
do {
let colorHex = try container.decode(String.self, forKey: .accentColor)
accentColor = Color(hex: colorHex)
} catch {
accentColor = nil
}
do {
let colorHex = try container.decode(String.self, forKey: .backgroundColor)
backgroundColor = Color(hex: colorHex)
} catch {
accentColor = nil
}
do {
optionalButtonTitle = try container.decode(String.self, forKey: .optionalButtonTitle)
} catch {
optionalButtonTitle = nil
}
do {
let urlString = try container.decode(String.self, forKey: .optionalButtonURL)
optionalButtonURL = URL(string: urlString)
} catch {
optionalButtonURL = nil
}
do {
isShowingOptionalButton = try container.decode(Bool.self, forKey: .isShowingOptionalButton)
} catch {
if optionalButtonTitle != nil {
isShowingOptionalButton = true
} else {
isShowingOptionalButton = false
}
}
}
}
private extension WelcomeSheetPage {
static func getAnyViewFrom(view: (() -> any View)?) -> AnyView? {
guard let view else { return nil }
return AnyView(view())
}
static func getAnyViewFrom(uiVIew: UIView?) -> AnyView? {
guard let uiVIew else { return nil }
return AnyView(OptionalButtonView(uiView: uiVIew))
}
}
================================================
FILE: Sources/WelcomeSheet/Models/WelcomeSheetPageRow.swift
================================================
//
// WelcomeSheetPageRow.swift
//
//
// Created by Jakub Florek on 27/11/2021.
//
import SwiftUI
/// Describes Welcome Sheet page row's content.
public struct WelcomeSheetPageRow: Identifiable, Decodable {
private enum CodingKeys : String, CodingKey {
case title, content, imageName, accentColor
}
public var id = UUID()
/// Title displayed above the content.
public var title: String
/// Text displayed beneath the title.
public var content: String
/// Image displayed at the beginning of a row.
public var image: Image
/// Color used for image. When `nil`, uses default accent color.
public var accentColor: Color?
// V SwiftUI Initializers V
/// Creates Welcome Sheet page row with given image, title and content.
public init(image: Image, accentColor: Color? = nil, title: String, content: String) {
self.image = image
self.accentColor = accentColor
self.title = title
self.content = content
}
/// Creates Welcome Sheet page row with system image, given title and content. Tints image with specified colour.
public init(imageSystemName: String, accentColor: Color?, title: String, content: String) {
self.init(image: Image(systemName: imageSystemName), accentColor: accentColor, title: title, content: content)
}
/// Creates Welcome Sheet page row with image name, given title and content. Tints image with specified colour.
public init(imageNamed: String, accentColor: Color?, title: String, content: String) {
self.init(image: Image(imageNamed), accentColor: accentColor, title: title, content: content)
}
// V UIKit initializers V
/// Creates Welcome Sheet page row with given image, title and content. Tints image with specified colour.
public init(uiImage: UIImage, accentUIColor: UIColor? = nil, title: String, content: String) {
if let systemSymbolName = uiImage.systemSymbolName() {
self.init(imageSystemName: systemSymbolName, accentUIColor: accentUIColor, title: title, content: content)
} else {
self.init(image: Image(uiImage: uiImage), accentColor: accentUIColor?.toColor(), title: title, content: content)
}
}
/// Creates Welcome Sheet page row with system image, given title and content. Tints image with specified colour.
public init(imageSystemName: String, accentUIColor: UIColor?, title: String, content: String) {
self.init(image: Image(systemName: imageSystemName), accentColor: accentUIColor?.toColor(), title: title, content: content)
}
/// Creates Welcome Sheet page row with image name, given title and content. Tints image with specified colour.
public init(imageNamed: String, accentUIColor: UIColor?, title: String, content: String) {
self.init(image: Image(imageNamed), accentColor: accentUIColor?.toColor(), title: title, content: content)
}
// V Universal initializers V
/// Creates Welcome Sheet page row with system image, given title and content. Tints image with specified colour.
public init(imageSystemName: String, title: String, content: String) {
self.init(image: Image(systemName: imageSystemName), title: title, content: content)
}
/// Creates Welcome Sheet page row with image name, given title and content. Tints image with specified colour.
public init(imageNamed: String, title: String, content: String) {
self.init(image: Image(imageNamed), title: title, content: content)
}
// V Codable initializer V
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
title = try container.decode(String.self, forKey: .title)
content = try container.decode(String.self, forKey: .content)
let imageName = try container.decode(String.self, forKey: .imageName)
if let uiImage = UIImage(named: imageName) {
image = Image(uiImage: uiImage)
} else {
image = Image(systemName: imageName)
}
do {
let colorHex = try container.decode(String.self, forKey: .accentColor)
accentColor = Color(hex: colorHex)
} catch {
accentColor = nil
}
}
}
================================================
FILE: Sources/WelcomeSheet/Views/HorizontalAlignment.swift
================================================
//
// File.swift
//
//
// Created by Jakub Florek on 14/01/2023.
//
import SwiftUI
extension HorizontalAlignment {
enum MidIcons: AlignmentID {
static func defaultValue(in d: ViewDimensions) -> CGFloat {
d[.leading]
}
}
static let midIcons = HorizontalAlignment(MidIcons.self)
}
================================================
FILE: Sources/WelcomeSheet/Views/OptionalButtonView.swift
================================================
//
// File.swift
//
//
// Created by Jakub Florek on 18/01/2023.
//
import SwiftUI
struct OptionalButtonView: UIViewRepresentable {
let uiView: UIView
func makeUIView(context: Context) -> UIView { uiView }
func updateUIView(_ uiView: UIView, context: Context) {}
}
================================================
FILE: Sources/WelcomeSheet/Views/ScrollOnlyOnOverflow.swift
================================================
// Source: https://stackoverflow.com/a/66875954
import SwiftUI
struct OverflowScrollView<Content>: View where Content : View {
@State private var axes: Axis.Set
private let showsIndicator: Bool
private let content: Content
init(_ axes: Axis.Set = .vertical, showsIndicators: Bool = true, @ViewBuilder content: @escaping () -> Content) {
self._axes = .init(wrappedValue: axes)
self.showsIndicator = showsIndicators
self.content = content()
}
fileprivate init(scrollView: ScrollView<Content>) {
self._axes = .init(wrappedValue: scrollView.axes)
self.showsIndicator = scrollView.showsIndicators
self.content = scrollView.content
}
public var body: some View {
GeometryReader { geometry in
ScrollView(axes, showsIndicators: showsIndicator) {
content
.background(ContentSizeReader())
.onPreferenceChange(ContentSizeKey.self) {
if $0.height <= geometry.size.height {
axes.remove(.vertical)
}
if $0.width <= geometry.size.width {
axes.remove(.horizontal)
}
}
}
}
}
}
private struct ContentSizeReader: View {
var body: some View {
GeometryReader {
Color.clear
.preference(
key: ContentSizeKey.self,
value: $0.frame(in: .local).size
)
}
}
}
private struct ContentSizeKey: PreferenceKey {
static var defaultValue: CGSize { .zero }
static func reduce(value: inout Value, nextValue: () -> Value) {
value = CGSize(width: value.width+nextValue().width,
height: value.height+nextValue().height)
}
}
extension ScrollView {
func scrollOnlyOnOverflow() -> some View {
OverflowScrollView(scrollView: self)
}
}
================================================
FILE: Sources/WelcomeSheet/Views/WelcomeSheetModal.swift
================================================
//
// WelcomeSheetModal.swift
//
//
// Created by Jakub Florek on 14/01/2023.
//
import SwiftUI
open class ModalWelcomeSheetUIHostingController: UIHostingController<WelcomeSheetView>, UIPopoverPresentationControllerDelegate {
override internal init(rootView: WelcomeSheetView) {
super.init(rootView: rootView)
self.rootView.onDismiss = getOnDismiss(with: rootView.onDismiss)
modalPresentationStyle = .formSheet
preferredContentSize = CGSize(width: iPadSheetDimensions.width, height: iPadSheetDimensions.height)
presentationController?.delegate = self
}
required public init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") }
public func presentationControllerDidDismiss(_ presentationController: UIPresentationController) { rootView.onDismiss() }
internal func getOnDismiss(with action: @escaping () -> Void) -> (() -> Void) {
return { [weak self] in
action()
self?.dismiss(animated: true)
}
}
}
class ModalWelcomeSheetUIViewController: UIViewController {
var isSlideToDismissDisabled: Bool?
var welcomeSheetView: WelcomeSheetView?
func show() {
guard let welcomeSheetView else { return }
let hostVC = ModalWelcomeSheetUIHostingController(rootView: welcomeSheetView)
hostVC.overrideUserInterfaceStyle = self.overrideUserInterfaceStyle
hostVC.isModalInPresentation = isSlideToDismissDisabled ?? false
present(hostVC, animated: true)
}
}
struct ModalWelcomeSheetUIViewControllerRepresentable: UIViewControllerRepresentable {
let show: Bool
let isSlideToDismissDisabled: Bool
let preferredColorScheme: ColorScheme?
let welcomeSheetView: WelcomeSheetView
var userInterfaceStyle: UIUserInterfaceStyle? {
if preferredColorScheme == .dark {
return .dark
} else {
return .light
}
}
func makeUIViewController(context: UIViewControllerRepresentableContext<ModalWelcomeSheetUIViewControllerRepresentable>) -> ModalWelcomeSheetUIViewController {
let vc = ModalWelcomeSheetUIViewController()
vc.welcomeSheetView = welcomeSheetView
vc.isSlideToDismissDisabled = isSlideToDismissDisabled
if let userInterfaceStyle {
vc.overrideUserInterfaceStyle = userInterfaceStyle
}
return vc
}
func updateUIViewController(_ uiViewController: ModalWelcomeSheetUIViewController, context: UIViewControllerRepresentableContext<ModalWelcomeSheetUIViewControllerRepresentable>) {
if show {
uiViewController.show()
} else {
uiViewController.dismiss(animated: true)
}
}
}
================================================
FILE: Sources/WelcomeSheet/Views/WelcomeSheetPageView.swift
================================================
//
// WelcomeSheetPageView.swift
//
//
// Created by Jakub Florek on 27/11/2021.
//
import SwiftUI
struct WelcomeSheetPageView: View {
let page: WelcomeSheetPage
let restPages: [WelcomeSheetPage]
let onDismiss: () -> Void
let isiPad = UIDevice.current.userInterfaceIdiom == .pad
@State private var optionalView: AnyView?
var body: some View {
VStack(spacing: 0) {
ScrollView {
VStack(spacing: iPhoneDimensions.spacing) {
HStack {
Spacer()
if #available(iOS 15.0, *) {
Text(page.title)
.font(.largeTitle)
.fontWeight(.bold)
.lineSpacing(8)
.multilineTextAlignment(.center)
.padding(.top, iPhoneDimensions.topPadding - (isiPad ? 15 : 0))
.fixedSize(horizontal: false, vertical: true)
.accessibilityHeading(.h1)
} else {
Text(page.title)
.font(.largeTitle)
.fontWeight(.bold)
.lineSpacing(8)
.multilineTextAlignment(.center)
.padding(.top, iPhoneDimensions.topPadding - (isiPad ? 15 : 0))
.fixedSize(horizontal: false, vertical: true)
}
Spacer()
}
VStack(alignment: .midIcons, spacing: 30) {
ForEach(page.rows) { row in
HStack(spacing: 17.5) {
row.image
.renderingMode(.template)
.resizable()
.scaledToFit()
.foregroundColor(row.accentColor ?? Color.accentColor)
.frame(width: 37, height: 37)
.alignmentGuide(.midIcons) { d in d[HorizontalAlignment.center] }
.accessibility(hidden: true)
VStack(alignment: .leading, spacing: 2) {
Text(row.title)
.font(.headline)
.lineLimit(2)
.fixedSize(horizontal: false, vertical: true)
Text(row.content)
.font(.subheadline)
.foregroundColor(.secondary)
.fixedSize(horizontal: false, vertical: true)
}
Spacer()
}
.padding(.horizontal, 20 + iPhoneDimensions.horizontalPaddingAddend)
.accessibilityElement(children: .combine)
}
}
}
.padding(.horizontal)
.padding(.horizontal, isiPad ? 45 : 0)
}
.scrollOnlyOnOverflow()
VStack(spacing: 5) {
if page.isShowingOptionalButton {
if let optionalButtonTitle = page.optionalButtonTitle {
Button(optionalButtonTitle) {
if let view = page.optionalButtonView {
optionalView = view
} else if let action = page.optionalButtonAction {
action()
} else if let url = page.optionalButtonURL {
UIApplication.shared.open(url)
}
}
.buttonStyle(PlainButtonStyle())
.font(Font.headline.weight(.medium))
.foregroundColor(page.accentColor ?? Color.accentColor)
.padding(.top)
}
}
if let nextPage = restPages.first {
NavigationLink {
WelcomeSheetPageView(page: nextPage, restPages: restPages.filter({ $0.id != nextPage.id }), onDismiss: onDismiss)
} label: {
ZStack {
page.accentColor ?? Color.accentColor
Text(page.mainButtonTitle)
.font(.headline)
.foregroundColor(.white)
.padding()
}
.frame(width: isiPad ? iPadSheetDimensions.width / 1.7 : nil)
.fixedSize(horizontal: false, vertical: true)
.clipShape(RoundedRectangle(cornerRadius: 15, style: .continuous))
}
.buttonStyle(PlainButtonStyle())
.padding(.horizontal, 10)
.padding(.top)
} else {
Button {
onDismiss()
} label: {
ZStack {
page.accentColor ?? Color.accentColor
Text(page.mainButtonTitle)
.font(.headline)
.foregroundColor(.white)
.padding()
}
.frame(width: isiPad ? iPadSheetDimensions.width / 1.7 : nil)
.fixedSize(horizontal: false, vertical: true)
.clipShape(RoundedRectangle(cornerRadius: 15, style: .continuous))
}
.buttonStyle(PlainButtonStyle())
.padding(.horizontal, 10)
.padding(.top)
}
}
.padding(.horizontal, 15 + iPhoneDimensions.horizontalPaddingAddend)
.padding(.bottom, 60)
.sheet(item: $optionalView) { view in
view.edgesIgnoringSafeArea(.all)
}
}
.background(
page.backgroundColor.edgesIgnoringSafeArea(.all)
)
.edgesIgnoringSafeArea(.top)
}
}
================================================
FILE: Sources/WelcomeSheet/Views/WelcomeSheetView.swift
================================================
//
// WelcomeSheetView.swift
//
//
// Created by Jakub Florek on 27/11/2021.
//
import SwiftUI
public struct WelcomeSheetView: View {
var pages: [WelcomeSheetPage]
var onDismiss: () -> Void
public var body: some View {
NavigationView {
if let firstPage = pages.first {
WelcomeSheetPageView(page: firstPage, restPages: pages.filter({ $0.id != firstPage.id }), onDismiss: onDismiss)
.navigationBarTitle(Text(""), displayMode: .inline)
.navigationBarHidden(true)
}
}
.navigationViewStyle(StackNavigationViewStyle())
}
}
================================================
FILE: Sources/WelcomeSheet/WelcomeSheet.swift
================================================
//
// WelcomeSheet.swift
//
//
// Created by Jakub Florek on 27/11/2021.
//
import SwiftUI
struct WelcomeSheet: ViewModifier {
@Binding var showSheet: Bool
let pages: [WelcomeSheetPage]
let onDismiss: () -> Void
let isSlideToDismissDisabled: Bool
let preferredColorScheme: ColorScheme?
func body(content: Content) -> some View {
content
.background(ModalWelcomeSheetUIViewControllerRepresentable(show: showSheet, isSlideToDismissDisabled: isSlideToDismissDisabled, preferredColorScheme: preferredColorScheme, welcomeSheetView: WelcomeSheetView(pages: pages, onDismiss: getOnDismiss())))
}
func getOnDismiss() -> () -> Void {
return {
showSheet = false
onDismiss()
}
}
}
public extension View {
/// Presents Welcome Sheet with given pages when a binding to a Boolean value that you provide is true.
func welcomeSheet(isPresented showSheet: Binding<Bool>, onDismiss: @escaping () -> Void = {}, isSlideToDismissDisabled: Bool = false, preferredColorScheme: ColorScheme? = nil, pages: [WelcomeSheetPage]) -> some View {
modifier(WelcomeSheet(showSheet: showSheet, pages: pages, onDismiss: onDismiss, isSlideToDismissDisabled: isSlideToDismissDisabled, preferredColorScheme: preferredColorScheme))
}
}
================================================
FILE: Sources/WelcomeSheet/WelcomeSheetController.swift
================================================
//
// WelcomeSheetController.swift
//
//
// Created by Kevin Romero Peces-Barba on 2/10/22.
//
import UIKit
open class WelcomeSheetController: ModalWelcomeSheetUIHostingController {
/// Pages of the sheet.
public var pages: [WelcomeSheetPage] = [] {
didSet {
rootView.pages = pages
}
}
/// Closure called on dismissal of the sheet.
public var onDismiss: (() -> Void)?
/// Creates Welcome Sheet controller without pages and onDismiss action.
public init() {
super.init(rootView: WelcomeSheetView(pages: [], onDismiss: {}))
rootView.onDismiss = getOnDismiss(with: didDismiss)
}
/// Creates Welcome Sheet controller with given pages and onDismiss action.
public init(pages: [WelcomeSheetPage], isSlideToDismissDisabled: Bool = false, onDismiss: @escaping () -> Void = {}) {
super.init(rootView: WelcomeSheetView(pages: pages, onDismiss: {}))
self.onDismiss = onDismiss
rootView.onDismiss = getOnDismiss(with: didDismiss)
self.pages = pages
self.isModalInPresentation = isSlideToDismissDisabled
}
required public init?(coder: NSCoder) {
super.init(rootView: WelcomeSheetView(pages: [], onDismiss: {}))
rootView.onDismiss = getOnDismiss(with: didDismiss)
}
open func didDismiss() {
self.onDismiss?()
}
}
================================================
FILE: Sources/WelcomeSheet/WelcomeSheetStoryboardController.swift
================================================
//
// WelcomeSheetController.swift
//
//
// Created by Eskil Gjerde Sviggum on 29/01/2023.
//
import UIKit
import SwiftUI
@objc
public protocol WelcomeSheetDelegate: AnyObject {
@objc
optional func welcomeSheetController(didDismiss welcomeSheetController: UIViewController)
@objc
optional func welcomeSheetController(pages welcomeSheetController: UIViewController) -> [UIWelcomeSheetPage]
}
open class WelcomeSheetStoryboardController: ModalWelcomeSheetUIHostingController {
@IBOutlet weak public var delegate: WelcomeSheetDelegate?
/// Pages of the sheet.
@IBOutlet
public var pages: [UIWelcomeSheetPage] = [] {
didSet {
rootView.pages = pages.map { $0.welcomeSheetPage() }
}
}
/// Closure called on dismissal of the sheet.
public var onDismiss: (() -> Void)?
/// Creates Welcome Sheet controller without pages and onDismiss action.
public init() {
super.init(rootView: WelcomeSheetView(pages: [], onDismiss: {}))
rootView.onDismiss = getOnDismiss(with: didDismiss)
}
/// Creates Welcome Sheet controller with given pages and onDismiss action.
public init(pages: [UIWelcomeSheetPage], isSlideToDismissDisabled: Bool = false, onDismiss: @escaping () -> Void = {}) {
super.init(rootView: WelcomeSheetView(pages: pages.map { $0.welcomeSheetPage() }, onDismiss: {}))
self.onDismiss = onDismiss
rootView.onDismiss = getOnDismiss(with: didDismiss)
self.pages = pages
self.isModalInPresentation = isSlideToDismissDisabled
}
required public init?(coder: NSCoder) {
super.init(rootView: WelcomeSheetView(pages: [], onDismiss: {}))
rootView.onDismiss = getOnDismiss(with: didDismiss)
}
public override func viewDidLoad() {
if let pages = delegate?.welcomeSheetController?(pages: self) {
self.pages = pages
} else {
rootView.pages = pages.map { $0.welcomeSheetPage() }
}
}
open func didDismiss() {
delegate?.welcomeSheetController?(didDismiss: self)
self.onDismiss?()
}
}
gitextract_z12ur_l3/
├── .gitignore
├── .swiftpm/
│ └── xcode/
│ └── package.xcworkspace/
│ └── xcshareddata/
│ └── IDEWorkspaceChecks.plist
├── Demo/
│ ├── UIKit-Storyboard-WelcomeSheetDemo/
│ │ ├── Readme.md
│ │ ├── UIKit-Storyboard-WelcomeSheetDemo/
│ │ │ ├── AppDelegate.swift
│ │ │ ├── Assets.xcassets/
│ │ │ │ ├── AccentColor.colorset/
│ │ │ │ │ └── Contents.json
│ │ │ │ ├── AppIcon.appiconset/
│ │ │ │ │ └── Contents.json
│ │ │ │ ├── Contents.json
│ │ │ │ └── gears.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── Base.lproj/
│ │ │ │ ├── LaunchScreen.storyboard
│ │ │ │ └── Main.storyboard
│ │ │ ├── Info.plist
│ │ │ ├── SceneDelegate.swift
│ │ │ └── ViewController.swift
│ │ └── UIKit-Storyboard-WelcomeSheetDemo.xcodeproj/
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ ├── UIKit-WelcomeSheetDemo/
│ │ ├── UIKit-WelcomeSheetDemo/
│ │ │ ├── AppDelegate.swift
│ │ │ ├── Assets.xcassets/
│ │ │ │ ├── AccentColor.colorset/
│ │ │ │ │ └── Contents.json
│ │ │ │ ├── AppIcon.appiconset/
│ │ │ │ │ └── Contents.json
│ │ │ │ ├── Contents.json
│ │ │ │ └── gears.imageset/
│ │ │ │ └── Contents.json
│ │ │ ├── Base.lproj/
│ │ │ │ ├── LaunchScreen.storyboard
│ │ │ │ └── Main.storyboard
│ │ │ ├── Info.plist
│ │ │ ├── SceneDelegate.swift
│ │ │ └── ViewController.swift
│ │ └── UIKit-WelcomeSheetDemo.xcodeproj/
│ │ ├── project.pbxproj
│ │ └── project.xcworkspace/
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata/
│ │ └── IDEWorkspaceChecks.plist
│ └── WelcomeSheetDemo/
│ ├── Shared/
│ │ ├── Assets.xcassets/
│ │ │ ├── AccentColor.colorset/
│ │ │ │ └── Contents.json
│ │ │ ├── AppIcon.appiconset/
│ │ │ │ └── Contents.json
│ │ │ ├── Contents.json
│ │ │ └── gears.imageset/
│ │ │ └── Contents.json
│ │ ├── ContentView.swift
│ │ ├── WelcomeSheetDemoApp.swift
│ │ └── demo.json
│ ├── WelcomeSheetDemo.xcodeproj/
│ │ └── project.pbxproj
│ └── macOS/
│ └── macOS.entitlements
├── Documentation/
│ └── UIKit/
│ └── Readme.md
├── LICENSE
├── Package.swift
├── README.md
└── Sources/
└── WelcomeSheet/
├── Dimensions/
│ ├── iPadSheetDimensions.swift
│ └── iPhoneDimensions.swift
├── Extensions/
│ ├── AnyView+Extensitons.swift
│ ├── Color+Extensions.swift
│ ├── UIColor+Extensions.swift
│ └── UIImage+Extensions.swift
├── Models/
│ ├── UIWelcomeSheetPage.swift
│ ├── UIWelcomeSheetPageRow.swift
│ ├── WelcomeSheetPage.swift
│ └── WelcomeSheetPageRow.swift
├── Views/
│ ├── HorizontalAlignment.swift
│ ├── OptionalButtonView.swift
│ ├── ScrollOnlyOnOverflow.swift
│ ├── WelcomeSheetModal.swift
│ ├── WelcomeSheetPageView.swift
│ └── WelcomeSheetView.swift
├── WelcomeSheet.swift
├── WelcomeSheetController.swift
└── WelcomeSheetStoryboardController.swift
Condensed preview — 61 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (189K chars).
[
{
"path": ".gitignore",
"chars": 126,
"preview": ".DS_Store\n/.build\n/Packages\n/*.xcodeproj\nxcuserdata/\nDerivedData/\n.swiftpm/xcode/package.xcworkspace/contents.xcworkspac"
},
{
"path": ".swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Demo/UIKit-Storyboard-WelcomeSheetDemo/Readme.md",
"chars": 166,
"preview": "# UIKit Storyboard WelcomeSheet Demo\n\nFor a step-by-step guide on how to configure by storyboards, please see the [Docum"
},
{
"path": "Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo/AppDelegate.swift",
"chars": 1383,
"preview": "//\n// AppDelegate.swift\n// UIKit-Storyboard-WelcomeSheetDemo\n//\n// Created by Eskil Gjerde Sviggum on 18/01/2023.\n//\n"
},
{
"path": "Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo/Assets.xcassets/AccentColor.colorset/Contents.json",
"chars": 335,
"preview": "{\n \"colors\" : [\n {\n \"color\" : {\n \"color-space\" : \"display-p3\",\n \"components\" : {\n \"alpha"
},
{
"path": "Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo/Assets.xcassets/AppIcon.appiconset/Contents.json",
"chars": 208,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"1024.png\",\n \"idiom\" : \"universal\",\n \"platform\" : \"ios\",\n \"size"
},
{
"path": "Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo/Assets.xcassets/Contents.json",
"chars": 63,
"preview": "{\n \"info\" : {\n \"author\" : \"xcode\",\n \"version\" : 1\n }\n}\n"
},
{
"path": "Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo/Assets.xcassets/gears.imageset/Contents.json",
"chars": 312,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"settings-gears.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\"\n },"
},
{
"path": "Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo/Base.lproj/LaunchScreen.storyboard",
"chars": 1665,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard"
},
{
"path": "Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo/Base.lproj/Main.storyboard",
"chars": 24007,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3"
},
{
"path": "Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo/Info.plist",
"chars": 704,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo/SceneDelegate.swift",
"chars": 2326,
"preview": "//\n// SceneDelegate.swift\n// UIKit-Storyboard-WelcomeSheetDemo\n//\n// Created by Eskil Gjerde Sviggum on 18/01/2023.\n/"
},
{
"path": "Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo/ViewController.swift",
"chars": 769,
"preview": "//\n// ViewController.swift\n// UIKit-Storyboard-WelcomeSheetDemo\n//\n// Created by Eskil Gjerde Sviggum on 18/01/2023.\n"
},
{
"path": "Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo.xcodeproj/project.pbxproj",
"chars": 15995,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 56;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "Demo/UIKit-Storyboard-WelcomeSheetDemo/UIKit-Storyboard-WelcomeSheetDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo/AppDelegate.swift",
"chars": 1373,
"preview": "//\n// AppDelegate.swift\n// UIKit-WelcomeSheetDemo\n//\n// Created by Kevin Romero Peces-Barba on 6/10/22.\n//\n\nimport UI"
},
{
"path": "Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo/Assets.xcassets/AccentColor.colorset/Contents.json",
"chars": 335,
"preview": "{\n \"colors\" : [\n {\n \"color\" : {\n \"color-space\" : \"display-p3\",\n \"components\" : {\n \"alpha"
},
{
"path": "Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo/Assets.xcassets/AppIcon.appiconset/Contents.json",
"chars": 4025,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"40.png\",\n \"idiom\" : \"iphone\",\n \"scale\" : \"2x\",\n \"size\" : \"20x2"
},
{
"path": "Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo/Assets.xcassets/Contents.json",
"chars": 63,
"preview": "{\n \"info\" : {\n \"author\" : \"xcode\",\n \"version\" : 1\n }\n}\n"
},
{
"path": "Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo/Assets.xcassets/gears.imageset/Contents.json",
"chars": 312,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"settings-gears.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\"\n },"
},
{
"path": "Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo/Base.lproj/LaunchScreen.storyboard",
"chars": 1665,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard"
},
{
"path": "Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo/Base.lproj/Main.storyboard",
"chars": 3229,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3"
},
{
"path": "Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo/Info.plist",
"chars": 704,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo/SceneDelegate.swift",
"chars": 2316,
"preview": "//\n// SceneDelegate.swift\n// UIKit-WelcomeSheetDemo\n//\n// Created by Kevin Romero Peces-Barba on 6/10/22.\n//\n\nimport "
},
{
"path": "Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo/ViewController.swift",
"chars": 5258,
"preview": "//\n// ViewController.swift\n// UIKit-WelcomeSheetDemo\n//\n// Created by Kevin Romero Peces-Barba on 6/10/22.\n//\n\nimport"
},
{
"path": "Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo.xcodeproj/project.pbxproj",
"chars": 15953,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 56;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata",
"chars": 135,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Workspace\n version = \"1.0\">\n <FileRef\n location = \"self:\">\n </FileRef"
},
{
"path": "Demo/UIKit-WelcomeSheetDemo/UIKit-WelcomeSheetDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
"chars": 238,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Demo/WelcomeSheetDemo/Shared/Assets.xcassets/AccentColor.colorset/Contents.json",
"chars": 335,
"preview": "{\n \"colors\" : [\n {\n \"color\" : {\n \"color-space\" : \"display-p3\",\n \"components\" : {\n \"alpha"
},
{
"path": "Demo/WelcomeSheetDemo/Shared/Assets.xcassets/AppIcon.appiconset/Contents.json",
"chars": 4742,
"preview": "{\"images\":[{\"size\":\"60x60\",\"expected-size\":\"180\",\"filename\":\"180.png\",\"folder\":\"Assets.xcassets/AppIcon.appiconset/\",\"id"
},
{
"path": "Demo/WelcomeSheetDemo/Shared/Assets.xcassets/Contents.json",
"chars": 63,
"preview": "{\n \"info\" : {\n \"author\" : \"xcode\",\n \"version\" : 1\n }\n}\n"
},
{
"path": "Demo/WelcomeSheetDemo/Shared/Assets.xcassets/gears.imageset/Contents.json",
"chars": 312,
"preview": "{\n \"images\" : [\n {\n \"filename\" : \"settings-gears.png\",\n \"idiom\" : \"universal\",\n \"scale\" : \"1x\"\n },"
},
{
"path": "Demo/WelcomeSheetDemo/Shared/ContentView.swift",
"chars": 5676,
"preview": "//\n// ContentView.swift\n// Shared\n//\n// Created by Jakub Florek on 27/11/2021.\n//\n\nimport SwiftUI\nimport WelcomeSheet"
},
{
"path": "Demo/WelcomeSheetDemo/Shared/WelcomeSheetDemoApp.swift",
"chars": 243,
"preview": "//\n// WelcomeSheetDemoApp.swift\n// Shared\n//\n// Created by Jakub Florek on 27/11/2021.\n//\n\nimport SwiftUI\n\n@main\nstru"
},
{
"path": "Demo/WelcomeSheetDemo/Shared/demo.json",
"chars": 1177,
"preview": "[\r\n {\r\n \"optionalButtonURL\":\"https:\\/\\/github.com\\/MAJKFL\\/Welcome-Sheet\",\r\n \"accentColor\":\"BF5AF2\",\r\n "
},
{
"path": "Demo/WelcomeSheetDemo/WelcomeSheetDemo.xcodeproj/project.pbxproj",
"chars": 19169,
"preview": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 55;\n\tobjects = {\n\n/* Begin PBXBuildFile section *"
},
{
"path": "Demo/WelcomeSheetDemo/macOS/macOS.entitlements",
"chars": 322,
"preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/P"
},
{
"path": "Documentation/UIKit/Readme.md",
"chars": 3249,
"preview": "# Configuring from Storyboards\n\nYou can set up the pages of your Welcome Sheet from a Storyboard or XIB file—without wri"
},
{
"path": "LICENSE",
"chars": 1069,
"preview": "MIT License\n\nCopyright (c) 2021 Jakub Florek\n\nPermission is hereby granted, free of charge, to any person obtaining a co"
},
{
"path": "Package.swift",
"chars": 958,
"preview": "// swift-tools-version:5.5\n// The swift-tools-version declares the minimum version of Swift required to build this packa"
},
{
"path": "README.md",
"chars": 10425,
"preview": "# Welcome Sheet\n\n\n\nWelcome sheet for iOS enables incredibly "
},
{
"path": "Sources/WelcomeSheet/Dimensions/iPadSheetDimensions.swift",
"chars": 1034,
"preview": "//\n// iPadSheetDimensions.swift\n// \n//\n// Created by Jakub Florek on 29/11/2021.\n//\n\nimport SwiftUI\n\nstruct iPadSheet"
},
{
"path": "Sources/WelcomeSheet/Dimensions/iPhoneDimensions.swift",
"chars": 1054,
"preview": "//\n// iPhoneDimensions.swift\n// \n//\n// Created by Jakub Florek on 29/11/2021.\n//\n\nimport SwiftUI\n\nstruct iPhoneDimens"
},
{
"path": "Sources/WelcomeSheet/Extensions/AnyView+Extensitons.swift",
"chars": 172,
"preview": "//\n// File.swift\n// \n//\n// Created by Jakub Florek on 14/01/2023.\n//\n\nimport SwiftUI\n\nextension AnyView: Identifiable"
},
{
"path": "Sources/WelcomeSheet/Extensions/Color+Extensions.swift",
"chars": 973,
"preview": "//\n// Color+Extensions.swift\n// \n//\n// Created by Jakub Florek on 05/12/2021.\n//\n\nimport SwiftUI\n\nextension Color {\n "
},
{
"path": "Sources/WelcomeSheet/Extensions/UIColor+Extensions.swift",
"chars": 167,
"preview": "//\n// File.swift\n// \n//\n// Created by Jakub Florek on 18/01/2023.\n//\n\nimport SwiftUI\n\nextension UIColor {\n func to"
},
{
"path": "Sources/WelcomeSheet/Extensions/UIImage+Extensions.swift",
"chars": 1161,
"preview": "//\n// UIImage+Extensions.swift\n// \n//\n// Created by Eskil Gjerde Sviggum on 30/01/2023.\n//\n\nimport UIKit\n\nextension U"
},
{
"path": "Sources/WelcomeSheet/Models/UIWelcomeSheetPage.swift",
"chars": 1765,
"preview": "//\n// UIWelcomeSheetPage.swift\n// \n//\n// Created by Eskil Gjerde Sviggum on 18/01/2023.\n//\n\nimport UIKit\n\n@objc\npubli"
},
{
"path": "Sources/WelcomeSheet/Models/UIWelcomeSheetPageRow.swift",
"chars": 783,
"preview": "//\n// UIWelcomeSheetPageRow.swift\n// \n//\n// Created by Eskil Gjerde Sviggum on 18/01/2023.\n//\n\nimport UIKit\n\n@objc\npu"
},
{
"path": "Sources/WelcomeSheet/Models/WelcomeSheetPage.swift",
"chars": 8823,
"preview": "//\n// WelcomeSheetPage.swift\n// \n//\n// Created by Jakub Florek on 27/11/2021.\n//\n\nimport SwiftUI\n\n/// Describes Welco"
},
{
"path": "Sources/WelcomeSheet/Models/WelcomeSheetPageRow.swift",
"chars": 4372,
"preview": "//\n// WelcomeSheetPageRow.swift\n//\n//\n// Created by Jakub Florek on 27/11/2021.\n//\n\nimport SwiftUI\n\n/// Describes Welc"
},
{
"path": "Sources/WelcomeSheet/Views/HorizontalAlignment.swift",
"chars": 326,
"preview": "//\n// File.swift\n// \n//\n// Created by Jakub Florek on 14/01/2023.\n//\n\nimport SwiftUI\n\nextension HorizontalAlignment {"
},
{
"path": "Sources/WelcomeSheet/Views/OptionalButtonView.swift",
"chars": 289,
"preview": "//\n// File.swift\n// \n//\n// Created by Jakub Florek on 18/01/2023.\n//\n\nimport SwiftUI\n\nstruct OptionalButtonView: UIVi"
},
{
"path": "Sources/WelcomeSheet/Views/ScrollOnlyOnOverflow.swift",
"chars": 2042,
"preview": "// Source: https://stackoverflow.com/a/66875954\n\nimport SwiftUI\n\nstruct OverflowScrollView<Content>: View where Content "
},
{
"path": "Sources/WelcomeSheet/Views/WelcomeSheetModal.swift",
"chars": 2799,
"preview": "//\n// WelcomeSheetModal.swift\n//\n//\n// Created by Jakub Florek on 14/01/2023.\n//\n\nimport SwiftUI\n\nopen class ModalWelc"
},
{
"path": "Sources/WelcomeSheet/Views/WelcomeSheetPageView.swift",
"chars": 6859,
"preview": "//\n// WelcomeSheetPageView.swift\n//\n//\n// Created by Jakub Florek on 27/11/2021.\n//\n\nimport SwiftUI\n\nstruct WelcomeShe"
},
{
"path": "Sources/WelcomeSheet/Views/WelcomeSheetView.swift",
"chars": 646,
"preview": "//\n// WelcomeSheetView.swift\n//\n//\n// Created by Jakub Florek on 27/11/2021.\n//\n\nimport SwiftUI\n\npublic struct Welcome"
},
{
"path": "Sources/WelcomeSheet/WelcomeSheet.swift",
"chars": 1330,
"preview": "//\n// WelcomeSheet.swift\n//\n//\n// Created by Jakub Florek on 27/11/2021.\n//\n\nimport SwiftUI\n \nstruct WelcomeSheet: Vie"
},
{
"path": "Sources/WelcomeSheet/WelcomeSheetController.swift",
"chars": 1407,
"preview": "//\n// WelcomeSheetController.swift\n// \n//\n// Created by Kevin Romero Peces-Barba on 2/10/22.\n//\n\nimport UIKit\n\nopen c"
},
{
"path": "Sources/WelcomeSheet/WelcomeSheetStoryboardController.swift",
"chars": 2177,
"preview": "//\n// WelcomeSheetController.swift\n//\n//\n// Created by Eskil Gjerde Sviggum on 29/01/2023.\n//\n\nimport UIKit\nimport Swi"
}
]
About this extraction
This page contains the full source code of the MAJKFL/Welcome-Sheet GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 61 files (166.2 KB), approximately 45.8k tokens. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.