Circular Frame
|
@ -27,8 +27,8 @@ import SwiftUI
|
|||
{{accessModifier}} typealias {{param.colorAliasName|default:"AssetColorTypeAlias"}} = {{colorType}}.SystemColor
|
||||
{% endif %}
|
||||
{% if resourceCount.image > 0 %}
|
||||
@available(*, deprecated, renamed: "{{imageType}}.Image", message: "This typealias will be removed in SwiftGen 7.0")
|
||||
{{accessModifier}} typealias {{param.imageAliasName|default:"AssetImageTypeAlias"}} = {{imageType}}.Image
|
||||
@available(*, deprecated, renamed: "{{imageType}}.UniversalImage", message: "This typealias will be removed in SwiftGen 7.0")
|
||||
{{accessModifier}} typealias {{param.imageAliasName|default:"AssetImageTypeAlias"}} = {{imageType}}.UniversalImage
|
||||
{% endif %}
|
||||
|
||||
// swiftlint:disable superfluous_disable_command file_length implicit_return
|
||||
|
@ -224,29 +224,34 @@ import SwiftUI
|
|||
{{accessModifier}} fileprivate(set) var name: String
|
||||
|
||||
#if os(macOS)
|
||||
{{accessModifier}} typealias Image = NSImage
|
||||
{{accessModifier}} typealias UniversalImage = NSImage
|
||||
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||
{{accessModifier}} typealias Image = UIImage
|
||||
{{accessModifier}} typealias UniversalImage = UIImage
|
||||
#endif
|
||||
|
||||
{{accessModifier}} var image: Image {
|
||||
{{accessModifier}} var systemImage: UniversalImage {
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
#if os(iOS) || os(tvOS)
|
||||
let image = Image(named: name, in: bundle, compatibleWith: nil)
|
||||
let image = UniversalImage(named: name, in: bundle, compatibleWith: nil)
|
||||
#elseif os(macOS)
|
||||
let name = NSImage.Name(self.name)
|
||||
let image = (bundle == .main) ? NSImage(named: name) : bundle.image(forResource: name)
|
||||
#elseif os(watchOS)
|
||||
let image = Image(named: name)
|
||||
let image = UniversalImage(named: name)
|
||||
#endif
|
||||
guard let result = image else {
|
||||
fatalError("Unable to load image asset named \(name).")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
{{accessModifier}} var image: Image {
|
||||
let bundle = {{param.bundle|default:"BundleToken.bundle"}}
|
||||
return Image(name, bundle: bundle)
|
||||
}
|
||||
}
|
||||
|
||||
{{accessModifier}} extension {{imageType}}.Image {
|
||||
{{accessModifier}} extension {{imageType}}.UniversalImage {
|
||||
@available(macOS, deprecated,
|
||||
message: "This initializer is unsafe on macOS, please use the {{imageType}}.image property")
|
||||
convenience init?(asset: {{imageType}}) {
|
||||
|
|
|
@ -83,6 +83,9 @@
|
|||
6654C73E2715A41300901167 /* OnboardingStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6654C73D2715A41300901167 /* OnboardingStore.swift */; };
|
||||
6654C7412715A47300901167 /* Onboarding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6654C7402715A47300901167 /* Onboarding.swift */; };
|
||||
6654C7442715A4AC00901167 /* OnboardingStoreTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6654C7432715A4AC00901167 /* OnboardingStoreTests.swift */; };
|
||||
665C963F272C26E600BC04FB /* CircularFrameBackground.swift in Sources */ = {isa = PBXBuildFile; fileRef = 665C963E272C26E600BC04FB /* CircularFrameBackground.swift */; };
|
||||
669FDAE9272C23B3007B9422 /* CircularFrame.swift in Sources */ = {isa = PBXBuildFile; fileRef = 669FDAE8272C23B3007B9422 /* CircularFrame.swift */; };
|
||||
669FDAEB272C23C2007B9422 /* CircularFrameBadge.swift in Sources */ = {isa = PBXBuildFile; fileRef = 669FDAEA272C23C2007B9422 /* CircularFrameBadge.swift */; };
|
||||
66A0807B271993C500118B79 /* OnboardingProgressIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66A0807A271993C500118B79 /* OnboardingProgressIndicator.swift */; };
|
||||
66D50668271D9B6100E51F0D /* NavigationButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66D50667271D9B6100E51F0D /* NavigationButtonStyle.swift */; };
|
||||
66DC733F271D88CC0053CBB6 /* StandardButtonStyle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66DC733E271D88CC0053CBB6 /* StandardButtonStyle.swift */; };
|
||||
|
@ -187,6 +190,9 @@
|
|||
6654C73D2715A41300901167 /* OnboardingStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingStore.swift; sourceTree = "<group>"; };
|
||||
6654C7402715A47300901167 /* Onboarding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Onboarding.swift; sourceTree = "<group>"; };
|
||||
6654C7432715A4AC00901167 /* OnboardingStoreTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingStoreTests.swift; sourceTree = "<group>"; };
|
||||
665C963E272C26E600BC04FB /* CircularFrameBackground.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircularFrameBackground.swift; sourceTree = "<group>"; };
|
||||
669FDAE8272C23B3007B9422 /* CircularFrame.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircularFrame.swift; sourceTree = "<group>"; };
|
||||
669FDAEA272C23C2007B9422 /* CircularFrameBadge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CircularFrameBadge.swift; sourceTree = "<group>"; };
|
||||
66A0807A271993C500118B79 /* OnboardingProgressIndicator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingProgressIndicator.swift; sourceTree = "<group>"; };
|
||||
66D50667271D9B6100E51F0D /* NavigationButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationButtonStyle.swift; sourceTree = "<group>"; };
|
||||
66DC733E271D88CC0053CBB6 /* StandardButtonStyle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StandardButtonStyle.swift; sourceTree = "<group>"; };
|
||||
|
@ -468,12 +474,13 @@
|
|||
0DA13C9126C15E1900E3B610 /* UI Components */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
669FDAE7272C239D007B9422 /* CircularFrame */,
|
||||
0DB8AA80271DC7520035BC9D /* DesignGuide.swift */,
|
||||
0DF2DC5227235E1F00FA31E2 /* Extensions */,
|
||||
0D535FE0271F945C009A9E3E /* Chips */,
|
||||
663FAB9A271D873300E495F8 /* Buttons */,
|
||||
66A0807A271993C500118B79 /* OnboardingProgressIndicator.swift */,
|
||||
0DB8AA80271DC7520035BC9D /* DesignGuide.swift */,
|
||||
0D7DF08B271DCC0E00530046 /* ScreenBackground.swift */,
|
||||
669FDAE5272C2371007B9422 /* ProgressIndicators */,
|
||||
669FDAE6272C2380007B9422 /* Backgrounds */,
|
||||
);
|
||||
path = "UI Components";
|
||||
sourceTree = "<group>";
|
||||
|
@ -604,6 +611,32 @@
|
|||
path = OnboardingTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
669FDAE5272C2371007B9422 /* ProgressIndicators */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
66A0807A271993C500118B79 /* OnboardingProgressIndicator.swift */,
|
||||
);
|
||||
path = ProgressIndicators;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
669FDAE6272C2380007B9422 /* Backgrounds */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0D7DF08B271DCC0E00530046 /* ScreenBackground.swift */,
|
||||
);
|
||||
path = Backgrounds;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
669FDAE7272C239D007B9422 /* CircularFrame */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
669FDAE8272C23B3007B9422 /* CircularFrame.swift */,
|
||||
669FDAEA272C23C2007B9422 /* CircularFrameBadge.swift */,
|
||||
665C963E272C26E600BC04FB /* CircularFrameBackground.swift */,
|
||||
);
|
||||
path = CircularFrame;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
|
@ -803,6 +836,7 @@
|
|||
files = (
|
||||
660558F8270C862F009D6954 /* XCAssets+Generated.swift in Sources */,
|
||||
0D32281F26C5867D00262533 /* ScanQrScreenViewModel.swift in Sources */,
|
||||
669FDAE9272C23B3007B9422 /* CircularFrame.swift in Sources */,
|
||||
0D32282E26C5870B00262533 /* SendScreenViewModel.swift in Sources */,
|
||||
0D32282D26C5870B00262533 /* SendScreen.swift in Sources */,
|
||||
663FABA2271D876C00E495F8 /* SecondaryButton.swift in Sources */,
|
||||
|
@ -814,12 +848,14 @@
|
|||
0D535FE2271F9476009A9E3E /* EnumeratedChip.swift in Sources */,
|
||||
6654C73E2715A41300901167 /* OnboardingStore.swift in Sources */,
|
||||
0D32281E26C5867D00262533 /* ScanQrScreen.swift in Sources */,
|
||||
669FDAEB272C23C2007B9422 /* CircularFrameBadge.swift in Sources */,
|
||||
0D864A0E26E1583000A61879 /* LoadingScreen.swift in Sources */,
|
||||
0DA13C9C26C1942100E3B610 /* BackupWalletScreen.swift in Sources */,
|
||||
0DA13C9826C186FF00E3B610 /* RestoreWalletScreenViewModel.swift in Sources */,
|
||||
0D32283326C5877A00262533 /* BalanceScreenViewModel.swift in Sources */,
|
||||
0D5D16F526E24CCF00AD33D1 /* AppError.swift in Sources */,
|
||||
0D18581B272728D60046B928 /* PhraseChip.swift in Sources */,
|
||||
665C963F272C26E600BC04FB /* CircularFrameBackground.swift in Sources */,
|
||||
0DB8AA81271DC7520035BC9D /* DesignGuide.swift in Sources */,
|
||||
0D32282326C586A800262533 /* HistoryScreen.swift in Sources */,
|
||||
0D864A0A26E154FD00A61879 /* InitFailedScreenViewModel.swift in Sources */,
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "callout0.jpg",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "callout0-1.jpg",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "callout0-2.jpg",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 14 KiB |
After Width: | Height: | Size: 14 KiB |
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "callout1.jpg",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "callout1-1.jpg",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "callout1-2.jpg",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 138 KiB |
After Width: | Height: | Size: 138 KiB |
After Width: | Height: | Size: 138 KiB |
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "callout2.jpg",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "callout2-1.jpg",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "callout2-2.jpg",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 150 KiB |
After Width: | Height: | Size: 150 KiB |
After Width: | Height: | Size: 150 KiB |
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "callout3.jpg",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "callout3-1.jpg",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "callout3-2.jpg",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 195 KiB |
After Width: | Height: | Size: 195 KiB |
After Width: | Height: | Size: 195 KiB |
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"filename" : "finalcallout.jpg",
|
||||
"idiom" : "universal",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"filename" : "finalcallout-1.jpg",
|
||||
"idiom" : "universal",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"filename" : "finalcallout-2.jpg",
|
||||
"idiom" : "universal",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
After Width: | Height: | Size: 269 KiB |
After Width: | Height: | Size: 269 KiB |
After Width: | Height: | Size: 269 KiB |
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
|
@ -13,8 +13,8 @@ import SwiftUI
|
|||
// Deprecated typealiases
|
||||
@available(*, deprecated, renamed: "ColorAsset.SystemColor", message: "This typealias will be removed in SwiftGen 7.0")
|
||||
internal typealias AssetColorTypeAlias = ColorAsset.SystemColor
|
||||
@available(*, deprecated, renamed: "ImageAsset.Image", message: "This typealias will be removed in SwiftGen 7.0")
|
||||
internal typealias AssetImageTypeAlias = ImageAsset.Image
|
||||
@available(*, deprecated, renamed: "ImageAsset.UniversalImage", message: "This typealias will be removed in SwiftGen 7.0")
|
||||
internal typealias AssetImageTypeAlias = ImageAsset.UniversalImage
|
||||
|
||||
// swiftlint:disable superfluous_disable_command file_length implicit_return
|
||||
|
||||
|
@ -23,10 +23,17 @@ internal typealias AssetImageTypeAlias = ImageAsset.Image
|
|||
// swiftlint:disable identifier_name line_length nesting type_body_length type_name
|
||||
internal enum Asset {
|
||||
internal enum Assets {
|
||||
internal enum Backgrounds {
|
||||
internal static let callout0 = ImageAsset(name: "callout0")
|
||||
internal static let callout1 = ImageAsset(name: "callout1")
|
||||
internal static let callout2 = ImageAsset(name: "callout2")
|
||||
internal static let callout3 = ImageAsset(name: "callout3")
|
||||
internal static let callout4 = ImageAsset(name: "callout4")
|
||||
}
|
||||
internal enum Icons {
|
||||
internal static let badge = ImageAsset(name: "badge")
|
||||
internal static let list = ImageAsset(name: "list")
|
||||
internal static let person = ImageAsset(name: "person")
|
||||
internal static let profile = ImageAsset(name: "profile")
|
||||
internal static let shield = ImageAsset(name: "shield")
|
||||
}
|
||||
}
|
||||
internal enum Colors {
|
||||
|
@ -124,29 +131,34 @@ internal struct ImageAsset {
|
|||
internal fileprivate(set) var name: String
|
||||
|
||||
#if os(macOS)
|
||||
internal typealias Image = NSImage
|
||||
internal typealias UniversalImage = NSImage
|
||||
#elseif os(iOS) || os(tvOS) || os(watchOS)
|
||||
internal typealias Image = UIImage
|
||||
internal typealias UniversalImage = UIImage
|
||||
#endif
|
||||
|
||||
internal var image: Image {
|
||||
internal var systemImage: UniversalImage {
|
||||
let bundle = BundleToken.bundle
|
||||
#if os(iOS) || os(tvOS)
|
||||
let image = Image(named: name, in: bundle, compatibleWith: nil)
|
||||
let image = UniversalImage(named: name, in: bundle, compatibleWith: nil)
|
||||
#elseif os(macOS)
|
||||
let name = NSImage.Name(self.name)
|
||||
let image = (bundle == .main) ? NSImage(named: name) : bundle.image(forResource: name)
|
||||
#elseif os(watchOS)
|
||||
let image = Image(named: name)
|
||||
let image = UniversalImage(named: name)
|
||||
#endif
|
||||
guard let result = image else {
|
||||
fatalError("Unable to load image asset named \(name).")
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
internal var image: Image {
|
||||
let bundle = BundleToken.bundle
|
||||
return Image(name, bundle: bundle)
|
||||
}
|
||||
}
|
||||
|
||||
internal extension ImageAsset.Image {
|
||||
internal extension ImageAsset.UniversalImage {
|
||||
@available(macOS, deprecated,
|
||||
message: "This initializer is unsafe on macOS, please use the ImageAsset.image property")
|
||||
convenience init?(asset: ImageAsset) {
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
//
|
||||
// CircularImageFrame.swift
|
||||
// secant-testnet
|
||||
//
|
||||
// Created by Adam Stener on 9/29/21.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct CircularFrame: View {
|
||||
var body: some View {
|
||||
GeometryReader { proxy in
|
||||
let lineWidth = proxy.size.width * 0.07
|
||||
|
||||
Circle()
|
||||
.stroke(lineWidth: lineWidth)
|
||||
.foregroundColor(Asset.Colors.Onboarding.circularFrame.color)
|
||||
// Add two points to the frame to properly mask edges
|
||||
.frame(
|
||||
width: proxy.size.width - lineWidth + 2,
|
||||
height: proxy.size.height - lineWidth + 2,
|
||||
alignment: .center
|
||||
)
|
||||
// Update the offset to account for the 2 extra points
|
||||
.offset(x: lineWidth / 2 - 1, y: lineWidth / 2 - 1)
|
||||
.shadow(radius: 10)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct OnboardingCircularFrame: View {
|
||||
@Binding var index: Int
|
||||
let size: CGFloat
|
||||
|
||||
var body: some View {
|
||||
ZStack {
|
||||
CircularFrame()
|
||||
.frame(width: size, height: size)
|
||||
|
||||
switch index {
|
||||
case 0:
|
||||
Asset.Assets.Icons.shield.image
|
||||
.onboardingBadge(parentSize: size)
|
||||
case 1:
|
||||
Asset.Assets.Icons.profile.image
|
||||
.onboardingBadge(parentSize: size)
|
||||
case 2:
|
||||
Asset.Assets.Icons.list.image
|
||||
.onboardingBadge(parentSize: size)
|
||||
default:
|
||||
EmptyView()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension Image {
|
||||
func onboardingBadge(parentSize: CGFloat) -> some View {
|
||||
self
|
||||
.resizable()
|
||||
.frame(width: parentSize / 2, height: parentSize / 2)
|
||||
.offset(y: parentSize * 0.47)
|
||||
.zIndex(100)
|
||||
}
|
||||
}
|
||||
|
||||
struct CircularFramePreviewHelper: View {
|
||||
@State var index = 0
|
||||
private let size: CGFloat = 300
|
||||
|
||||
var body: some View {
|
||||
VStack {
|
||||
HStack(spacing: 25) {
|
||||
Button("+") {
|
||||
guard index < 2 else { return }
|
||||
index += 1
|
||||
}
|
||||
|
||||
Button("-") {
|
||||
guard index != 0 else { return }
|
||||
index -= 1
|
||||
}
|
||||
|
||||
Text("\(index)")
|
||||
}
|
||||
|
||||
GeometryReader { proxy in
|
||||
VStack {
|
||||
Spacer()
|
||||
|
||||
HStack {
|
||||
Spacer()
|
||||
|
||||
OnboardingCircularFrame(index: $index, size: proxy.size.width / 2)
|
||||
.animation(.easeInOut(duration: 2), value: index)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
|
||||
CircularFrame()
|
||||
.backgroundImage(Asset.Assets.Backgrounds.callout1.image)
|
||||
.frame(width: size, height: size)
|
||||
.badgeIcon(.shield)
|
||||
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct CircularFrame_Previews: PreviewProvider {
|
||||
static var previews: some View {
|
||||
CircularFramePreviewHelper()
|
||||
.preferredColorScheme(.light)
|
||||
.previewLayout(.device)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
//
|
||||
// CircularFrameBackground.swift
|
||||
// secant-testnet
|
||||
//
|
||||
// Created by Adam Stener on 10/29/21.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct CircularFrameBackgroundImage: ViewModifier {
|
||||
let image: Image
|
||||
func body(content: Content) -> some View {
|
||||
ZStack {
|
||||
image
|
||||
.resizable()
|
||||
.aspectRatio(1.3, contentMode: .fill)
|
||||
.mask(Circle())
|
||||
|
||||
content
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension CircularFrame {
|
||||
func backgroundImage(_ image: Image) -> some View {
|
||||
modifier(CircularFrameBackgroundImage(image: image))
|
||||
}
|
||||
}
|
||||
|
||||
struct CircularFrameBackground_Previews: PreviewProvider {
|
||||
static let size: CGFloat = 300
|
||||
static var previews: some View {
|
||||
Group {
|
||||
CircularFrame()
|
||||
.backgroundImage(Asset.Assets.Backgrounds.callout0.image)
|
||||
.frame(width: 300, height: 300)
|
||||
|
||||
CircularFrame()
|
||||
.backgroundImage(Asset.Assets.Backgrounds.callout1.image)
|
||||
.frame(width: 300, height: 300)
|
||||
|
||||
CircularFrame()
|
||||
.backgroundImage(Asset.Assets.Backgrounds.callout2.image)
|
||||
.frame(width: 300, height: 300)
|
||||
|
||||
CircularFrame()
|
||||
.backgroundImage(Asset.Assets.Backgrounds.callout3.image)
|
||||
.frame(width: 300, height: 300)
|
||||
}
|
||||
.preferredColorScheme(.light)
|
||||
.previewLayout(.fixed(width: size + 50, height: size + 50))
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
//
|
||||
// CircularImageFrame.swift
|
||||
// secant-testnet
|
||||
//
|
||||
// Created by Adam Stener on 9/29/21.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct BadgeIcon: ViewModifier {
|
||||
enum Badge: Equatable {
|
||||
case shield
|
||||
case list
|
||||
case person
|
||||
|
||||
var image: Image {
|
||||
switch self {
|
||||
case .shield: return Asset.Assets.Icons.shield.image
|
||||
case .list: return Asset.Assets.Icons.list.image
|
||||
case .person: return Asset.Assets.Icons.profile.image
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let badge: Badge
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
content
|
||||
.overlay(
|
||||
GeometryReader { proxy in
|
||||
VStack {
|
||||
Spacer()
|
||||
|
||||
HStack {
|
||||
Spacer()
|
||||
|
||||
badge.image
|
||||
.resizable()
|
||||
.frame(
|
||||
width: proxy.size.width * 0.5,
|
||||
height: proxy.size.height * 0.5,
|
||||
alignment: .center
|
||||
)
|
||||
.offset(
|
||||
x: 0.0,
|
||||
y: proxy.size.height * 0.21
|
||||
)
|
||||
Spacer()
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
extension View {
|
||||
func badgeIcon(_ badge: BadgeIcon.Badge) -> some View {
|
||||
modifier(BadgeIcon(badge: badge))
|
||||
}
|
||||
}
|
||||
|
||||
struct Badge_Previews: PreviewProvider {
|
||||
static let size: CGFloat = 300
|
||||
|
||||
static var previews: some View {
|
||||
Group {
|
||||
CircularFrame()
|
||||
.frame(width: size, height: size)
|
||||
.badgeIcon(.shield)
|
||||
|
||||
CircularFrame()
|
||||
.frame(width: size, height: size)
|
||||
.badgeIcon(.list)
|
||||
|
||||
CircularFrame()
|
||||
.frame(width: size, height: size)
|
||||
.badgeIcon(.person)
|
||||
}
|
||||
.preferredColorScheme(.light)
|
||||
.previewLayout(.fixed(width: size + 50, height: size + 50))
|
||||
}
|
||||
}
|