Badges updated to use symbols

The badge is now in full control of SwiftUI code, the background rounded rect + colors and on top of that is the symbol itself driven by enum

badges updated to the latest design
This commit is contained in:
Lukas Korba 2022-03-08 15:07:05 +01:00
parent 41551883b1
commit db77a0227e
44 changed files with 330 additions and 85 deletions

View File

@ -0,0 +1,56 @@
{
"images" : [
{
"filename" : "iconbank_lighttheme.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "iconbank_darktheme.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "iconbank_lighttheme@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "iconbank_darktheme@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "iconbank_lighttheme@3x.png",
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "iconbank_darktheme@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -1,16 +1,50 @@
{
"images" : [
{
"filename" : "icon_list.png",
"filename" : "iconlist_lighttheme.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "icon_list@2x.png",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "iconlist_darktheme.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "iconlist_lighttheme@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "iconlist_darktheme@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "iconlist_lighttheme@3x.png",
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "iconlist_darktheme@3x.png",
"idiom" : "universal",
"scale" : "3x"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -1,16 +1,50 @@
{
"images" : [
{
"filename" : "icon_person.png",
"filename" : "iconperson_lighttheme.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "icon_person@2x.png",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "iconperson_darktheme.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "iconperson_lighttheme@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "iconperson_darktheme@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "iconperson_lighttheme@3x.png",
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "iconperson_darktheme@3x.png",
"idiom" : "universal",
"scale" : "3x"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -1,16 +1,50 @@
{
"images" : [
{
"filename" : "calloutBadge_shield.png",
"filename" : "iconshield_lighttheme.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "calloutBadge_shield@2x.png",
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "iconshield_darktheme.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "iconshield_lighttheme@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "iconshield_darktheme@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "iconshield_lighttheme@3x.png",
"idiom" : "universal",
"scale" : "3x"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"filename" : "iconshield_darktheme@3x.png",
"idiom" : "universal",
"scale" : "3x"
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

@ -5,9 +5,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "1.000",
"green" : "1.000",
"red" : "1.000"
"blue" : "0xF7",
"green" : "0xED",
"red" : "0xE3"
}
},
"idiom" : "universal"

View File

@ -5,9 +5,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "1.000",
"green" : "1.000",
"red" : "1.000"
"blue" : "0xEF",
"green" : "0xE6",
"red" : "0xDB"
}
},
"idiom" : "universal"
@ -23,9 +23,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "66",
"green" : "30",
"red" : "21"
"blue" : "0x46",
"green" : "0x25",
"red" : "0x19"
}
},
"idiom" : "universal"

View File

@ -5,9 +5,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "1.000",
"green" : "1.000",
"red" : "1.000"
"blue" : "0xF9",
"green" : "0xF2",
"red" : "0xEF"
}
},
"idiom" : "universal"
@ -23,9 +23,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "117",
"green" : "80",
"red" : "69"
"blue" : "0x73",
"green" : "0x4F",
"red" : "0x42"
}
},
"idiom" : "universal"

View File

@ -5,9 +5,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "233",
"green" : "221",
"red" : "209"
"blue" : "0xFA",
"green" : "0xF0",
"red" : "0xE4"
}
},
"idiom" : "universal"
@ -23,9 +23,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "106",
"green" : "63",
"red" : "44"
"blue" : "0x82",
"green" : "0x51",
"red" : "0x3D"
}
},
"idiom" : "universal"

View File

@ -5,9 +5,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xFD",
"green" : "0xF7",
"red" : "0xF1"
"blue" : "0xFA",
"green" : "0xF0",
"red" : "0xE4"
}
},
"idiom" : "universal"
@ -23,9 +23,9 @@
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x62",
"green" : "0x33",
"red" : "0x22"
"blue" : "0x82",
"green" : "0x51",
"red" : "0x3D"
}
},
"idiom" : "universal"

View File

@ -0,0 +1,38 @@
{
"colors" : [
{
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0xFA",
"green" : "0xF0",
"red" : "0xE4"
}
},
"idiom" : "universal"
},
{
"appearances" : [
{
"appearance" : "luminosity",
"value" : "dark"
}
],
"color" : {
"color-space" : "srgb",
"components" : {
"alpha" : "1.000",
"blue" : "0x82",
"green" : "0x51",
"red" : "0x3D"
}
},
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@ -29,11 +29,12 @@ internal enum Asset {
internal static let callout2 = ImageAsset(name: "callout2")
internal static let callout3 = ImageAsset(name: "callout3")
internal static let callout4 = ImageAsset(name: "callout4")
internal static let calloutBackupFailed = ImageAsset(name: "calloutBackupFailed")
internal static let calloutBackupFlow1 = ImageAsset(name: "calloutBackupFlow1")
internal static let calloutBackupSucceeded = ImageAsset(name: "calloutBackupSucceeded")
internal static let calloutBackupFailed = ImageAsset(name: "calloutBackupFailed")
}
internal enum Icons {
internal static let bank = ImageAsset(name: "bank")
internal static let list = ImageAsset(name: "list")
internal static let profile = ImageAsset(name: "profile")
internal static let shield = ImageAsset(name: "shield")
@ -70,6 +71,7 @@ internal enum Asset {
internal static let navigationButtonEnabled = ColorAsset(name: "NavigationButtonEnabled")
internal static let neumorphicDarkSide = ColorAsset(name: "NeumorphicDarkSide")
internal static let neumorphicLightSide = ColorAsset(name: "NeumorphicLightSide")
internal static let badgeBackground = ColorAsset(name: "badgeBackground")
}
internal enum ProgressIndicator {
internal static let gradientLeft = ColorAsset(name: "GradientLeft")

View File

@ -8,12 +8,11 @@
import SwiftUI
struct CircularFrame: View {
@Environment(\.colorScheme) var colorScheme
var body: some View {
GeometryReader { proxy in
let lineWidth = proxy.size.width * 0.06
let lineWidth = 20.0
let lineHalfwidth = lineWidth * 0.5
Circle()
.stroke(
LinearGradient(
@ -21,31 +20,34 @@ struct CircularFrame: View {
Asset.Colors.Onboarding.circularFrameGradientStart.color,
Asset.Colors.Onboarding.circularFrameGradientEnd.color
],
startPoint: colorScheme == .light ? .topLeading : .top,
endPoint: colorScheme == .light ? .bottomTrailing : .bottom
startPoint: .topLeading,
endPoint: .bottomTrailing
),
style: StrokeStyle(
lineWidth: lineWidth
)
)
.padding(colorScheme == .light ? 0 : 10)
if colorScheme == .dark {
Circle()
.stroke(
LinearGradient(
colors: [
Asset.Colors.Onboarding.circularFrameDarkOutlineGradientStart.color,
Asset.Colors.Onboarding.circularFrameDarkOutlineGradientEnd.color
],
startPoint: .top,
endPoint: .bottom
),
style: StrokeStyle(
lineWidth: lineWidth * 0.15
)
Circle()
.stroke(
LinearGradient(
colors: [
Asset.Colors.Onboarding.circularFrameDarkOutlineGradientStart.color,
Asset.Colors.Onboarding.circularFrameDarkOutlineGradientEnd.color
],
startPoint: .topLeading,
endPoint: .bottomTrailing
),
style: StrokeStyle(
lineWidth: lineWidth * 0.2
)
}
)
.frame(
width: proxy.size.width + lineWidth,
height: proxy.size.height + lineWidth,
alignment: .center
)
.offset(x: -lineHalfwidth, y: -lineHalfwidth)
}
}
}
@ -135,6 +137,11 @@ struct CircularFramePreviewHelper: View {
struct CircularFrame_Previews: PreviewProvider {
static var previews: some View {
CircularFramePreviewHelper()
.preferredColorScheme(.light)
.previewLayout(.device)
.applyScreenBackground()
CircularFramePreviewHelper()
.preferredColorScheme(.dark)
.previewLayout(.device)

View File

@ -88,6 +88,7 @@ struct CircularFrameBackground_Previews: PreviewProvider {
.frame(width: 300, height: 300)
.applyScreenBackground()
.neumorphic()
.preferredColorScheme(.dark)
}
.preferredColorScheme(.light)
.previewLayout(.fixed(width: size + 50, height: size + 50))

View File

@ -14,7 +14,7 @@ enum Badge: Equatable {
case person
case error
private func getImage() -> Image? {
private func badgeSymbol() -> Image? {
switch self {
case .shield:
return Asset.Assets.Icons.shield.image
@ -31,10 +31,8 @@ enum Badge: Equatable {
if self == .error {
ErrorBadge()
} else {
if let image = getImage() {
image
.resizable()
.renderingMode(.none)
if let symbol = badgeSymbol() {
IconBadge(image: symbol)
}
}
}
@ -45,12 +43,51 @@ struct ErrorBadge: View {
Text("X")
.font(.custom(FontFamily.Rubik.bold.name, size: 36))
.foregroundColor(Asset.Colors.BackgroundColors.red.color)
.frame(width: 60, height: 55, alignment: .center)
.background(Asset.Colors.BackgroundColors.numberedChip.color)
.frame(width: 60, height: 60, alignment: .center)
.background(Asset.Colors.Onboarding.badgeBackground.color)
.cornerRadius(10)
}
}
struct IconBadge: View {
let image: Image
var body: some View {
ZStack {
Rectangle()
.fill(
LinearGradient(
colors: [
Asset.Colors.Onboarding.circularFrameGradientStart.color,
Asset.Colors.Onboarding.circularFrameGradientEnd.color
],
startPoint: .top,
endPoint: .bottom
)
)
.frame(width: 60, height: 60, alignment: .center)
.cornerRadius(10)
Rectangle()
.fill(Asset.Colors.Onboarding.badgeBackground.color)
.frame(width: 55, height: 55, alignment: .center)
.cornerRadius(10)
.shadow(
color: Asset.Colors.Onboarding.badgeShadow.color,
radius: 10,
x: 0,
y: 0
)
image
.resizable()
.renderingMode(.none)
.scaledToFill()
.frame(width: 60, height: 60)
}
}
}
struct BadgesOverlay: Animatable, ViewModifier {
struct ViewState: Equatable {
let index: Int
@ -78,17 +115,8 @@ struct BadgesOverlay: Animatable, ViewModifier {
height: proxy.size.height * 0.35,
alignment: .center
)
.offset(
x: 4.0,
y: proxy.size.height * 0.15
)
.offset(y: proxy.size.height * 0.16)
.opacity(badgeIndex == viewStore.index ? 1 : 0)
.shadow(
color: Asset.Colors.Onboarding.badgeShadow.color,
radius: 10,
x: 0,
y: 0
)
}
}
@ -120,18 +148,9 @@ struct BadgeOverlay: Animatable, ViewModifier {
height: proxy.size.height * 0.35,
alignment: .center
)
.offset(
x: 4.0,
y: proxy.size.height * 0.15
)
.offset(y: proxy.size.height * 0.16)
.transition(.scale(scale: 2))
.transition(.opacity)
.shadow(
color: Asset.Colors.Onboarding.badgeShadow.color,
radius: 10,
x: 0,
y: 0
)
Spacer()
}
}
@ -162,7 +181,7 @@ struct Badge_Previews: PreviewProvider {
CircularFrame()
.frame(width: size, height: size)
.badgeIcon(.list)
CircularFrame()
.frame(width: size, height: size)
.badgeIcon(.person)
@ -173,5 +192,25 @@ struct Badge_Previews: PreviewProvider {
}
.preferredColorScheme(.light)
.previewLayout(.fixed(width: size + 50, height: size + 50))
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)
CircularFrame()
.frame(width: size, height: size)
.badgeIcon(.error)
}
.preferredColorScheme(.dark)
.previewLayout(.fixed(width: size + 50, height: size + 50))
}
}