♻️ :: Update example application

This commit is contained in:
Felix Mau
2022-03-07 21:53:13 +01:00
parent d484da4f83
commit d9c7840323
150 changed files with 2398 additions and 10351 deletions
@@ -0,0 +1,11 @@
{
"colors" : [
{
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,98 @@
{
"images" : [
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
},
{
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
},
{
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "20x20"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "40x40"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
},
{
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"
},
{
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
+31
View File
@@ -0,0 +1,31 @@
//
// ExampleApp.swift
// Example
//
// Created by Felix Mau on 07.03.22.
// Copyright © 2022 Felix Mau. All rights reserved.
//
import SwiftUI
@main
struct ExampleApp: App {
var body: some Scene {
WindowGroup {
EntryPointView()
.onAppear {
// Use iOS 13 navigation bar appearance.
//
// While the entry point scene looks better with an opaque navigation background, the child scenes look
// better with the default navigation background. As we can't update the appearance per scene we fallback
// to an appearance with the default background here.
//
// Based on: https://sarunw.com/posts/uinavigationbar-changes-in-ios13/
let appearance = UINavigationBarAppearance()
appearance.configureWithDefaultBackground()
UINavigationBar.appearance().scrollEdgeAppearance = appearance
}
}
}
}
@@ -0,0 +1,28 @@
//
// StoryboardView.swift
// Example
//
// Created by Felix Mau on 02.02.22.
// Copyright © 2022 Felix Mau. All rights reserved.
//
import SwiftUI
struct StoryboardView: UIViewControllerRepresentable {
// MARK: - Public properties
let name: String
// MARK: - Public properties
func makeUIViewController(context _: Context) -> UIViewController {
let storyboard = UIStoryboard(name: name, bundle: nil)
guard let viewController = storyboard.instantiateInitialViewController() else {
fatalError("⚠️ Could not instantiate initial view controller for storyboard with name `\(name)`.")
}
return viewController
}
func updateUIViewController(_: UIViewController, context _: Context) {}
}
@@ -0,0 +1,6 @@
{
"info" : {
"author" : "xcode",
"version" : 1
}
}
@@ -0,0 +1,76 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Y6W-OH-hqX">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
<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>
<!--Advanced Example View Controller-->
<scene sceneID="s0d-6b-0kx">
<objects>
<viewController id="Y6W-OH-hqX" customClass="AdvancedExampleViewController" customModule="Example" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="5EZ-qb-Rvc">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="wBu-Jx-yJe">
<rect key="frame" x="16" y="409" width="382" height="78"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="cc6-eP-2iq" userLabel="Custom Superview Button" customClass="BorderedButton" customModule="Example" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="382" height="31"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="plain" title="Custom Superview">
<fontDescription key="titleFontDescription" style="UICTFontTextStyleBody"/>
</buttonConfiguration>
<connections>
<action selector="toggleCustomSuperviewButtonTouchUpInside:" destination="Y6W-OH-hqX" eventType="touchUpInside" id="0Yr-Fe-Acm"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="kEU-Kf-t9a" userLabel="Custom Colors Button">
<rect key="frame" x="0.0" y="47" width="382" height="31"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="Custom Colors">
<fontDescription key="titleFontDescription" style="UICTFontTextStyleBody"/>
</buttonConfiguration>
<connections>
<action selector="toggleCustomColorsButtonTouchUpInside:" destination="Y6W-OH-hqX" eventType="touchUpInside" id="loC-hh-CUH"/>
</connections>
</button>
</subviews>
</stackView>
</subviews>
<viewLayoutGuide key="safeArea" id="vDu-zF-Fre"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="wBu-Jx-yJe" firstAttribute="leading" secondItem="vDu-zF-Fre" secondAttribute="leading" constant="16" id="Rnt-hi-cwg"/>
<constraint firstItem="vDu-zF-Fre" firstAttribute="trailing" secondItem="wBu-Jx-yJe" secondAttribute="trailing" constant="16" id="qcu-sZ-sEv"/>
<constraint firstItem="wBu-Jx-yJe" firstAttribute="centerY" secondItem="5EZ-qb-Rvc" secondAttribute="centerY" id="quc-6s-WJW"/>
</constraints>
</view>
<connections>
<outlet property="customColorsButton" destination="kEU-Kf-t9a" id="cmO-oH-05r"/>
<outlet property="customSuperviewButton" destination="cc6-eP-2iq" id="fqL-8j-Z58"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Ief-a0-LHa" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="132" y="62"/>
</scene>
</scenes>
<designables>
<designable name="cc6-eP-2iq">
<size key="intrinsicContentSize" width="145.5" height="31"/>
</designable>
<designable name="kEU-Kf-t9a">
<size key="intrinsicContentSize" width="119.5" height="31"/>
</designable>
</designables>
<resources>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>
@@ -0,0 +1,129 @@
//
// AdvancedExampleViewController.swift
// Example
//
// Created by Felix Mau on 07.03.22.
// Copyright © 2022 Felix Mau. All rights reserved.
//
import UIKit
import SwiftUI
import GradientLoadingBar
final class AdvancedExampleViewController: UIViewController {
// MARK: - Config
private enum Config {
/// The programatically applied height of the `GradientActivityIndicatorView`.
static let height: CGFloat = 3.5
}
// MARK: - Outlets
@IBOutlet private var customSuperviewButton: BorderedButton!
@IBOutlet private var customColorsButton: UIButton!
// MARK: - Private properties
private let customSuperviewGradientActivityIndicatorView = GradientActivityIndicatorView()
private let customColorsGradientLoadingBar = GradientLoadingBar()
// MARK: - Public methods
override func viewDidLoad() {
super.viewDidLoad()
setupCustomSuperviewGradientActivityIndicatorView()
setupCustomColorsGradientLoadingBar()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Reset any possible visible loading bar.
customSuperviewGradientActivityIndicatorView.fadeOut()
customColorsGradientLoadingBar.fadeOut()
}
// MARK: - Private methods
private func setupCustomSuperviewGradientActivityIndicatorView() {
customSuperviewGradientActivityIndicatorView.isHidden = true
customSuperviewGradientActivityIndicatorView.alpha = 0
customSuperviewGradientActivityIndicatorView.translatesAutoresizingMaskIntoConstraints = false
customSuperviewButton.addSubview(customSuperviewGradientActivityIndicatorView)
NSLayoutConstraint.activate([
customSuperviewGradientActivityIndicatorView.leadingAnchor.constraint(equalTo: customSuperviewButton.leadingAnchor),
customSuperviewGradientActivityIndicatorView.trailingAnchor.constraint(equalTo: customSuperviewButton.trailingAnchor),
customSuperviewGradientActivityIndicatorView.topAnchor.constraint(equalTo: customSuperviewButton.topAnchor),
customSuperviewGradientActivityIndicatorView.heightAnchor.constraint(equalToConstant: Config.height),
])
}
private func setupCustomColorsGradientLoadingBar() {
// Source: https://color.adobe.com/Pink-Flamingo-color-theme-10343714/
customColorsGradientLoadingBar.gradientColors = [
#colorLiteral(red: 0.9490196078, green: 0.3215686275, blue: 0.431372549, alpha: 1), #colorLiteral(red: 0.9450980392, green: 0.4784313725, blue: 0.5921568627, alpha: 1), #colorLiteral(red: 0.9529411765, green: 0.737254902, blue: 0.7843137255, alpha: 1), #colorLiteral(red: 0.4274509804, green: 0.8666666667, blue: 0.9490196078, alpha: 1), #colorLiteral(red: 0.7568627451, green: 0.9411764706, blue: 0.9568627451, alpha: 1),
]
}
@IBAction private func toggleCustomSuperviewButtonTouchUpInside(_: Any) {
if customSuperviewGradientActivityIndicatorView.isHidden {
customSuperviewGradientActivityIndicatorView.fadeIn()
} else {
customSuperviewGradientActivityIndicatorView.fadeOut()
}
}
@IBAction private func toggleCustomColorsButtonTouchUpInside(_: Any) {
// TODO: Add `isHidden` shortcut
if customColorsGradientLoadingBar.gradientActivityIndicatorView.isHidden {
customColorsGradientLoadingBar.fadeIn()
} else {
customColorsGradientLoadingBar.fadeOut()
}
}
}
// MARK: - Helpers
///
///
@IBDesignable
final class BorderedButton: UIButton {
private enum Config {
static let borderColor = #colorLiteral(red: 0.2862745098, green: 0.5647058824, blue: 0.8862745098, alpha: 1)
}
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
private func commonInit() {
backgroundColor = .clear
tintColor = Config.borderColor
layer.borderColor = Config.borderColor.cgColor
layer.borderWidth = 1
layer.cornerRadius = 4
layer.masksToBounds = true
}
}
struct AdvancedExampleView: View {
var body: some View {
StoryboardView(name: "AdvancedExample")
.navigationTitle("🚀 Advanced Example")
}
}
@@ -0,0 +1,64 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Y6W-OH-hqX">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
<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>
<!--Basic Example View Controller-->
<scene sceneID="s0d-6b-0kx">
<objects>
<viewController id="Y6W-OH-hqX" customClass="BasicExampleViewController" customModule="Example" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="5EZ-qb-Rvc">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="i3m-u5-CBZ">
<rect key="frame" x="16" y="432.5" width="382" height="31"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="iqR-B3-IAJ" userLabel="ShowButton">
<rect key="frame" x="0.0" y="0.0" width="183" height="31"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="Show">
<fontDescription key="titleFontDescription" style="UICTFontTextStyleBody"/>
</buttonConfiguration>
<connections>
<action selector="showButtonTouchUpInside:" destination="Y6W-OH-hqX" eventType="touchUpInside" id="syE-bX-c9J"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="0mi-83-2Nx" userLabel="HideButton">
<rect key="frame" x="199" y="0.0" width="183" height="31"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="Hide">
<fontDescription key="titleFontDescription" style="UICTFontTextStyleBody"/>
</buttonConfiguration>
<connections>
<action selector="hideButtonTouchUpInside:" destination="Y6W-OH-hqX" eventType="touchUpInside" id="xWJ-X0-hCH"/>
</connections>
</button>
</subviews>
</stackView>
</subviews>
<viewLayoutGuide key="safeArea" id="vDu-zF-Fre"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="i3m-u5-CBZ" firstAttribute="centerY" secondItem="5EZ-qb-Rvc" secondAttribute="centerY" id="J8f-pR-dOH"/>
<constraint firstItem="vDu-zF-Fre" firstAttribute="trailing" secondItem="i3m-u5-CBZ" secondAttribute="trailing" constant="16" id="RpI-X5-afT"/>
<constraint firstItem="i3m-u5-CBZ" firstAttribute="leading" secondItem="vDu-zF-Fre" secondAttribute="leading" constant="16" id="qcn-hk-qmQ"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Ief-a0-LHa" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="132" y="115"/>
</scene>
</scenes>
<resources>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>
@@ -0,0 +1,41 @@
//
// BasicExampleViewController.swift
// Example
//
// Created by Felix Mau on 07.03.22.
// Copyright © 2022 Felix Mau. All rights reserved.
//
import UIKit
import SwiftUI
import GradientLoadingBar
final class BasicExampleViewController: UIViewController {
// MARK: - Public methods
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Reset any possible visible loading bar.
GradientLoadingBar.shared.fadeOut()
}
// MARK: - Private methods
@IBAction private func showButtonTouchUpInside(_: Any) {
GradientLoadingBar.shared.fadeIn()
}
@IBAction private func hideButtonTouchUpInside(_: Any) {
GradientLoadingBar.shared.fadeOut()
}
}
// MARK: - Helpers
struct BasicExampleView: View {
var body: some View {
StoryboardView(name: "BasicExample")
.navigationTitle("🏡 Basic Example")
}
}
@@ -0,0 +1,97 @@
//
// EntryPointView.swift
// Example
//
// Created by Felix Mau on 07.03.22.
// Copyright © 2022 Felix Mau. All rights reserved.
//
import SwiftUI
struct EntryPointView: View {
// MARK: - Private properties
@State
private var isNavigationBarExampleVisible = false
// MARK: - Render
var body: some View {
NavigationView {
List {
Section(header: Text("Example Application")) {
NavigationLink(destination: BasicExampleView()) {
TitleSubtitleView(title: "🏡 Basic Example",
subtitle: "Basic usage and setup.")
}
NavigationLink(destination: SafeAreaExampleView()) {
TitleSubtitleView(title: "📲 Safe Area Example",
subtitle: "Loading bar ignoring the safe area.")
}
NavigationLink(destination: InterfaceBuilderExampleView()) {
TitleSubtitleView(title: "🎨 Interface Builder Example",
subtitle: "Setup in a storyboard or xib.")
}
NavigationLink(destination: AdvancedExampleView()) {
TitleSubtitleView(title: "🚀 Advanced Example",
subtitle: "How to apply e.g. custom colors.")
}
Button {
isNavigationBarExampleVisible = true
} label: {
TitleSubtitleView(title: "🧭 Navigation Bar Example",
subtitle: "Attach the loading bar to a navigation bar.")
// Make entire row tappable and not just the text.
.frame(maxWidth: .infinity, alignment: .leading)
.contentShape(Rectangle())
}
.buttonStyle(PlainButtonStyle())
NavigationLink(destination: SwiftUIExampleView()) {
TitleSubtitleView(title: "🪄 SwiftUI Example",
subtitle: "How to use in a SwiftUI context.")
}
}
}
// We present the `NavigationBarExampleView` as a sheet using it's own navigation controller.
// The `NavigationView` passed from SwiftUI isn't accessible from a `UIViewController` in a way, that we can add subviews to it.
.sheet(isPresented: $isNavigationBarExampleVisible) {
NavigationBarExampleView()
}
// Unfortunately setting the title here results in constraint warnings.
// I couldn't find a possible fix yet, even `.navigationViewStyle(.stack)` doesn't seem to work.
// https://stackoverflow.com/q/65316497
.navigationTitle("GradientProgressBar")
.navigationBarTitleDisplayMode(.large)
}
}
}
// MARK: - Subviews
private struct TitleSubtitleView: View {
let title: String
let subtitle: String
var body: some View {
VStack(alignment: .leading, spacing: 8) {
Text(title)
.font(.headline)
Text(subtitle)
.font(.subheadline)
}
.padding(.vertical, 8)
}
}
// MARK: - Preview
struct EntryPointView_Previews: PreviewProvider {
static var previews: some View {
EntryPointView()
}
}
@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Y6W-OH-hqX">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
<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>
<!--Interface Builder Example View Controller-->
<scene sceneID="s0d-6b-0kx">
<objects>
<viewController id="Y6W-OH-hqX" customClass="InterfaceBuilderExampleViewController" customModule="Example" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="5EZ-qb-Rvc">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="JRZ-82-J3x" customClass="GradientActivityIndicatorView" customModule="GradientLoadingBar">
<rect key="frame" x="16" y="60" width="382" height="3"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstAttribute="height" constant="3" id="E7r-bo-9Xk"/>
</constraints>
</view>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="L9o-al-XKN">
<rect key="frame" x="16" y="432.5" width="382" height="31"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="v1q-i7-LJ5" userLabel="ShowButton">
<rect key="frame" x="0.0" y="0.0" width="183" height="31"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="Show">
<fontDescription key="titleFontDescription" style="UICTFontTextStyleBody"/>
</buttonConfiguration>
<connections>
<action selector="showButtonTouchUpInside:" destination="Y6W-OH-hqX" eventType="touchUpInside" id="q22-io-OL4"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="kz6-Yl-S6N" userLabel="HideButton">
<rect key="frame" x="199" y="0.0" width="183" height="31"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="Hide">
<fontDescription key="titleFontDescription" style="UICTFontTextStyleBody"/>
</buttonConfiguration>
<connections>
<action selector="hideButtonTouchUpInside:" destination="Y6W-OH-hqX" eventType="touchUpInside" id="7r8-ac-gXr"/>
</connections>
</button>
</subviews>
</stackView>
</subviews>
<viewLayoutGuide key="safeArea" id="vDu-zF-Fre"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="JRZ-82-J3x" firstAttribute="leading" secondItem="vDu-zF-Fre" secondAttribute="leading" constant="16" id="AHc-Eb-KZU"/>
<constraint firstItem="L9o-al-XKN" firstAttribute="centerY" secondItem="5EZ-qb-Rvc" secondAttribute="centerY" id="Med-CE-cP1"/>
<constraint firstItem="vDu-zF-Fre" firstAttribute="trailing" secondItem="L9o-al-XKN" secondAttribute="trailing" constant="16" id="RjT-rE-G7c"/>
<constraint firstItem="L9o-al-XKN" firstAttribute="leading" secondItem="5EZ-qb-Rvc" secondAttribute="leading" constant="16" id="XZ6-eE-acR"/>
<constraint firstItem="JRZ-82-J3x" firstAttribute="top" secondItem="vDu-zF-Fre" secondAttribute="top" constant="16" id="mr4-ZU-4jd"/>
<constraint firstItem="vDu-zF-Fre" firstAttribute="trailing" secondItem="JRZ-82-J3x" secondAttribute="trailing" constant="16" id="r2O-pX-Qka"/>
</constraints>
</view>
<connections>
<outlet property="gradientActivityIndicatorView" destination="JRZ-82-J3x" id="cdf-nh-RRH"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Ief-a0-LHa" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="132" y="81"/>
</scene>
</scenes>
<resources>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>
@@ -0,0 +1,45 @@
//
// InterfaceBuilderExampleViewController.swift
// Example
//
// Created by Felix Mau on 07.03.22.
// Copyright © 2022 Felix Mau. All rights reserved.
//
import UIKit
import SwiftUI
import GradientLoadingBar
final class InterfaceBuilderExampleViewController: UIViewController {
// MARK: - Outlets
@IBOutlet private var gradientActivityIndicatorView: GradientActivityIndicatorView!
// MARK: - Public methods
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Reset any possible visible loading bar.
gradientActivityIndicatorView.fadeOut()
}
// MARK: - Private methods
@IBAction private func showButtonTouchUpInside(_: Any) {
gradientActivityIndicatorView.fadeIn()
}
@IBAction private func hideButtonTouchUpInside(_: Any) {
gradientActivityIndicatorView.fadeOut()
}
}
// MARK: - Helpers
struct InterfaceBuilderExampleView: View {
var body: some View {
StoryboardView(name: "InterfaceBuilderExample")
.navigationTitle("🎨 Interface Builder Example")
}
}
@@ -0,0 +1,83 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="QqU-dK-9N3">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
<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>
<!--🧭 Navigation Bar Example-->
<scene sceneID="s0d-6b-0kx">
<objects>
<viewController id="Y6W-OH-hqX" customClass="NavigationBarExampleViewController" customModule="Example" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="5EZ-qb-Rvc">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="NLc-ox-i4v">
<rect key="frame" x="16" y="432.5" width="382" height="31"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="m50-Bi-edx" userLabel="ShowButton">
<rect key="frame" x="0.0" y="0.0" width="183" height="31"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="Show">
<fontDescription key="titleFontDescription" style="UICTFontTextStyleBody"/>
</buttonConfiguration>
<connections>
<action selector="showButtonTouchUpInside:" destination="Y6W-OH-hqX" eventType="touchUpInside" id="Wp7-QY-9dg"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="aXh-Qp-yVs" userLabel="HideButton">
<rect key="frame" x="199" y="0.0" width="183" height="31"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="Hide">
<fontDescription key="titleFontDescription" style="UICTFontTextStyleBody"/>
</buttonConfiguration>
<connections>
<action selector="hideButtonTouchUpInside:" destination="Y6W-OH-hqX" eventType="touchUpInside" id="vxz-29-LMX"/>
</connections>
</button>
</subviews>
</stackView>
</subviews>
<viewLayoutGuide key="safeArea" id="vDu-zF-Fre"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="vDu-zF-Fre" firstAttribute="trailing" secondItem="NLc-ox-i4v" secondAttribute="trailing" constant="16" id="2Ig-gz-o5i"/>
<constraint firstItem="NLc-ox-i4v" firstAttribute="leading" secondItem="vDu-zF-Fre" secondAttribute="leading" constant="16" id="5DU-9Z-LFC"/>
<constraint firstItem="NLc-ox-i4v" firstAttribute="centerY" secondItem="5EZ-qb-Rvc" secondAttribute="centerY" id="uG6-3e-Y6q"/>
</constraints>
</view>
<navigationItem key="navigationItem" title="🧭 Navigation Bar Example" id="cJ0-SC-qx4"/>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Ief-a0-LHa" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1042.0289855072465" y="61.607142857142854"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="Fzj-P1-1gQ">
<objects>
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="QqU-dK-9N3" sceneMemberID="viewController">
<toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" largeTitles="YES" id="Gew-of-pOh">
<rect key="frame" x="0.0" y="44" width="414" height="104"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<nil name="viewControllers"/>
<connections>
<segue destination="Y6W-OH-hqX" kind="relationship" relationship="rootViewController" id="YmV-f4-HGX"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="brr-zi-WNx" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="131.8840579710145" y="61.607142857142854"/>
</scene>
</scenes>
<resources>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>
@@ -0,0 +1,81 @@
//
// NavigationBarExampleViewController.swift
// Example
//
// Created by Felix Mau on 07.03.22.
// Copyright © 2022 Felix Mau. All rights reserved.
//
import UIKit
import SwiftUI
import GradientLoadingBar
final class NavigationBarExampleViewController: UIViewController {
// MARK: - Config
private enum Config {
/// The programatically applied height of the `GradientActivityIndicatorView`.
static let height: CGFloat = 3
}
// MARK: - Private properties
private let gradientProgressIndicatorView = GradientActivityIndicatorView()
// MARK: - Public methods
override func viewDidLoad() {
super.viewDidLoad()
let barButtonItem = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(doneButtonTapped))
navigationItem.rightBarButtonItem = barButtonItem
setupGradientProgressIndicatorView()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Reset any possible visible loading bar.
gradientProgressIndicatorView.fadeOut()
}
// MARK: - Private methods
private func setupGradientProgressIndicatorView() {
guard let navigationBar = navigationController?.navigationBar else { return }
gradientProgressIndicatorView.fadeOut(duration: 0)
gradientProgressIndicatorView.translatesAutoresizingMaskIntoConstraints = false
navigationBar.addSubview(gradientProgressIndicatorView)
NSLayoutConstraint.activate([
gradientProgressIndicatorView.leadingAnchor.constraint(equalTo: navigationBar.leadingAnchor),
gradientProgressIndicatorView.trailingAnchor.constraint(equalTo: navigationBar.trailingAnchor),
gradientProgressIndicatorView.bottomAnchor.constraint(equalTo: navigationBar.bottomAnchor),
gradientProgressIndicatorView.heightAnchor.constraint(equalToConstant: Config.height),
])
}
@IBAction private func doneButtonTapped(_: Any) {
dismiss(animated: true)
}
@IBAction private func showButtonTouchUpInside(_: Any) {
gradientProgressIndicatorView.fadeIn()
}
@IBAction private func hideButtonTouchUpInside(_: Any) {
gradientProgressIndicatorView.fadeOut()
}
}
// MARK: - Helpers
struct NavigationBarExampleView: View {
var body: some View {
StoryboardView(name: "NavigationBarExample")
}
}
@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="Y6W-OH-hqX">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
<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>
<!--Safe Area Example View Controller-->
<scene sceneID="s0d-6b-0kx">
<objects>
<viewController id="Y6W-OH-hqX" customClass="SafeAreaExampleViewController" customModule="Example" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="5EZ-qb-Rvc">
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="vQo-n2-n4V" userLabel="Top Stack View">
<rect key="frame" x="16" y="409" width="382" height="31"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="xx7-io-IHi" userLabel="ShowBasicBarButton">
<rect key="frame" x="0.0" y="0.0" width="183" height="31"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="Show Basic Bar">
<fontDescription key="titleFontDescription" style="UICTFontTextStyleBody"/>
</buttonConfiguration>
<connections>
<action selector="showBasicBarButtonTouchUpInside:" destination="Y6W-OH-hqX" eventType="touchUpInside" id="o8j-Z6-6kZ"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Xxs-Xn-l65" userLabel="HideBasicBarButton">
<rect key="frame" x="199" y="0.0" width="183" height="31"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="Hide Basic Bar">
<fontDescription key="titleFontDescription" style="UICTFontTextStyleBody"/>
</buttonConfiguration>
<connections>
<action selector="hideBasicBarButtonTouchUpInside:" destination="Y6W-OH-hqX" eventType="touchUpInside" id="XXK-yZ-LR4"/>
</connections>
</button>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="J6X-XZ-YZb" userLabel="Bottom Stack View">
<rect key="frame" x="16" y="456" width="382" height="31"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="8wt-vv-Sj1" userLabel="ShowNotchBarButton">
<rect key="frame" x="0.0" y="0.0" width="183" height="31"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="Show Notch Bar">
<fontDescription key="titleFontDescription" style="UICTFontTextStyleBody"/>
</buttonConfiguration>
<connections>
<action selector="showNotchBarButtonTouchUpInside:" destination="Y6W-OH-hqX" eventType="touchUpInside" id="aHn-BO-ovO"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="DS9-JT-RIl" userLabel="HideNotchBarButton">
<rect key="frame" x="199" y="0.0" width="183" height="31"/>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="Hide Notch Bar">
<fontDescription key="titleFontDescription" style="UICTFontTextStyleBody"/>
</buttonConfiguration>
<connections>
<action selector="hideNotchBarButtonTouchUpInside:" destination="Y6W-OH-hqX" eventType="touchUpInside" id="INf-lf-Egt"/>
</connections>
</button>
</subviews>
</stackView>
</subviews>
<viewLayoutGuide key="safeArea" id="vDu-zF-Fre"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstItem="vDu-zF-Fre" firstAttribute="trailing" secondItem="J6X-XZ-YZb" secondAttribute="trailing" constant="16" id="FLY-Rz-mWy"/>
<constraint firstItem="vQo-n2-n4V" firstAttribute="leading" secondItem="5EZ-qb-Rvc" secondAttribute="leading" constant="16" id="Vh8-QH-gYf"/>
<constraint firstItem="J6X-XZ-YZb" firstAttribute="top" secondItem="5EZ-qb-Rvc" secondAttribute="centerY" constant="8" id="XPa-0S-CCv"/>
<constraint firstItem="J6X-XZ-YZb" firstAttribute="leading" secondItem="vDu-zF-Fre" secondAttribute="leading" constant="16" id="XpT-4k-VAf"/>
<constraint firstItem="vQo-n2-n4V" firstAttribute="bottom" secondItem="5EZ-qb-Rvc" secondAttribute="centerY" constant="-8" id="czm-UN-XEM"/>
<constraint firstItem="vDu-zF-Fre" firstAttribute="trailing" secondItem="vQo-n2-n4V" secondAttribute="trailing" constant="16" id="umO-We-0lr"/>
</constraints>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Ief-a0-LHa" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="133" y="115"/>
</scene>
</scenes>
<resources>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>
@@ -0,0 +1,55 @@
//
// SafeAreaExampleViewController.swift
// Example
//
// Created by Felix Mau on 07.03.22.
// Copyright © 2022 Felix Mau. All rights reserved.
//
import UIKit
import SwiftUI
import GradientLoadingBar
final class SafeAreaExampleViewController: UIViewController {
// MARK: - Private properties
private let gradientLoadingBar = GradientLoadingBar(isRelativeToSafeArea: false)
private let notchGradientLoadingBar = NotchGradientLoadingBar(isRelativeToSafeArea: false)
// MARK: - Public methods
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Reset any possible visible loading bar.
gradientLoadingBar.fadeOut()
notchGradientLoadingBar.fadeOut()
}
// MARK: - Private methods
@IBAction private func showBasicBarButtonTouchUpInside(_: Any) {
gradientLoadingBar.fadeIn()
}
@IBAction private func hideBasicBarButtonTouchUpInside(_: Any) {
gradientLoadingBar.fadeOut()
}
@IBAction private func showNotchBarButtonTouchUpInside(_: Any) {
notchGradientLoadingBar.fadeIn()
}
@IBAction private func hideNotchBarButtonTouchUpInside(_: Any) {
notchGradientLoadingBar.fadeOut()
}
}
// MARK: - Helpers
struct SafeAreaExampleView: View {
var body: some View {
StoryboardView(name: "SafeAreaExample")
.navigationTitle("📲 Safe Area Example")
}
}
@@ -0,0 +1,22 @@
//
// SwiftUIExampleView.swift
// Example
//
// Created by Felix Mau on 07.03.22.
// Copyright © 2022 Felix Mau. All rights reserved.
//
import SwiftUI
struct SwiftUIExampleView: View {
var body: some View {
Text("Coming soon!")
.navigationTitle("🎨 SwiftUI Example")
}
}
struct SwiftUIExampleView_Previews: PreviewProvider {
static var previews: some View {
SwiftUIExampleView()
}
}