♻️ :: Update example application

This commit is contained in:
Felix Mau
2022-04-15 18:40:44 +02:00
parent 6c9c0ab1e1
commit b981df3519
12 changed files with 534 additions and 302 deletions
@@ -1,97 +1,164 @@
<?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">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="ZAD-6Y-gxa">
<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"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
<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">
<!--Advanced Example Table View Controller-->
<scene sceneID="iwG-zT-VrO">
<objects>
<viewController id="Y6W-OH-hqX" customClass="AdvancedExampleViewController" customModule="Example" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="5EZ-qb-Rvc">
<tableViewController id="ZAD-6Y-gxa" customClass="AdvancedExampleTableViewController" customModule="Example" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="insetGrouped" separatorStyle="default" allowsSelection="NO" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" estimatedSectionHeaderHeight="-1" sectionFooterHeight="18" estimatedSectionFooterHeight="-1" id="2vt-bX-4b7">
<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="362.5" width="382" height="171"/>
<subviews>
<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="0.0" width="382" height="40"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="40" id="NJg-XX-Snw"/>
</constraints>
<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>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="9g2-oL-JNk" customClass="GradientActivityIndicatorView" customModule="GradientLoadingBar">
<rect key="frame" x="0.0" y="56" width="382" height="3"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstAttribute="height" constant="3" id="gVZ-Gu-0d8"/>
</constraints>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="5x1-lr-GQw" userLabel="Interface Builder Setup Button">
<rect key="frame" x="0.0" y="75" width="382" height="40"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="40" id="e4a-f8-HBf"/>
</constraints>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="Interface-Builder Setup">
<fontDescription key="titleFontDescription" style="UICTFontTextStyleBody"/>
</buttonConfiguration>
<connections>
<action selector="interfaceBuilderSetupButtonTouchUpInside:" destination="Y6W-OH-hqX" eventType="touchUpInside" id="zRi-LD-twy"/>
</connections>
</button>
<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="131" width="382" height="40"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="40" id="AkT-c3-A4M"/>
</constraints>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="plain" title="Custom Superview">
<fontDescription key="titleFontDescription" style="UICTFontTextStyleBody"/>
</buttonConfiguration>
<connections>
<action selector="customSuperviewButtonTouchUpInside:" destination="Y6W-OH-hqX" eventType="touchUpInside" id="ydP-3C-qZO"/>
</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"/>
<outlet property="gradientActivityIndicator" destination="9g2-oL-JNk" id="ge0-pf-6OJ"/>
<outlet property="interfaceBuilderSetupButton" destination="5x1-lr-GQw" id="1ja-dz-ejF"/>
<outlet property="stackView" destination="wBu-Jx-yJe" id="8j9-MR-DLr"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="Ief-a0-LHa" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="CustomColorsTableViewCell" id="qq9-jr-nNk" customClass="CustomColorsTableViewCell" customModule="Example" customModuleProvider="target">
<rect key="frame" x="20" y="49.5" width="374" height="120.5"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="qq9-jr-nNk" id="60G-w2-6BV">
<rect key="frame" x="0.0" y="0.0" width="374" height="120.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="12" translatesAutoresizingMaskIntoConstraints="NO" id="zN2-pr-LT6">
<rect key="frame" x="16" y="16" width="342" height="88.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Example showing how to provide custom gradient colors." textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lbJ-pG-fGJ">
<rect key="frame" x="0.0" y="0.0" width="342" height="36"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="uL7-lu-aRP" userLabel="Toggle Custom Colors Button">
<rect key="frame" x="0.0" y="48" width="342" height="40.5"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="40" id="jZd-Vw-MAb"/>
</constraints>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="Toggle Custom Colors ↑">
<fontDescription key="titleFontDescription" style="UICTFontTextStyleBody"/>
</buttonConfiguration>
<connections>
<action selector="customColorsButtonTouchUpInside:" destination="qq9-jr-nNk" eventType="touchUpInside" id="XyI-4Q-sja"/>
</connections>
</button>
</subviews>
</stackView>
</subviews>
<constraints>
<constraint firstItem="zN2-pr-LT6" firstAttribute="leading" secondItem="60G-w2-6BV" secondAttribute="leading" constant="16" id="18p-RW-IFT"/>
<constraint firstAttribute="bottom" secondItem="zN2-pr-LT6" secondAttribute="bottom" constant="16" id="6LP-eX-o55"/>
<constraint firstItem="zN2-pr-LT6" firstAttribute="top" secondItem="60G-w2-6BV" secondAttribute="top" constant="16" id="RzJ-mr-IHP"/>
<constraint firstAttribute="trailing" secondItem="zN2-pr-LT6" secondAttribute="trailing" constant="16" id="h7A-pm-6hb"/>
</constraints>
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="InterfaceBuilderSetupTableViewCell" id="yBS-fc-uJy" customClass="InterfaceBuilderSetupTableViewCell" customModule="Example" customModuleProvider="target">
<rect key="frame" x="20" y="170" width="374" height="83.5"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="yBS-fc-uJy" id="Tid-am-qRM">
<rect key="frame" x="0.0" y="0.0" width="374" height="83.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="8" translatesAutoresizingMaskIntoConstraints="NO" id="KTF-6b-NmT">
<rect key="frame" x="16" y="16" width="342" height="51.5"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bCd-m6-FJm" customClass="GradientActivityIndicatorView" customModule="GradientLoadingBar">
<rect key="frame" x="0.0" y="0.0" width="342" height="3"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<constraints>
<constraint firstAttribute="height" constant="3" id="FQe-RY-KH7"/>
</constraints>
</view>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="TpO-6A-9Bl" userLabel="Toggle IB Setup Button">
<rect key="frame" x="0.0" y="11" width="342" height="40.5"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="40" id="QLO-3y-Y29"/>
</constraints>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="Toggle IB Setup 🎨">
<fontDescription key="titleFontDescription" style="UICTFontTextStyleBody"/>
</buttonConfiguration>
<connections>
<action selector="toggleIBSetupButtonTouchUpInside:" destination="yBS-fc-uJy" eventType="touchUpInside" id="WLP-Dw-VmD"/>
</connections>
</button>
</subviews>
</stackView>
</subviews>
<constraints>
<constraint firstItem="KTF-6b-NmT" firstAttribute="top" secondItem="Tid-am-qRM" secondAttribute="top" constant="16" id="2Bc-ex-Ggk"/>
<constraint firstItem="KTF-6b-NmT" firstAttribute="leading" secondItem="Tid-am-qRM" secondAttribute="leading" constant="16" id="Aka-HV-cVb"/>
<constraint firstAttribute="bottom" secondItem="KTF-6b-NmT" secondAttribute="bottom" constant="16" id="MH0-A6-FGH"/>
<constraint firstAttribute="trailing" secondItem="KTF-6b-NmT" secondAttribute="trailing" constant="16" id="pLD-Mq-O5j"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="gradientActivityIndicator" destination="bCd-m6-FJm" id="z4t-IP-gqw"/>
</connections>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="CustomSuperviewViewCell" id="ah2-WM-rFd" customClass="CustomSuperviewTableViewCell" customModule="Example" customModuleProvider="target">
<rect key="frame" x="20" y="253.5" width="374" height="120.5"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="ah2-WM-rFd" id="2Sj-GS-zEL">
<rect key="frame" x="0.0" y="0.0" width="374" height="120.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="12" translatesAutoresizingMaskIntoConstraints="NO" id="ja4-s5-ZP7">
<rect key="frame" x="20" y="16" width="334" height="88.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Example showing how to add the loading bar as a subview." textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="c7X-oS-Zcv">
<rect key="frame" x="0.0" y="0.0" width="334" height="36"/>
<fontDescription key="fontDescription" style="UICTFontTextStyleBody"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="ZxZ-rY-wUa" userLabel="Toggle Custom Superview Button" customClass="BorderedButton" customModule="Example" customModuleProvider="target">
<rect key="frame" x="0.0" y="48" width="334" height="40.5"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="40" id="YS7-tA-cMK"/>
</constraints>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="plain" title="Toggle Custom Superview 🧪">
<fontDescription key="titleFontDescription" style="UICTFontTextStyleBody"/>
</buttonConfiguration>
<connections>
<action selector="toggleButtonTouchUpInside:" destination="ah2-WM-rFd" eventType="touchUpInside" id="W51-If-b5H"/>
</connections>
</button>
</subviews>
</stackView>
</subviews>
<constraints>
<constraint firstItem="ja4-s5-ZP7" firstAttribute="top" secondItem="2Sj-GS-zEL" secondAttribute="top" constant="16" id="ERr-8u-XhG"/>
<constraint firstAttribute="trailing" secondItem="ja4-s5-ZP7" secondAttribute="trailing" constant="20" id="SsK-Vx-1BL"/>
<constraint firstAttribute="bottom" secondItem="ja4-s5-ZP7" secondAttribute="bottom" constant="16" id="UBf-R5-ixV"/>
<constraint firstItem="ja4-s5-ZP7" firstAttribute="leading" secondItem="2Sj-GS-zEL" secondAttribute="leading" constant="20" id="xgE-OJ-VIu"/>
</constraints>
</tableViewCellContentView>
<connections>
<outlet property="toggleButton" destination="ZxZ-rY-wUa" id="TwF-62-tM1"/>
</connections>
</tableViewCell>
</prototypes>
<connections>
<outlet property="dataSource" destination="ZAD-6Y-gxa" id="3QD-qs-jpF"/>
<outlet property="delegate" destination="ZAD-6Y-gxa" id="yIF-PG-bRO"/>
</connections>
</tableView>
<extendedEdge key="edgesForExtendedLayout" bottom="YES"/>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="R94-H9-mvS" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="132" y="62"/>
<point key="canvasLocation" x="-165" y="27"/>
</scene>
</scenes>
<designables>
<designable name="cc6-eP-2iq">
<size key="intrinsicContentSize" width="145.5" height="31"/>
<designable name="ZxZ-rY-wUa">
<size key="intrinsicContentSize" width="216.5" height="31"/>
</designable>
</designables>
<resources>
@@ -0,0 +1,138 @@
//
// AdvancedExampleTableViewController.swift
// Example
//
// Created by Felix Mau on 12.04.22.
// Copyright © 2022 Felix Mau. All rights reserved.
//
import UIKit
import SwiftUI
import GradientLoadingBar
final class AdvancedExampleTableViewController: UITableViewController {
// MARK: - Config
private enum Config {
/// The custom gradient colors we use.
/// Source: https://color.adobe.com/Pink-Flamingo-color-theme-10343714/
static let 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),
]
///
static let firstSectionHeaderHeight: CGFloat = 48
///
static let defaultSectionHeaderHeight: CGFloat = 32
}
// MARK: - Types
private enum Section: CaseIterable {
case customColors
case interfaceBuilderSetup
case customSuperview
var cellIdentifier: String {
switch self {
case .customColors:
return CustomColorsTableViewCell.reuseIdentifier
case .interfaceBuilderSetup:
return InterfaceBuilderSetupTableViewCell.reuseIdentifier
case .customSuperview:
return CustomSuperviewTableViewCell.reuseIdentifier
}
}
var sectionTitle: String {
switch self {
case .customColors:
return "Custom Colors"
case .interfaceBuilderSetup:
return "Interface Builder Setup"
case .customSuperview:
return "Custom Superview"
}
}
var sectionHeaderHeight: CGFloat {
switch self {
case .customColors:
return Config.firstSectionHeaderHeight
case .interfaceBuilderSetup, .customSuperview:
return Config.defaultSectionHeaderHeight
}
}
}
// MARK: - Private properties
private let gradientLoadingBar = GradientLoadingBar()
// MARK: - Public methods
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemGroupedBackground
gradientLoadingBar.gradientColors = Config.gradientColors
}
// MARK: - Table view data source
override func numberOfSections(in _: UITableView) -> Int {
Section.allCases.count
}
override func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int {
1
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let section = Section.allCases[indexPath.section]
switch section {
case .customColors:
guard let cell = tableView.dequeueReusableCell(withIdentifier: section.cellIdentifier, for: indexPath) as? CustomColorsTableViewCell else {
fatalError("⚠️ Invalid table view setup. Expected to have `CustomColorsTableViewCell` at this point!")
}
cell.tapHandler = { [weak self] in
if self?.gradientLoadingBar.isHidden == true {
self?.gradientLoadingBar.fadeIn()
} else {
self?.gradientLoadingBar.fadeOut()
}
}
return cell
case .interfaceBuilderSetup, .customSuperview:
return tableView.dequeueReusableCell(withIdentifier: section.cellIdentifier, for: indexPath)
}
}
override func tableView(_: UITableView, titleForHeaderInSection section: Int) -> String? {
Section.allCases[section].sectionTitle
}
override func tableView(_: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
Section.allCases[section].sectionHeaderHeight
}
}
// MARK: - Helper
struct AdvancedExampleView: View {
var body: some View {
StoryboardView(name: "AdvancedExample")
.navigationTitle("🚀 Advanced Example")
.edgesIgnoringSafeArea(.bottom)
}
}
@@ -1,158 +0,0 @@
//
// 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
/// The custom gradient colors we use.
/// Source: https://color.adobe.com/Pink-Flamingo-color-theme-10343714/
static let 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),
]
static let smallStackViewSpacing: CGFloat = 8
}
// MARK: - Outlets
@IBOutlet private var stackView: UIStackView!
@IBOutlet private var customColorsButton: UIButton!
@IBOutlet private var gradientActivityIndicator: GradientActivityIndicatorView!
@IBOutlet private var interfaceBuilderSetupButton: UIButton!
@IBOutlet private var customSuperviewButton: BorderedButton!
// MARK: - Private properties
// swiftlint:disable:next identifier_name
private let customSuperviewGradientActivityIndicatorView = GradientActivityIndicatorView()
private let customColorsGradientLoadingBar = GradientLoadingBar()
// MARK: - Public methods
override func viewDidLoad() {
super.viewDidLoad()
setupStackView()
setupCustomColorsGradientLoadingBar()
setupCustomSuperviewGradientActivityIndicatorView()
}
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
// Reset any possible visible loading bar.
customColorsGradientLoadingBar.fadeOut()
}
// MARK: - Private methods
private func setupStackView() {
stackView.setCustomSpacing(Config.smallStackViewSpacing, after: gradientActivityIndicator)
}
private func setupCustomColorsGradientLoadingBar() {
customColorsGradientLoadingBar.gradientColors = Config.gradientColors
}
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),
])
}
@IBAction private func toggleCustomColorsButtonTouchUpInside(_: Any) {
if customColorsGradientLoadingBar.isHidden {
customColorsGradientLoadingBar.fadeIn()
} else {
customColorsGradientLoadingBar.fadeOut()
}
}
@IBAction private func interfaceBuilderSetupButtonTouchUpInside(_: Any) {
// We explicitly "only" reduce the alpha here, as calling `fadeIn()` / `fadeOut()` would update the `isHidden`
// flag accordingly. This would then lead to a height-update of the parent stack view.
UIView.animate(withDuration: 1.0) {
if self.gradientActivityIndicator.alpha > 0 {
self.gradientActivityIndicator.alpha = 0
} else {
self.gradientActivityIndicator.alpha = 1
}
}
}
@IBAction private func customSuperviewButtonTouchUpInside(_: Any) {
if customSuperviewGradientActivityIndicatorView.isHidden {
customSuperviewGradientActivityIndicatorView.fadeIn()
} else {
customSuperviewGradientActivityIndicatorView.fadeOut()
}
}
}
// MARK: - Subviews
@IBDesignable
final class BorderedButton: UIButton {
private enum Config {
static let borderColor = #colorLiteral(red: 0.2862745098, green: 0.5647058824, blue: 0.8862745098, alpha: 1)
static let borderWidth: CGFloat = 1
static let cornerRadius: CGFloat = 4
}
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 = Config.borderWidth
layer.cornerRadius = Config.cornerRadius
layer.masksToBounds = true
}
}
// MARK: - Helpers
struct AdvancedExampleView: View {
var body: some View {
StoryboardView(name: "AdvancedExample")
.navigationTitle("🚀 Advanced Example")
}
}
@@ -0,0 +1,23 @@
//
// CustomColorsTableViewCell.swift
// Example
//
// Created by Felix Mau on 15.04.22.
// Copyright © 2022 Felix Mau. All rights reserved.
//
import UIKit
final class CustomColorsTableViewCell: UITableViewCell {
// MARK: - Public properties
static let reuseIdentifier = "CustomColorsTableViewCell"
var tapHandler: (() -> Void)?
// MARK: - Private methods
@IBAction private func customColorsButtonTouchUpInside(_: Any) {
tapHandler?()
}
}
@@ -0,0 +1,61 @@
//
// CustomSuperviewTableViewCell.swift
// Example
//
// Created by Felix Mau on 15.04.22.
// Copyright © 2022 Felix Mau. All rights reserved.
//
import UIKit
import GradientLoadingBar
final class CustomSuperviewTableViewCell: UITableViewCell {
// MARK: - Config
private enum Config {
static let height: CGFloat = 3
}
// MARK: - Outlets
@IBOutlet private var toggleButton: UIButton!
// MARK: - Public properties
static let reuseIdentifier = "CustomSuperviewViewCell"
// MARK: - Private properties
private let gradientActivityIndicatorView = GradientActivityIndicatorView()
// MARK: - Public methods
override func awakeFromNib() {
super.awakeFromNib()
setupGradientActivityIndicatorView()
}
// MARK: - Private methods
private func setupGradientActivityIndicatorView() {
gradientActivityIndicatorView.translatesAutoresizingMaskIntoConstraints = false
toggleButton.addSubview(gradientActivityIndicatorView)
NSLayoutConstraint.activate([
gradientActivityIndicatorView.leadingAnchor.constraint(equalTo: toggleButton.leadingAnchor),
gradientActivityIndicatorView.trailingAnchor.constraint(equalTo: toggleButton.trailingAnchor),
gradientActivityIndicatorView.bottomAnchor.constraint(equalTo: toggleButton.bottomAnchor),
gradientActivityIndicatorView.heightAnchor.constraint(equalToConstant: Config.height),
])
}
@IBAction private func toggleButtonTouchUpInside(_: Any) {
if gradientActivityIndicatorView.isHidden {
gradientActivityIndicatorView.fadeIn()
} else {
gradientActivityIndicatorView.fadeOut()
}
}
}
@@ -0,0 +1,40 @@
//
// InterfaceBuilderSetupTableViewCell.swift
// Example
//
// Created by Felix Mau on 15.04.22.
// Copyright © 2022 Felix Mau. All rights reserved.
//
import UIKit
import GradientLoadingBar
final class InterfaceBuilderSetupTableViewCell: UITableViewCell {
// MARK: - Config
private enum Config {
static let animationDuration: TimeInterval = 0.5
}
// MARK: - Outlets
@IBOutlet private var gradientActivityIndicator: GradientActivityIndicatorView!
// MARK: - Public properties
static let reuseIdentifier = "InterfaceBuilderSetupTableViewCell"
// MARK: - Private methods
@IBAction private func toggleIBSetupButtonTouchUpInside(_: Any) {
// We explicitly "only" reduce the alpha here, as calling `fadeIn()` / `fadeOut()` would update the `isHidden`
// flag accordingly. This would then lead to a height-update of the parent stack view.
UIView.animate(withDuration: Config.animationDuration) {
if self.gradientActivityIndicator.alpha > 0 {
self.gradientActivityIndicator.alpha = 0
} else {
self.gradientActivityIndicator.alpha = 1
}
}
}
}
@@ -0,0 +1,46 @@
//
// BorderedButton.swift
// Example
//
// Created by Felix Mau on 15.04.22.
// Copyright © 2022 Felix Mau. All rights reserved.
//
import UIKit
@IBDesignable
final class BorderedButton: UIButton {
// MARK: - Config
private enum Config {
static let borderColor = #colorLiteral(red: 0.2862745098, green: 0.5647058824, blue: 0.8862745098, alpha: 1)
static let borderWidth: CGFloat = 1
static let cornerRadius: CGFloat = 4
}
// MARK: - Initializer
override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
// MARK: - Private methods
private func commonInit() {
backgroundColor = .clear
tintColor = Config.borderColor
layer.borderColor = Config.borderColor.cgColor
layer.borderWidth = Config.borderWidth
layer.cornerRadius = Config.cornerRadius
layer.masksToBounds = true
}
}
@@ -1,8 +1,8 @@
<?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">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="20037" 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"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
<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"/>
@@ -16,7 +16,7 @@
<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">
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="i3m-u5-CBZ" userLabel="Content Stack View">
<rect key="frame" x="16" y="428" width="382" height="40"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="iqR-B3-IAJ" userLabel="ShowButton">
@@ -25,7 +25,7 @@
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="40" id="ygd-aW-5tx"/>
</constraints>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="Show">
<buttonConfiguration key="configuration" style="filled" title="Show">
<fontDescription key="titleFontDescription" style="UICTFontTextStyleBody"/>
</buttonConfiguration>
<connections>
@@ -38,7 +38,7 @@
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="40" id="bWt-eh-ohc"/>
</constraints>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="Hide">
<buttonConfiguration key="configuration" style="filled" title="Hide ">
<fontDescription key="titleFontDescription" style="UICTFontTextStyleBody"/>
</buttonConfiguration>
<connections>
@@ -1,8 +1,8 @@
<?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">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="20037" 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"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
<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"/>
@@ -1,8 +1,8 @@
<?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">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="20037" 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"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
<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"/>
@@ -16,11 +16,11 @@
<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">
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillProportionally" alignment="center" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="vQo-n2-n4V" userLabel="Top Content Stack View">
<rect key="frame" x="16" y="400" width="382" height="40"/>
<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="40"/>
<rect key="frame" x="0.0" y="0.0" width="244" height="40"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="40" id="wri-XG-tfO"/>
</constraints>
@@ -33,12 +33,12 @@
</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="40"/>
<rect key="frame" x="260" y="0.0" width="122" height="40"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="40" id="zfx-4A-wZB"/>
</constraints>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="Hide Basic Bar">
<buttonConfiguration key="configuration" style="filled" title="Hide">
<fontDescription key="titleFontDescription" style="UICTFontTextStyleBody"/>
</buttonConfiguration>
<connections>
@@ -47,11 +47,24 @@
</button>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" alignment="center" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="J6X-XZ-YZb" userLabel="Bottom Stack View">
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillProportionally" alignment="center" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="J6X-XZ-YZb" userLabel="Bottom Content Stack View">
<rect key="frame" x="16" y="456" width="382" height="40"/>
<subviews>
<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="0.0" y="0.0" width="104" height="40"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="40" id="64O-UM-b99"/>
</constraints>
<state key="normal" title="Button"/>
<buttonConfiguration key="configuration" style="filled" title="Hide">
<fontDescription key="titleFontDescription" style="UICTFontTextStyleBody"/>
</buttonConfiguration>
<connections>
<action selector="hideNotchBarButtonTouchUpInside:" destination="Y6W-OH-hqX" eventType="touchUpInside" id="INf-lf-Egt"/>
</connections>
</button>
<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="40"/>
<rect key="frame" x="120" y="0.0" width="262" height="40"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="40" id="nUb-HA-Cts"/>
</constraints>
@@ -63,19 +76,6 @@
<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="40"/>
<constraints>
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="40" id="64O-UM-b99"/>
</constraints>
<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>
@@ -14,17 +14,15 @@ struct SwiftUIExampleView: View {
var body: some View {
List {
// We need to apply a `Spacer()` as header to have a little space between the sections
// and the navigation bar.
Section(header: Spacer()) {
Section(header: Text("Default example")) {
DefaultExampleView()
}
Section {
Section(header: Text("Custom colors")) {
CustomColorsExampleView()
}
Section {
Section(header: Text("Custom animation duration")) {
CustomProgressDurationExampleView()
}
}
@@ -34,29 +32,14 @@ struct SwiftUIExampleView: View {
// 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)
}
.frame(maxWidth: .infinity, alignment: .leading)
}
}
private struct DefaultExampleView: View {
@State
private var isVisible = false
private var isVisible = true
var body: some View {
VStack(spacing: 16) {
TitleSubtitleView(title: "Default example",
subtitle: "Example using the default configuration.")
Text("Example using the default configuration.")
.frame(maxWidth: .infinity, alignment: .leading)
GradientLoadingBarView()
.frame(maxWidth: .infinity, maxHeight: 3)
@@ -94,12 +77,12 @@ private struct CustomColorsExampleView: View {
}
@State
private var isVisible = false
private var isVisible = true
var body: some View {
VStack(spacing: 16) {
TitleSubtitleView(title: "Custom colors",
subtitle: "Example showing how to provide custom gradient colors.")
Text("Example showing how to provide custom gradient colors.")
.frame(maxWidth: .infinity, alignment: .leading)
GradientLoadingBarView(gradientColors: Config.gradientColors)
.frame(maxWidth: .infinity, maxHeight: 3)
@@ -134,12 +117,12 @@ private struct CustomProgressDurationExampleView: View {
}
@State
private var isVisible = false
private var isVisible = true
var body: some View {
VStack(spacing: 16) {
TitleSubtitleView(title: "Custom animation duration",
subtitle: "Example showing how to provide a custom progress animation duration.")
Text("Example showing how to provide a custom progress animation duration.")
.frame(maxWidth: .infinity, alignment: .leading)
GradientLoadingBarView(progressDuration: Config.progressDuration)
.frame(maxWidth: .infinity, maxHeight: 3)