You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
433 lines
17 KiB
433 lines
17 KiB
import SwiftUI
|
|
import QRCode
|
|
|
|
// MARK: - 二维码颜色
|
|
enum QRCodeColor: String, CaseIterable, Hashable {
|
|
case black = "black"
|
|
case white = "white"
|
|
case red = "red"
|
|
case blue = "blue"
|
|
case green = "green"
|
|
case yellow = "yellow"
|
|
case purple = "purple"
|
|
case orange = "orange"
|
|
case pink = "pink"
|
|
case cyan = "cyan"
|
|
case magenta = "magenta"
|
|
case brown = "brown"
|
|
case gray = "gray"
|
|
case navy = "navy"
|
|
case teal = "teal"
|
|
case indigo = "indigo"
|
|
case lime = "lime"
|
|
case maroon = "maroon"
|
|
case olive = "olive"
|
|
case silver = "silver"
|
|
|
|
// 渐变色
|
|
case gradientRed = "gradientRed"
|
|
case gradientBlue = "gradientBlue"
|
|
case gradientGreen = "gradientGreen"
|
|
case gradientPurple = "gradientPurple"
|
|
case gradientOrange = "gradientOrange"
|
|
case gradientPink = "gradientPink"
|
|
case gradientYellow = "gradientYellow"
|
|
case gradientCyan = "gradientCyan"
|
|
case gradientMagenta = "gradientMagenta"
|
|
case gradientTeal = "gradientTeal"
|
|
case gradientIndigo = "gradientIndigo"
|
|
case gradientLime = "gradientLime"
|
|
|
|
var color: Color {
|
|
switch self {
|
|
case .black: return Color(red: 0, green: 0, blue: 0)
|
|
case .white: return Color(red: 1, green: 1, blue: 1)
|
|
case .red: return Color(red: 1, green: 0, blue: 0)
|
|
case .blue: return Color(red: 0, green: 0, blue: 1)
|
|
case .green: return Color(red: 0, green: 1, blue: 0)
|
|
case .yellow: return Color(red: 1, green: 1, blue: 0)
|
|
case .purple: return Color(red: 0.5, green: 0, blue: 0.5)
|
|
case .orange: return Color(red: 1, green: 0.5, blue: 0)
|
|
case .pink: return Color(red: 1, green: 0.75, blue: 0.8)
|
|
case .cyan: return Color(red: 0, green: 1, blue: 1)
|
|
case .magenta: return Color(red: 1, green: 0, blue: 1)
|
|
case .brown: return Color(red: 0.6, green: 0.4, blue: 0.2)
|
|
case .gray: return Color(red: 0.5, green: 0.5, blue: 0.5)
|
|
case .navy: return Color(red: 0, green: 0, blue: 0.5)
|
|
case .teal: return Color(red: 0, green: 0.5, blue: 0.5)
|
|
case .indigo: return Color(red: 0.3, green: 0, blue: 0.5)
|
|
case .lime: return Color(red: 0.5, green: 1, blue: 0)
|
|
case .maroon: return Color(red: 0.5, green: 0, blue: 0)
|
|
case .olive: return Color(red: 0.5, green: 0.5, blue: 0)
|
|
case .silver: return Color(red: 0.75, green: 0.75, blue: 0.75)
|
|
case .gradientRed: return Color(red: 1, green: 0, blue: 0)
|
|
case .gradientBlue: return Color(red: 0, green: 0, blue: 1)
|
|
case .gradientGreen: return Color(red: 0, green: 1, blue: 0)
|
|
case .gradientPurple: return Color(red: 0.5, green: 0, blue: 0.5)
|
|
case .gradientOrange: return Color(red: 1, green: 0.5, blue: 0)
|
|
case .gradientPink: return Color(red: 1, green: 0.75, blue: 0.8)
|
|
case .gradientYellow: return Color(red: 1, green: 1, blue: 0)
|
|
case .gradientCyan: return Color(red: 0, green: 1, blue: 1)
|
|
case .gradientMagenta: return Color(red: 1, green: 0, blue: 1)
|
|
case .gradientTeal: return Color(red: 0, green: 0.5, blue: 0.5)
|
|
case .gradientIndigo: return Color(red: 0.3, green: 0, blue: 0.5)
|
|
case .gradientLime: return Color(red: 0.5, green: 1, blue: 0)
|
|
}
|
|
}
|
|
|
|
var cgColor: CGColor {
|
|
return color.cgColor!
|
|
}
|
|
|
|
static var foregroundColors: [QRCodeColor] {
|
|
return [.black, .red, .blue, .green, .purple, .orange, .pink, .brown, .navy, .teal, .indigo, .maroon, .olive, .gradientRed, .gradientBlue, .gradientGreen, .gradientPurple, .gradientOrange, .gradientPink, .gradientYellow, .gradientCyan, .gradientMagenta, .gradientTeal, .gradientIndigo, .gradientLime]
|
|
}
|
|
|
|
static var backgroundColors: [QRCodeColor] {
|
|
return [.white, .gray, .silver, .cyan, .yellow, .lime]
|
|
}
|
|
}
|
|
|
|
// MARK: - 二维码点类型
|
|
enum QRCodeDotType: String, CaseIterable, Hashable {
|
|
case square = "data_square"
|
|
case circle = "data_circle"
|
|
case roundedRect = "data_roundedRect"
|
|
case squircle = "data_squircle"
|
|
case diamond = "data_diamond"
|
|
case hexagon = "data_hexagon"
|
|
case star = "data_star"
|
|
case heart = "data_heart"
|
|
case flower = "data_flower"
|
|
case gear = "data_gear"
|
|
case abstract = "data_abstract"
|
|
case arrow = "data_arrow"
|
|
case blob = "data_blob"
|
|
case circuit = "data_circuit"
|
|
case crosshatch = "data_crosshatch"
|
|
case crt = "data_crt"
|
|
case curvePixel = "data_curvePixel"
|
|
case diagonal = "data_diagonal"
|
|
case diagonalStripes = "data_diagonalStripes"
|
|
case donut = "data_donut"
|
|
case dripHorizontal = "data_dripHorizontal"
|
|
case dripVertical = "data_dripVertical"
|
|
case flame = "data_flame"
|
|
case grid2x2 = "data_grid2x2"
|
|
case grid3x3 = "data_grid3x3"
|
|
case grid4x4 = "data_grid4x4"
|
|
case horizontal = "data_horizontal"
|
|
case koala = "data_koala"
|
|
case pointy = "data_pointy"
|
|
case razor = "data_razor"
|
|
case roundedEndIndent = "data_roundedEndIndent"
|
|
case roundedPath = "data_roundedPath"
|
|
case roundedTriangle = "data_roundedTriangle"
|
|
case sharp = "data_sharp"
|
|
case shiny = "data_shiny"
|
|
case spikyCircle = "data_spikyCircle"
|
|
case stitch = "data_stitch"
|
|
case vertical = "data_vertical"
|
|
case vortex = "data_vortex"
|
|
case wave = "data_wave"
|
|
case wex = "data_wex"
|
|
|
|
var thumbnailName: String {
|
|
return rawValue
|
|
}
|
|
|
|
var displayName: String {
|
|
switch self {
|
|
case .square: return "方形"
|
|
case .circle: return "圆形"
|
|
case .roundedRect: return "圆角矩形"
|
|
case .squircle: return "超椭圆"
|
|
case .diamond: return "菱形"
|
|
case .hexagon: return "六边形"
|
|
case .star: return "星形"
|
|
case .heart: return "心形"
|
|
case .flower: return "花朵"
|
|
case .gear: return "齿轮"
|
|
case .abstract: return "抽象"
|
|
case .arrow: return "箭头"
|
|
case .blob: return "斑点"
|
|
case .circuit: return "电路"
|
|
case .crosshatch: return "交叉线"
|
|
case .crt: return "CRT"
|
|
case .curvePixel: return "曲线像素"
|
|
case .diagonal: return "对角线"
|
|
case .diagonalStripes: return "对角条纹"
|
|
case .donut: return "甜甜圈"
|
|
case .dripHorizontal: return "水平滴落"
|
|
case .dripVertical: return "垂直滴落"
|
|
case .flame: return "火焰"
|
|
case .grid2x2: return "2x2网格"
|
|
case .grid3x3: return "3x3网格"
|
|
case .grid4x4: return "4x4网格"
|
|
case .horizontal: return "水平"
|
|
case .koala: return "考拉"
|
|
case .pointy: return "尖角"
|
|
case .razor: return "剃刀"
|
|
case .roundedEndIndent: return "圆角缩进"
|
|
case .roundedPath: return "圆角路径"
|
|
case .roundedTriangle: return "圆角三角形"
|
|
case .sharp: return "尖锐"
|
|
case .shiny: return "闪亮"
|
|
case .spikyCircle: return "尖刺圆形"
|
|
case .stitch: return "缝合"
|
|
case .vertical: return "垂直"
|
|
case .vortex: return "漩涡"
|
|
case .wave: return "波浪"
|
|
case .wex: return "WEX"
|
|
}
|
|
}
|
|
|
|
var pixelShape: QRCodePixelShapeGenerator {
|
|
switch self {
|
|
case .square: return QRCode.PixelShape.Square()
|
|
case .circle: return QRCode.PixelShape.Circle()
|
|
case .roundedRect: return QRCode.PixelShape.RoundedRect()
|
|
case .squircle: return QRCode.PixelShape.Squircle()
|
|
case .diamond: return QRCode.PixelShape.Diamond()
|
|
case .hexagon: return QRCode.PixelShape.Hexagon()
|
|
case .star: return QRCode.PixelShape.Star()
|
|
case .heart: return QRCode.PixelShape.Heart()
|
|
case .flower: return QRCode.PixelShape.Flower()
|
|
case .gear: return QRCode.PixelShape.Gear()
|
|
case .abstract: return QRCode.PixelShape.Abstract()
|
|
case .arrow: return QRCode.PixelShape.Arrow()
|
|
case .blob: return QRCode.PixelShape.Blob()
|
|
case .circuit: return QRCode.PixelShape.Circuit()
|
|
case .crosshatch: return QRCode.PixelShape.Crosshatch()
|
|
case .crt: return QRCode.PixelShape.CRT()
|
|
case .curvePixel: return QRCode.PixelShape.CurvePixel()
|
|
case .diagonal: return QRCode.PixelShape.Diagonal()
|
|
case .diagonalStripes: return QRCode.PixelShape.DiagonalStripes()
|
|
case .donut: return QRCode.PixelShape.Donut()
|
|
case .dripHorizontal: return QRCode.PixelShape.DripHorizontal()
|
|
case .dripVertical: return QRCode.PixelShape.DripVertical()
|
|
case .flame: return QRCode.PixelShape.Flame()
|
|
case .grid2x2: return QRCode.PixelShape.Grid2x2()
|
|
case .grid3x3: return QRCode.PixelShape.Grid3x3()
|
|
case .grid4x4: return QRCode.PixelShape.Grid4x4()
|
|
case .horizontal: return QRCode.PixelShape.Horizontal()
|
|
case .koala: return QRCode.PixelShape.Koala()
|
|
case .pointy: return QRCode.PixelShape.Pointy()
|
|
case .razor: return QRCode.PixelShape.Razor()
|
|
case .roundedEndIndent: return QRCode.PixelShape.RoundedEndIndent()
|
|
case .roundedPath: return QRCode.PixelShape.RoundedPath()
|
|
case .roundedTriangle: return QRCode.PixelShape.RoundedTriangle()
|
|
case .sharp: return QRCode.PixelShape.Sharp()
|
|
case .shiny: return QRCode.PixelShape.Shiny()
|
|
case .spikyCircle: return QRCode.PixelShape.SpikyCircle()
|
|
case .stitch: return QRCode.PixelShape.Stitch()
|
|
case .vertical: return QRCode.PixelShape.Vertical()
|
|
case .vortex: return QRCode.PixelShape.Vortex()
|
|
case .wave: return QRCode.PixelShape.Wave()
|
|
case .wex: return QRCode.PixelShape.Wex()
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - 二维码眼睛类型
|
|
enum QRCodeEyeType: String, CaseIterable, Hashable {
|
|
case square = "eye_square"
|
|
case circle = "eye_circle"
|
|
case roundedRect = "eye_roundedRect"
|
|
case squircle = "eye_squircle"
|
|
case arc = "eye_arc"
|
|
case barsHorizontal = "eye_barsHorizontal"
|
|
case barsVertical = "eye_barsVertical"
|
|
case cloud = "eye_cloud"
|
|
case cloudCircle = "eye_cloudCircle"
|
|
case corneredPixels = "eye_corneredPixels"
|
|
case crt = "eye_crt"
|
|
case diagonalStripes = "eye_diagonalStripes"
|
|
case dotDragHorizontal = "eye_dotDragHorizontal"
|
|
case dotDragVertical = "eye_dotDragVertical"
|
|
case edges = "eye_edges"
|
|
case explode = "eye_explode"
|
|
case eye = "eye_eye"
|
|
case fabricScissors = "eye_fabricScissors"
|
|
case fireball = "eye_fireball"
|
|
case flame = "eye_flame"
|
|
case headlight = "eye_headlight"
|
|
case holePunch = "eye_holePunch"
|
|
case leaf = "eye_leaf"
|
|
case peacock = "eye_peacock"
|
|
case pinch = "eye_pinch"
|
|
case pixels = "eye_pixels"
|
|
case roundedOuter = "eye_roundedOuter"
|
|
case roundedPointingIn = "eye_roundedPointingIn"
|
|
case roundedPointingOut = "eye_roundedPointingOut"
|
|
case shield = "eye_shield"
|
|
case spikyCircle = "eye_spikyCircle"
|
|
case squarePeg = "eye_squarePeg"
|
|
case surroundingBars = "eye_surroundingBars"
|
|
case teardrop = "eye_teardrop"
|
|
case ufo = "eye_ufo"
|
|
case ufoRounded = "eye_ufoRounded"
|
|
case usePixelShape = "eye_usePixelShape"
|
|
|
|
var thumbnailName: String {
|
|
return rawValue
|
|
}
|
|
|
|
var displayName: String {
|
|
switch self {
|
|
case .square: return "方形"
|
|
case .circle: return "圆形"
|
|
case .roundedRect: return "圆角矩形"
|
|
case .squircle: return "超椭圆"
|
|
case .arc: return "弧形"
|
|
case .barsHorizontal: return "水平条"
|
|
case .barsVertical: return "垂直条"
|
|
case .cloud: return "云朵"
|
|
case .cloudCircle: return "云朵圆形"
|
|
case .corneredPixels: return "角像素"
|
|
case .crt: return "CRT"
|
|
case .diagonalStripes: return "对角条纹"
|
|
case .dotDragHorizontal: return "水平拖拽点"
|
|
case .dotDragVertical: return "垂直拖拽点"
|
|
case .edges: return "边缘"
|
|
case .explode: return "爆炸"
|
|
case .eye: return "眼睛"
|
|
case .fabricScissors: return "剪刀"
|
|
case .fireball: return "火球"
|
|
case .flame: return "火焰"
|
|
case .headlight: return "头灯"
|
|
case .holePunch: return "打孔"
|
|
case .leaf: return "叶子"
|
|
case .peacock: return "孔雀"
|
|
case .pinch: return "捏合"
|
|
case .pixels: return "像素"
|
|
case .roundedOuter: return "圆角外"
|
|
case .roundedPointingIn: return "圆角向内"
|
|
case .roundedPointingOut: return "圆角向外"
|
|
case .shield: return "盾牌"
|
|
case .spikyCircle: return "尖刺圆形"
|
|
case .squarePeg: return "方形钉"
|
|
case .surroundingBars: return "环绕条"
|
|
case .teardrop: return "泪滴"
|
|
case .ufo: return "UFO"
|
|
case .ufoRounded: return "圆角UFO"
|
|
case .usePixelShape: return "使用像素形状"
|
|
}
|
|
}
|
|
|
|
var eyeShape: QRCodeEyeShapeGenerator {
|
|
switch self {
|
|
case .square: return QRCode.EyeShape.Square()
|
|
case .circle: return QRCode.EyeShape.Circle()
|
|
case .roundedRect: return QRCode.EyeShape.RoundedRect()
|
|
case .squircle: return QRCode.EyeShape.Squircle()
|
|
case .arc: return QRCode.EyeShape.Arc()
|
|
case .barsHorizontal: return QRCode.EyeShape.BarsHorizontal()
|
|
case .barsVertical: return QRCode.EyeShape.BarsVertical()
|
|
case .cloud: return QRCode.EyeShape.Cloud()
|
|
case .cloudCircle: return QRCode.EyeShape.CloudCircle()
|
|
case .corneredPixels: return QRCode.EyeShape.CorneredPixels()
|
|
case .crt: return QRCode.EyeShape.CRT()
|
|
case .diagonalStripes: return QRCode.EyeShape.DiagonalStripes()
|
|
case .dotDragHorizontal: return QRCode.EyeShape.DotDragHorizontal()
|
|
case .dotDragVertical: return QRCode.EyeShape.DotDragVertical()
|
|
case .edges: return QRCode.EyeShape.Edges()
|
|
case .explode: return QRCode.EyeShape.Explode()
|
|
case .eye: return QRCode.EyeShape.Eye()
|
|
case .fabricScissors: return QRCode.EyeShape.FabricScissors()
|
|
case .fireball: return QRCode.EyeShape.Fireball()
|
|
case .flame: return QRCode.EyeShape.Flame()
|
|
case .headlight: return QRCode.EyeShape.Headlight()
|
|
case .holePunch: return QRCode.EyeShape.HolePunch()
|
|
case .leaf: return QRCode.EyeShape.Leaf()
|
|
case .peacock: return QRCode.EyeShape.Peacock()
|
|
case .pinch: return QRCode.EyeShape.Pinch()
|
|
case .pixels: return QRCode.EyeShape.Pixels()
|
|
case .roundedOuter: return QRCode.EyeShape.RoundedOuter()
|
|
case .roundedPointingIn: return QRCode.EyeShape.RoundedPointingIn()
|
|
case .roundedPointingOut: return QRCode.EyeShape.RoundedPointingOut()
|
|
case .shield: return QRCode.EyeShape.Shield()
|
|
case .spikyCircle: return QRCode.EyeShape.SpikyCircle()
|
|
case .squarePeg: return QRCode.EyeShape.SquarePeg()
|
|
case .surroundingBars: return QRCode.EyeShape.SurroundingBars()
|
|
case .teardrop: return QRCode.EyeShape.Teardrop()
|
|
case .ufo: return QRCode.EyeShape.UFO()
|
|
case .ufoRounded: return QRCode.EyeShape.UFORounded()
|
|
case .usePixelShape: return QRCode.EyeShape.UsePixelShape()
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - 二维码Logo
|
|
enum QRCodeLogo: String, CaseIterable, Hashable {
|
|
case scanMe = "scanMe"
|
|
case gmail = "gmail"
|
|
case paypal = "paypal"
|
|
case googlePlaystore = "googlePlaystore"
|
|
case spotify = "spotify"
|
|
case telegram = "telegram"
|
|
case whatsApp = "whatsApp"
|
|
case linkedIn = "linkedIn"
|
|
case tikTok = "tikTok"
|
|
case snapchat = "snapchat"
|
|
case youtube = "youtube"
|
|
case x = "x"
|
|
case pinterest = "pinterest"
|
|
case instagram = "instagram"
|
|
case facebook = "facebook"
|
|
|
|
var thumbnailName: String {
|
|
return rawValue
|
|
}
|
|
|
|
var displayName: String {
|
|
switch self {
|
|
case .scanMe: return "扫描我"
|
|
case .gmail: return "Gmail"
|
|
case .paypal: return "PayPal"
|
|
case .googlePlaystore: return "Google Play"
|
|
case .spotify: return "Spotify"
|
|
case .telegram: return "Telegram"
|
|
case .whatsApp: return "WhatsApp"
|
|
case .linkedIn: return "LinkedIn"
|
|
case .tikTok: return "TikTok"
|
|
case .snapchat: return "Snapchat"
|
|
case .youtube: return "YouTube"
|
|
case .x: return "X"
|
|
case .pinterest: return "Pinterest"
|
|
case .instagram: return "Instagram"
|
|
case .facebook: return "Facebook"
|
|
}
|
|
}
|
|
|
|
var image: UIImage? {
|
|
// 方法1: 尝试从Bundle中直接加载
|
|
if let image = UIImage(named: rawValue) {
|
|
return image
|
|
}
|
|
|
|
// 方法2: 尝试从logos子目录加载
|
|
if let image = UIImage(named: "logos/\(rawValue)") {
|
|
return image
|
|
}
|
|
|
|
// 方法3: 尝试从Resources/logos路径加载
|
|
if let path = Bundle.main.path(forResource: rawValue, ofType: "png", inDirectory: "Resources/logos") {
|
|
return UIImage(contentsOfFile: path)
|
|
}
|
|
|
|
// 方法4: 尝试从Bundle的Resources目录加载
|
|
if let bundlePath = Bundle.main.path(forResource: "Resources", ofType: nil),
|
|
let imagePath = Bundle.main.path(forResource: rawValue, ofType: "png", inDirectory: "logos") {
|
|
return UIImage(contentsOfFile: imagePath)
|
|
}
|
|
|
|
// 方法5: 尝试从Assets.xcassets加载
|
|
if let image = UIImage(named: rawValue, in: Bundle.main, with: nil) {
|
|
return image
|
|
}
|
|
|
|
return nil
|
|
}
|
|
}
|