Skip to content

Commit

Permalink
Beautiful gradient animation, fixed loading spinner, made stars look …
Browse files Browse the repository at this point in the history
…like web
  • Loading branch information
Cavallando committed Dec 18, 2023
1 parent 28e3a86 commit f33313a
Show file tree
Hide file tree
Showing 17 changed files with 675 additions and 409 deletions.
4 changes: 4 additions & 0 deletions Example/CommandBarIOS.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
FF409B4A2B2F76C900D2A3CD /* GradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF409B492B2F76C900D2A3CD /* GradientView.swift */; };
FF409B4C2B2F7B0800D2A3CD /* Toast.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF409B4B2B2F7B0800D2A3CD /* Toast.swift */; };
FF409B502B2FB49C00D2A3CD /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FF409B4F2B2FB49C00D2A3CD /* LaunchScreen.storyboard */; };
FF409B522B30995800D2A3CD /* Color.swift in Sources */ = {isa = PBXBuildFile; fileRef = FF409B512B30995800D2A3CD /* Color.swift */; };
FFB6A38B2B1BC93D0036D16F /* App.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFB6A38A2B1BC93D0036D16F /* App.swift */; };
FFB6A38D2B1E27850036D16F /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFB6A38C2B1E27850036D16F /* AppDelegate.swift */; };
FFB6A3902B1F98860036D16F /* ConfettiSwiftUI in Frameworks */ = {isa = PBXBuildFile; productRef = FFB6A38F2B1F98860036D16F /* ConfettiSwiftUI */; };
Expand Down Expand Up @@ -57,6 +58,7 @@
FF409B492B2F76C900D2A3CD /* GradientView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradientView.swift; sourceTree = "<group>"; };
FF409B4B2B2F7B0800D2A3CD /* Toast.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Toast.swift; sourceTree = "<group>"; };
FF409B4F2B2FB49C00D2A3CD /* LaunchScreen.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = "<group>"; };
FF409B512B30995800D2A3CD /* Color.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Color.swift; sourceTree = "<group>"; };
FFB6A38A2B1BC93D0036D16F /* App.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = App.swift; sourceTree = "<group>"; };
FFB6A38C2B1E27850036D16F /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
Expand Down Expand Up @@ -181,6 +183,7 @@
FF409B472B2F717200D2A3CD /* Button.swift */,
FF409B492B2F76C900D2A3CD /* GradientView.swift */,
FF409B4B2B2F7B0800D2A3CD /* Toast.swift */,
FF409B512B30995800D2A3CD /* Color.swift */,
);
path = Views;
sourceTree = "<group>";
Expand Down Expand Up @@ -371,6 +374,7 @@
FF409B4C2B2F7B0800D2A3CD /* Toast.swift in Sources */,
FFB6A38B2B1BC93D0036D16F /* App.swift in Sources */,
FF409B412B2F6A7200D2A3CD /* SceneDelegate.swift in Sources */,
FF409B522B30995800D2A3CD /* Color.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
1 change: 1 addition & 0 deletions Example/CommandBarIOS/App.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ struct CommandBarIOSExampleApp: App {
WindowGroup {
HomeView()
}

}

}
Expand Down
100 changes: 100 additions & 0 deletions Example/CommandBarIOS/Views/Color.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import Foundation
import SwiftUI

extension Color {
func uiColor() -> UIColor {

if #available(iOS 14.0, *) {
return UIColor(self)
}

let components = self.components()
return UIColor(red: components.r, green: components.g, blue: components.b, alpha: components.a)
}

private func components() -> (r: CGFloat, g: CGFloat, b: CGFloat, a: CGFloat) {

let scanner = Scanner(string: self.description.trimmingCharacters(in: CharacterSet.alphanumerics.inverted))
var hexNumber: UInt64 = 0
var r: CGFloat = 0.0, g: CGFloat = 0.0, b: CGFloat = 0.0, a: CGFloat = 0.0

let result = scanner.scanHexInt64(&hexNumber)
if result {
r = CGFloat((hexNumber & 0xff000000) >> 24) / 255
g = CGFloat((hexNumber & 0x00ff0000) >> 16) / 255
b = CGFloat((hexNumber & 0x0000ff00) >> 8) / 255
a = CGFloat(hexNumber & 0x000000ff) / 255
}
return (r, g, b, a)
}

static func random() -> Color {
let red = Double.random(in: 0..<1)
let green = Double.random(in: 0..<1)
let blue = Double.random(in: 0..<1)
return Color(red: red, green: green, blue: blue)
}

init(uiColor: UIColor) {
self.init(red: Double(uiColor.components.red),
green: Double(uiColor.components.green),
blue: Double(uiColor.components.blue),
opacity: Double(uiColor.components.alpha))
}

func lighter(by percentage: CGFloat = 30.0) -> Color {
if let uiColor = self.uiColor().lighter(by: percentage) {
return Color(uiColor: uiColor)
}
return self

}

func darker(by percentage: CGFloat = 30.0) -> Color {
if let uiColor = self.uiColor().darker(by: percentage) {
return Color(uiColor: uiColor)
}
return self

}

func adjust(by percentage: CGFloat = 30.0) -> Color {
let components = self.components()
return Color(red: min(Double(components.r + percentage/100), 1.0),
green: min(Double(components.g + percentage/100), 1.0),
blue: min(Double(components.b + percentage/100), 1.0),
opacity: Double(components.a))
}
}


extension UIColor {
var components: (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
var red: CGFloat = 0
var green: CGFloat = 0
var blue: CGFloat = 0
var alpha: CGFloat = 0
getRed(&red, green: &green, blue: &blue, alpha: &alpha)

return (red, green, blue, alpha)
}
func lighter(by percentage: CGFloat = 30.0) -> UIColor? {
return self.adjust(by: abs(percentage) )
}

func darker(by percentage: CGFloat = 30.0) -> UIColor? {
return self.adjust(by: -1 * abs(percentage) )
}

func adjust(by percentage: CGFloat = 30.0) -> UIColor? {
var red: CGFloat = 0, green: CGFloat = 0, blue: CGFloat = 0, alpha: CGFloat = 0
if self.getRed(&red, green: &green, blue: &blue, alpha: &alpha) {
return UIColor(red: min(red + percentage/100, 1.0),
green: min(green + percentage/100, 1.0),
blue: min(blue + percentage/100, 1.0),
alpha: alpha)
} else {
return nil
}
}
}
107 changes: 62 additions & 45 deletions Example/CommandBarIOS/Views/GradientView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,61 +2,78 @@ import SwiftUI
import UIKit

struct GradientView: View {

@State private var stage: Double = 0
private let maxStages: Double = 10.0

private let startColor: Color = .purple
private let endColor: Color = .blue.darker(by: 2)

private let timer = Timer.publish(every: 0.1, on: .main, in: .commonModes).autoconnect() // adjust as needed

var body: some View {
ZStack {
RadialGradient(
gradient: Gradient(colors: [Color(hue: 198/360, saturation: 1, brightness: 0.8), Color.clear]),
center: .init(x: 0.82, y: 0.65),
startRadius: 0,
endRadius: 0.55 * UIScreen.main.bounds.width
)
RadialGradient(
gradient: Gradient(colors: [Color(hue: 220/360, saturation: 0.37, brightness: 0.97), Color.clear]),
center: .init(x: 0.47, y: 0.33),
startRadius: 0,
endRadius: 0.59 * UIScreen.main.bounds.width
)

}.background(
LinearGradient(gradient: Gradient(colors: [.purple, .blue]), startPoint: .top, endPoint: .bottom).edgesIgnoringSafeArea(/*@START_MENU_TOKEN@*/.all/*@END_MENU_TOKEN@*/)
)
ForEach(0..<(Int(maxStages)), id: \.self) { i in
gradient(for: i)
.opacity(opacity(for: i))
.animation(.linear(duration: 0.4), value: self.stage)

}
}
.edgesIgnoringSafeArea(.all)
.onAppear{
Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { _ in
withAnimation {
self.stage = (self.stage + 1)
}
}
}
}

}

struct GradientBackgroundRepresentable: UIViewControllerRepresentable {
private func gradient(for index: Int) -> LinearGradient {
print(index)
let points = gradientPoints(for: index)
return LinearGradient(
gradient: Gradient(colors: [startColor, endColor]),
startPoint: points.0,
endPoint: points.1
)
}

func makeUIViewController(context: Context) -> UIViewController {
let hostingController = UIHostingController(rootView: GradientView())
return hostingController
private func gradientPoints(for index: Int) -> (UnitPoint, UnitPoint) {
switch index {
case 0:
return (.topLeading, .bottomTrailing)
case 1:
return (.top, .bottom)
case 2:
return (.topTrailing, .bottomLeading)
case 3:
return (.trailing, .leading)
case 4:
return (.bottomTrailing, .topLeading)
case 5:
return (.bottom, .top)
case 6:
return (.bottomLeading, .topTrailing)
case 7:
return (.leading, .trailing)
case 8:
return (.topLeading, .bottomTrailing)
default:
return (.topLeading, .bottomTrailing)
}
}

func updateUIViewController(_ uiViewController: UIViewController, context: Context) {

private func opacity(for index: Int) -> Double {
let adjustedStage = (self.stage - Double(index)) / self.maxStages
return max(0, 0.5 * cos(2 * Double.pi * adjustedStage) + 0.5)
}
}
class GradientBackgroundViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()

let gradientBackgroundView = UIHostingController(rootView: GradientView())
// Add as a child of the current view controller.
addChildViewController(gradientBackgroundView)

// Add the SwiftUI view to the view controller view hierarchy.
view.addSubview(gradientBackgroundView.view)

// Setup constraints to update the SwiftUI view boundaries.
// gradientBackgroundView.view.translatesAutoresizingMaskIntoConstraints = false
// NSLayoutConstraint.activate([
// gradientBackgroundView.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
// gradientBackgroundView.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
// gradientBackgroundView.view.topAnchor.constraint(equalTo: view.topAnchor),
// gradientBackgroundView.view.bottomAnchor.constraint(equalTo: view.bottomAnchor)
// ])
//
// // Notify the hosting controller that it has been moved to the current view controller.
// gradientBackgroundView.didMove(toParent: self)
struct GradientView_Previews: PreviewProvider {
static var previews: some View {
GradientView()
}
}
43 changes: 18 additions & 25 deletions Example/CommandBarIOS/Views/HomeView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,24 @@ struct HomeView: View {
VStack(alignment: .center) {
ZStack {
GradientView()
Main

VStack {
Spacer()
VStack {
LogoView()
.shadow(color: Color.black.opacity(0.3), radius: 10, x: 0, y: 5)
Text("Welcome to CommandBar!")
.multilineTextAlignment(.center)
.font(.title)
}
Spacer()
VStack() {
CustomButton(title: "Trigger Test Event") {
// 3. Track Events
CommandBarSDK.shared.trackEvent(event: "test_event")
}
}
}.padding(.horizontal)

if ORG_ID == "" {
VStack(alignment: .leading) {
Toast(message: "Org ID not set.")
Expand All @@ -33,27 +49,4 @@ struct HomeView: View {
}
}
}

var Main: some View {
VStack {
Spacer()
VStack {
LogoView()
.shadow(color: Color.black.opacity(0.3), radius: 10, x: 0, y: 5)
Text("Welcome to CommandBar!")
.multilineTextAlignment(.center)
.font(.title)
}
Spacer()
VStack() {
CustomButton(title: "Trigger Test Event") {
// 3. Track Events
CommandBarSDK.shared.trackEvent(event: "test_event")
}
CustomButton(title: "Open HelpHub") {
CommandBarSDK.shared.openHelpHub()
}
}
}.padding(.horizontal)
}
}
2 changes: 1 addition & 1 deletion Example/Podfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use_frameworks!

platform :ios, '15.0'
platform :ios, '13.0'

target 'CommandBarIOS_Example' do
pod 'CommandBarIOS', :path => '../'
Expand Down
2 changes: 1 addition & 1 deletion Example/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,6 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS:
CommandBarIOS: 6c8489472ed8f1f033d36b095b44f2227f9115ec

PODFILE CHECKSUM: 3a5c97c63efc3c50665cd2b1d284e459972dc9db
PODFILE CHECKSUM: 6d9bb10e6d829f27934a51717623c1fd87cac734

COCOAPODS: 1.14.2
2 changes: 1 addition & 1 deletion Example/Pods/Manifest.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit f33313a

Please sign in to comment.