From 9abb38594bfc4ac855449327ca4ef546e22fbddb Mon Sep 17 00:00:00 2001 From: v504 Date: Mon, 25 Aug 2025 17:24:00 +0800 Subject: [PATCH] Enhance CreateQRCodeView to support navigation to QRCodeStyleView upon QR code creation; implement comprehensive QR code content generation for various types including mail, WiFi, vCard, MeCard, location, calendar, and social media. This update improves user experience by streamlining the QR code creation process and expanding functionality. --- .../Resources.imageset/Contents.json | 20 + MyQrCode/Models/QRCodeStyleModels.swift | 402 ++++++++++++++++++ MyQrCode/Resources/dots/data_abstract.png | Bin 0 -> 2011 bytes MyQrCode/Resources/dots/data_crosshatch.png | Bin 0 -> 3151 bytes MyQrCode/Resources/dots/data_crt.png | Bin 0 -> 2588 bytes MyQrCode/Resources/dots/data_flower.png | Bin 0 -> 3465 bytes MyQrCode/Resources/dots/data_grid3x3.png | Bin 0 -> 1234 bytes MyQrCode/Resources/dots/data_pointy.png | Bin 0 -> 741 bytes MyQrCode/Resources/dots/data_roundedRect.png | Bin 0 -> 2205 bytes MyQrCode/Resources/dots/data_shiny.png | Bin 0 -> 2928 bytes MyQrCode/Resources/dots/data_square.png | Bin 0 -> 478 bytes MyQrCode/Resources/dots/data_vertical.png | Bin 0 -> 1670 bytes MyQrCode/Resources/dots/data_vortex.png | Bin 0 -> 1641 bytes MyQrCode/Resources/dots/data_wex.png | Bin 0 -> 2376 bytes MyQrCode/Resources/eyes/eye_arc.png | Bin 0 -> 1863 bytes .../Resources/eyes/eye_barsHorizontal.png | Bin 0 -> 1330 bytes MyQrCode/Resources/eyes/eye_circle.png | Bin 0 -> 2633 bytes MyQrCode/Resources/eyes/eye_cloud.png | Bin 0 -> 2490 bytes MyQrCode/Resources/eyes/eye_cloudCircle.png | Bin 0 -> 3208 bytes .../Resources/eyes/eye_corneredPixels.png | Bin 0 -> 937 bytes MyQrCode/Resources/eyes/eye_explode.png | Bin 0 -> 1945 bytes MyQrCode/Resources/eyes/eye_eye.png | Bin 0 -> 2268 bytes MyQrCode/Resources/eyes/eye_fireball.png | Bin 0 -> 2035 bytes MyQrCode/Resources/eyes/eye_headlight.png | Bin 0 -> 1953 bytes MyQrCode/Resources/eyes/eye_leaf.png | Bin 0 -> 1032 bytes MyQrCode/Resources/eyes/eye_pinch.png | Bin 0 -> 2145 bytes MyQrCode/Resources/eyes/eye_roundedOuter.png | Bin 0 -> 744 bytes MyQrCode/Resources/eyes/eye_shield.png | Bin 0 -> 1393 bytes MyQrCode/Resources/eyes/eye_square.png | Bin 0 -> 239 bytes MyQrCode/Resources/eyes/eye_squarePeg.png | Bin 0 -> 1812 bytes MyQrCode/Resources/eyes/eye_usePixelShape.png | Bin 0 -> 169 bytes MyQrCode/Views/CreateQRCodeView.swift | 142 ++++++- MyQrCode/Views/QRCodeStyleView.swift | 396 +++++++++++++++++ docs/CREATE_QRCODE_TO_STYLE_VIEW_README.md | 240 +++++++++++ docs/QRCODE_STYLE_VIEW_README.md | 208 +++++++++ 35 files changed, 1405 insertions(+), 3 deletions(-) create mode 100644 MyQrCode/Assets.xcassets/Resources.imageset/Contents.json create mode 100644 MyQrCode/Models/QRCodeStyleModels.swift create mode 100644 MyQrCode/Resources/dots/data_abstract.png create mode 100644 MyQrCode/Resources/dots/data_crosshatch.png create mode 100644 MyQrCode/Resources/dots/data_crt.png create mode 100644 MyQrCode/Resources/dots/data_flower.png create mode 100644 MyQrCode/Resources/dots/data_grid3x3.png create mode 100644 MyQrCode/Resources/dots/data_pointy.png create mode 100644 MyQrCode/Resources/dots/data_roundedRect.png create mode 100644 MyQrCode/Resources/dots/data_shiny.png create mode 100644 MyQrCode/Resources/dots/data_square.png create mode 100644 MyQrCode/Resources/dots/data_vertical.png create mode 100644 MyQrCode/Resources/dots/data_vortex.png create mode 100644 MyQrCode/Resources/dots/data_wex.png create mode 100644 MyQrCode/Resources/eyes/eye_arc.png create mode 100644 MyQrCode/Resources/eyes/eye_barsHorizontal.png create mode 100644 MyQrCode/Resources/eyes/eye_circle.png create mode 100644 MyQrCode/Resources/eyes/eye_cloud.png create mode 100644 MyQrCode/Resources/eyes/eye_cloudCircle.png create mode 100644 MyQrCode/Resources/eyes/eye_corneredPixels.png create mode 100644 MyQrCode/Resources/eyes/eye_explode.png create mode 100644 MyQrCode/Resources/eyes/eye_eye.png create mode 100644 MyQrCode/Resources/eyes/eye_fireball.png create mode 100644 MyQrCode/Resources/eyes/eye_headlight.png create mode 100644 MyQrCode/Resources/eyes/eye_leaf.png create mode 100644 MyQrCode/Resources/eyes/eye_pinch.png create mode 100644 MyQrCode/Resources/eyes/eye_roundedOuter.png create mode 100644 MyQrCode/Resources/eyes/eye_shield.png create mode 100644 MyQrCode/Resources/eyes/eye_square.png create mode 100644 MyQrCode/Resources/eyes/eye_squarePeg.png create mode 100644 MyQrCode/Resources/eyes/eye_usePixelShape.png create mode 100644 MyQrCode/Views/QRCodeStyleView.swift create mode 100644 docs/CREATE_QRCODE_TO_STYLE_VIEW_README.md create mode 100644 docs/QRCODE_STYLE_VIEW_README.md diff --git a/MyQrCode/Assets.xcassets/Resources.imageset/Contents.json b/MyQrCode/Assets.xcassets/Resources.imageset/Contents.json new file mode 100644 index 0000000..a19a549 --- /dev/null +++ b/MyQrCode/Assets.xcassets/Resources.imageset/Contents.json @@ -0,0 +1,20 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/MyQrCode/Models/QRCodeStyleModels.swift b/MyQrCode/Models/QRCodeStyleModels.swift new file mode 100644 index 0000000..649f231 --- /dev/null +++ b/MyQrCode/Models/QRCodeStyleModels.swift @@ -0,0 +1,402 @@ +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" + } + } +} diff --git a/MyQrCode/Resources/dots/data_abstract.png b/MyQrCode/Resources/dots/data_abstract.png new file mode 100644 index 0000000000000000000000000000000000000000..84bfaf58b7b03ad7e8fc9b1ed887373a81f071a0 GIT binary patch literal 2011 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 literal 0 HcmV?d00001 diff --git a/MyQrCode/Resources/dots/data_crt.png b/MyQrCode/Resources/dots/data_crt.png new file mode 100644 index 0000000000000000000000000000000000000000..05db06de529a02e2699fa31f913fa695108c9d5a GIT binary patch literal 2588 zcmZve`#%#3AIB#~8)L%6kfae}p2{W6r4?g`DR;&cPHr=~v{f$KlIea?))dppVwJ)n zxsMJ)mRsaH_vAL0+_k6k{B)k@_5ASteqW!@_YZi#({RrA5U?s3002NR4(QXruJG^K z{c8c>s8VMD05pa{+q#j(<_4p&-4hy(i*iyJy5gtX1DT@)m{{1r(mXffe5a+hLwpb@ zw*MY1*S;OGcJ{9Zn3A(q^WMO4ySFMgJff}eEw4MSIhDmA*uT@vCk!$LBU>WTMSLWu zcDZowVikY6fni~T$I>YRg;|{f21rD^USP+6&J!3y@jWl>4xe`u5}_3?bgy7H5|DA- z#pXF&X;yrsUrK9#$Y~OcF*`?S%T$~NjvN+`sbdQY$>zf=|QI*6hqsgm`O~?E#-7JSI&X8Z*B1EJw?zn?CH=Y{*5aMF$J3AEq%|w~HPW zNLPv7uE?;=0N%k;eNtLz(=D;|ep(AVzAlm{#ZEW- zUMld{eXW=Qd>~4*+8R(csFG?f;t(nyQ!I`bG>H)82r@~~`aUO5SH8#aWLwrPzjB1a zUh{6(eFN)VpVR><)bAV;8nH+H_{9(ci9B1QbfqwSO}{!K%97~d;Oz&MQCEL7eBeuG z(MxU9$m2v-)+67dm${~hcTW~x=?6SCwvaW&US3c8(GRbw)_W(j4+4~iz0ek1BS)1k zJRHO;t3&3cH>Lv5N;k7o=M7gK+=*Ij99z=GTTFE0_Qt|d#fDg zloBr1{x6wlZjbCf&0vMW(BiB8z_UH3nva?cpc(2Qlq^Ee4aB&ALQ~^9&3xX01ZNVZ zU?*b2d1~UFlMW;+rgKh*&GRamNj&n$Z3$0mDD1l!v~!2Bi@;R_$tLG3OseJu%Ua5l zw9EElOOP2hxfVin;Q`)E?JN|rE38!9X z-N1%hf9TJJRWL&`oT3aFp6f+wUeJK7RRHmlW+dff!K182=~1~MAE-zH59Kepn^kHi z*8k|tp6&N9oh-CQP&j-%Q#9Ikjlb16ZgP)wCXP*_IDett{42@7%Ghf-It)!z*x}@^ z28)VTzOD_LS|mKKc~&}+nRnY)W0Pe%f&Gh&aWZ`;+iX-2JKL0*w#W&3sQ#_Wb;&(4 zP!Dm}$7`#b;h*UPW*51mS1Ihf2eqs)IEU}@_ptcV!#n9V?|u{ny>VSKNgw(Wdah4C z57KmAOP%)~<`^E=cggF-)NfgUr@2R^9Ajep{Cswo%&idQ8XM)RExG zW0B(MYbdD_|0#2V32OJKZNlwQ_hfI#WWE_R+9fomcZq_$VYe`j% zl*LZbF|h)Wc36ydB7{kn%Cf06IUxtG)wU2y+%HiHFBHRa#a%SrGkFJ%l0QZZK;!3+ zusD0L#>~1pclU5YIn+@)PPL(5I``^Jt>v7q{Y!h&{X4=2E`Z%0wck_B z(qDn4%1ztMDbEKAQ#U>`Th)@h(B&y8N8^y2db+!cxK zFMrxE2ZV3fCMucx;nSbSUUmrcKUtsV`u>n=fj)i-N?iVYzoVSw)|0bdxU7S+S{eFj zCB^csC^u?CCvKw#;@<|k_82TdoI@91E!Gk3EEJvK$MO4nt60P0dzg%EAB0KRR@U+Up z-Z=AH;$waf&V}HuKR_C7r!9&NnWLzbKL6qZ=vWxrgX=1Eh1#cFhK1d@SuXjRN~tI?pIn z!aop4I;Oq%B+x2sVnG>lB{JspK(bvuwS_)%~O-D?V@v(NUm^9zD?`nL0SlO^X2 zX}9Bksd;xNwe~}0Mhf7^I~PocFdjdM?GXvMh%Mvc@g{4D-^egQPa=z%R19< zLgE@v{aHCRvb0#b$+cNLo*jjcW^=3O)`K?&&nAp;`Uv?+bDexk&!YF7k>bwh4<#yY kL*lLfk2L+4LH$nbJ7`IU`L?+8>k@Mk^lez literal 0 HcmV?d00001 diff --git a/MyQrCode/Resources/dots/data_flower.png b/MyQrCode/Resources/dots/data_flower.png new file mode 100644 index 0000000000000000000000000000000000000000..1ee73bcb8cba69de0b03c7f8fe85edd3d57655e5 GIT binary patch literal 3465 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 literal 0 HcmV?d00001 diff --git a/MyQrCode/Resources/dots/data_pointy.png b/MyQrCode/Resources/dots/data_pointy.png new file mode 100644 index 0000000000000000000000000000000000000000..0dc20f3ddf2234ca1f33f1ee818d00e224f0cbf8 GIT binary patch literal 741 zcmeAS@N?(olHy`uVBq!ia0vp^A3&G`NH9p-ZS!MbU|Qqp;uuoF`1Vd?s&1f&+e2Oh z4h4sfD@JR5*e^RPq%LV#sWgKrk6V0MC;Nfc+{&_hzwd74vZ#?ckbnJa3MZe(hJ=Gn ztlVNc5eUYEIV?y5HEZ^~Px!D=6V-f1C!=IGA^y>slvg?2N#KOc;l!~g72je+>`#+??jXO6y1(DMUI zSJimYMljcbI|0u4*bT3HczW$xRIn~(*fB(Gjw*0{H-{)Pevll)6 z!TVw36>R}y1My;m?_vVZV4BI0^?Y}Cb)!V{^P{bM9nKv5{Af{}(z6GZg@yXU=bLBl z*dgBa{Gdn79q*%`6O{Dc9eq@3ARzud>7$KAM|btc3OSx5NB2h9@UuO76sI$fof)W2 z?0j?Mjuqk^&ks8A9LO%sZJNBlgh8U>^T7+V`P=T*7<_rwywF^pXYbF17iZa>^X(+6 zpi&hEUzas+G?zKE*D~S3T=xAnC3_2b=i8iVel9J&m4l$a@6WHlf3Nu4zlm#KcQ?0N zRez`~&AqzypFesS{n!?AxyYOCbFkp)!qkRFi3;We4m^7p6BO9)F&GHgqjH(^8FmPQ z31KKpqNCBA;ZDa)5U~@=6Ek-bx0yEfLE{kb|)`a!oHB4w}qgMVTF-)l-g-aiMW NUr$#*mvv4FO#tm6Ln{CP literal 0 HcmV?d00001 diff --git a/MyQrCode/Resources/dots/data_roundedRect.png b/MyQrCode/Resources/dots/data_roundedRect.png new file mode 100644 index 0000000000000000000000000000000000000000..89b075874f60ec4510b38e5a25c29bed5ab26d39 GIT binary patch literal 2205 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 literal 0 HcmV?d00001 diff --git a/MyQrCode/Resources/dots/data_shiny.png b/MyQrCode/Resources/dots/data_shiny.png new file mode 100644 index 0000000000000000000000000000000000000000..d61db5cbc90fe65737cc19a5103d06b17c08cc3a GIT binary patch literal 2928 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 literal 0 HcmV?d00001 diff --git a/MyQrCode/Resources/dots/data_square.png b/MyQrCode/Resources/dots/data_square.png new file mode 100644 index 0000000000000000000000000000000000000000..ca6aa2499590e74c602e8ddda9a69673abb30c73 GIT binary patch literal 478 zcmeAS@N?(olHy`uVBq!ia0vp^A3&G`NH9p-ZS!MbU|j0y;uuoF`1Y<~!QldlV-I)z zj=i%{qg5dZ zf)97vpINmWO$~jJDL!izcQ>O1Zcx$s;HgB^D-p49aRzPne&^li*ET*j-s6kUf)D$$ z&HstsU_D^7HCpTY45$8Gtw;Ax+c2Y^^UnKQvj1OqJ(m!(#b>|<`y+F0YVI%0E?;G+ z^R4u?({^>Mtdr+I2#DSNymto++_e_$Jm{cC@>c9?Wu0TY_!s^@y;sD3`&RzwC-)BL z&$<5f<)oN>j~Ll-gE})%$efycIDgMh1_ri!X$SCuc%hnK_D`C(af2ex)78&qol`;+ E01{)bDF6Tf literal 0 HcmV?d00001 diff --git a/MyQrCode/Resources/dots/data_vertical.png b/MyQrCode/Resources/dots/data_vertical.png new file mode 100644 index 0000000000000000000000000000000000000000..d31d5da017e0413702fd0c8514f6c31a7475c8f5 GIT binary patch literal 1670 zcmZXVdsNZ~6vufZ5|Zzwk}Eew&C-R6iqEL@sHh2PQwLUVVm`34(y#=!rCa5xFg5Yj zlr=M9PRXgmAJ(F&X$bkqqx`a_fu)pYHPg0Er=3pyaUbX0zrNpl&*v6J)3)P`ZHyrh z2rev?y5qlUcoRndC5UZ+j0SMnKjBM)iHcb;(qAdAAKc9C0KYP zZ^s7Y>Kl!<>i*N~306A9rN>4Vf9`NXvN2YdEm~7<`$D`-SJzU}HMfgel8_gL@h!42 zUg3z>U-MBX`=vV%OiXt=>()(=&oAQxDBp@G_!9*y17^|!i|%0whMsF*eYZ;*DNXxb^n3fR7yDxR7<$$)PZ^e}op^|IjoNK_CRM(meitN)@M9Hi) zSb}*uYAtF^nhn<3N37Ikv-IfLz;g5iE_he!aFF}wX*HJ|gB|&7MsP#I=bIJ6G{M#k z=PxWHNcM|hP?dplM!~wM>5Hy&V(v|yaywJRa{S-YSFPqB8T+B#oJ0HEe4Ovr4SHwu^uola~@vMywfDKvYS`5 zUtr|V>#kGVjZC!w$sA-j@+(xuv>RK4kUaE)PWIARv2T|IggUU7&7YyoFnOxrBErp=q66=pV|(Tgv`5t&eCacoxU zVu7Td`rd8g*De;H7xTUWtUXtyzn;HMl0Jq3Wa+IRloaVLvw{tETXi;{5MlimD8~s?+xs?cD8A&o(|tG#aWl%x|_NYl_Wx9Z;xT z;txJ8sRjFx@o`I<2o9p**pnWr!9r8ncL7ZsE?{?4I2MV4QzzlWf(!-8;P@gh5zeQm{tLkKT znz(R5L5=k!Hs%UMX!X)jCr(X|cEw>k`pZKq52ss%1Zi zrBf@`2C-#Ne$-3=z~^Q|D~kajwSLQ zFLM68lii~wd4@poTVRbeYjzD*&VcrA%y&2EVjJ2|AqI8^jb7q`3;5``=k8fat804%Gdi#R wd16~imtpj##&!_D_t-lvAHw5fx{S1~z%z=Ka87+l*P90uwv|S03Ssg81u|>@1ONa4 literal 0 HcmV?d00001 diff --git a/MyQrCode/Resources/dots/data_vortex.png b/MyQrCode/Resources/dots/data_vortex.png new file mode 100644 index 0000000000000000000000000000000000000000..1a1d7ee8efbd505cf3010926dc13b79298137017 GIT binary patch literal 1641 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 literal 0 HcmV?d00001 diff --git a/MyQrCode/Resources/eyes/eye_arc.png b/MyQrCode/Resources/eyes/eye_arc.png new file mode 100644 index 0000000000000000000000000000000000000000..9b6ac5f1b47fe75ca29a21a5b4e14eb490512b6b GIT binary patch literal 1863 zcmZvd`9IW&AIB%=GLCUXn31F!6Sk2%)?geFnoyE!D64N_h8&|tGtFnWQ_it$ja@3% z(F~hpa!fwSYFO*YvE}-R6m4dCM888Fc@}cK_v1VzYne2`i(mXMXsc z=b_1lJj2HtsjBf9TetUw9^3KbW$P^sXX{*Sjju12-R4W9Ww`lGChcm zMDZb8>LH4?ZFK9~wxJ3NG+u2vJ^ibhoPByxy4IP3_Q^`$`x{sjs3*0+aoof6)?My^ z3PRL5-Fq{C+z<~SR@o~IoqIp0`c`ulM<(L| z>DlnLwtqQ^=qu9luto_aT$>r_dvVH2G&@;AD(`X7n^<0vkY=Owz?uc~*sCM8WadaX z>5a`Kcy7?C}i78XWI; zKbkYBgKyT}niP&*YEh59XFm=qdUbYRu|m-=n?>Ge#JQ%Um6jIk-A$|Q)DJUH7S0$) zc9FBz{%?4&eGnR(VIR$?pblHw``p{cj|;x{orhOOm+)Bbl}H`^E0 zk(yDl0s(r^VF_<5=7rZJDCm+^GmelE_13kHqIS$w4nHpB2wz|?TE#O9H-ZWAl4tvX zkg>-_Z?&kStXsBnBGcv+G5%2GaakIZ1XX18R3WoL+{KQ`%kV?FaH$JoN$3|WglC3z z9G=>7i?1d|34O9D5B2bu>KY@6ncU`Z#+l~8hk6rdE^hR89z~MXwiGz?4uEe_9pPze zuYws0C#ObTUI>`kx}03j$3&wN2H~$l8FV7v`}=&;vY39>^2&$Z-Fzy^P!%<^5jU1( zhf`K<%&uca^FV<1v0!Dg)AudOc};Zuww4x&t+4h`&>+D+7r$yLAwfkuV6UdvQ|c_ zW>%vD!|`P#XlVKDlBg@nEJX0IPLN~pJ}$($W2fk}1>Q9vx~&A|1~xHBwPh0~57Cfb zVjdT$oJ*c%GBC*;;O*1N?do^AY;2QKb#Afq0!?43k8kr5MyoIpF{q}3vbp&bl6vxW z_oS<<(GFlb)$+ci>i}&F3pxBv!8L5hS8`l+@xO~2y;VOVrb|G4+n`D-O>x4a>;)w^ zHwX0y8lj#8_)+kS;Ho?EY$<*Oh-I)f{2hyK2WH`ci1G)y{6AhnhDr3!nxvij};D$K{)((J=u5cis%diFM3C1 zm>g*;OMmh{LkyDL7bwB|^60WH)EoQ#i&+2}7}5wf?sR18^XBu1)L1}?eC@G{82rG> zo}r0Bw?`x%sB86Kj1C$^rrt-8H?Kj4TszwFH$Xilf2nc+MbFvh#D1s7CiQ9EWp=cG z{bXCIL-ZEP{N2J!4!SnzQBL5Of&9->b`#+*jRA6nw%qHu?Ad0OgQqpzZhAtA*TF%D zy+Z3+8$&&b=*oamLXN01NpDTUDElq^pKRu#h3nM|Yb)0;Sx_W)_NIP2x>2x|D8JrCLSI-I^-@Dr_RwEMlzu`KMTYflpz zj@^5pQ4zXw#Ij(6MsPV@ZwOG0QWjhyh$iJ}O-X@vj^BDd>oI*{5w&gVvz(j){=cHW aNQ;fsI!S01Unu>EH16M+5^|aV literal 0 HcmV?d00001 diff --git a/MyQrCode/Resources/eyes/eye_barsHorizontal.png b/MyQrCode/Resources/eyes/eye_barsHorizontal.png new file mode 100644 index 0000000000000000000000000000000000000000..2ceca5ebe5b2f202b9b6edacf7d6730f158a4e99 GIT binary patch literal 1330 zcmZvcX;e}P6vrP3q7>2?rn#17lRL>V%TT9D#>}P6eM1~8ccE>-$x@)HTpQCCr_?!C z>WsOJp=hG=#sznqM5&qLJTNt)^igUm9UMDnwh!~+{_g#BKm5=A-RvX&UO22V761U8 z_d(C2YaRYnI%@z-+?)LY0JZGxxj%@7c>4lzERt?0Qq43sTBSKT<)%XM^? z&aKqPCAf>>LE@nktc``O)dKC1Q~CM87IBWAG%xa|Q{;>M6sKRGyRNOqtUt0kQ}+B$ zT&E)d2l(wdytH{`5NSlqLTLXFHW>&3EpmCDm*&V9ngnu*qmd~qKPL_~6=Y0p*a`DO zNtQJWmFoa6d&!mIRLT(45<{%8osaWpgt^FTE@#j@=!D`AtwOWA_w?{BsbcXoz|5;~ z?FTyou9p)`r_ZwA$2u{hTn2s?Wed;Wt-GMlD3)LxJavWkcN=cFv0f*k+5(dqqty@M zadirmBn4y#M9_2>c^o$%#sS-wSlzk=bm$x5X)oKSC6Vk^x_I|5$g2w+Q3zB>h5N8? zZa*AMOPia;1t!y(=SayTBYY%&I6N3bI@JE`$E1;@mJN(bld+>YZ6(LEeAGPNqK|^> zBjR-z_#|>kYMywJWX)~ky?mtL)TkQ4lg`2LYJvjy1Qj1Yh#76P=D2u&aod{1x60xN zqUH_(bCo*MB0%c%8MzoRN3JKXrS~^hK(BpDiYRP`AYm2|*oT`#eB~j{{=6*wz@_`| z*m^LS-X&hv!a+riu{9YLfZ({%AJ_2i5i(T0X*OogXyTi0t|T2)%0UX15kP(_L+_J= zms+j32yNDNNt=y%Mz&#;K3)o;=~pnFFVUR@yyjHF*tywU7SU}Q<*{QKDi3z2FH|9k zXo>@U*A^TNONUwXi}$pAJIh-8TW24}zHuExC>|NSk97mxuv-H+-n2!Y3 zZh-ITTGz47JZcIZ+QWS)fb8^CYoRcZM0XzCbmppI#$oc3nd4F^iy`P$MCbN!6T5ZI z3p0prviI&=anP7LN~*515qj1~>D8$Zjh5_A+EjEZclhA=R?YmRNj<&v!}O$eSp;wc zrI~e}7_d?fB;)4VEa3;Gr0l___z2T-XGq9 z<)k~%P`nB(!>G#wELY9Ikni@8{rcE@X%2d?7+s$YziwVwqnG3(UP?(Cz z8I!4$-bX3vlgqoP=DLAbstHR=>;YA5Dg)&&!d4VK?V$FLz@qTVlQ+wx5raqc&3P zLmeck6we`AMPmJqqDZA*_8u@3EBLCX@Yq=!oZ}YD3vl^#k*d!E+h>vg`RNt@<|h{a hk>g)Y{+jIWX96+Dsu4py8wH=9p*O|fv+he8=TEqwYI6Vp literal 0 HcmV?d00001 diff --git a/MyQrCode/Resources/eyes/eye_circle.png b/MyQrCode/Resources/eyes/eye_circle.png new file mode 100644 index 0000000000000000000000000000000000000000..d17330704a8d55a40efd4aa176718a909a8de1ec GIT binary patch literal 2633 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 literal 0 HcmV?d00001 diff --git a/MyQrCode/Resources/eyes/eye_cloud.png b/MyQrCode/Resources/eyes/eye_cloud.png new file mode 100644 index 0000000000000000000000000000000000000000..dc45501db99721ca19de4b275eba15a3d36084b4 GIT binary patch literal 2490 zcmV;r2}SmaP)SX2WY~Hl!;#_0aAY_#92t%b zM}{NAk>SX2WH>S$8IBA`h9kpA?%TNOKn{7lad2~B>_}kjlg?f1w?8_7eBL-P40WC^ z!>`P}n7$(Y`xo#Ho%2$GvF`cjels?w6JN7)%E|O4Zr#%N@m<~Q^zhWBW_M~Z{PrxD zz9Tln1AsSXI)Sm=%pcS_84tk0%jtVgUi2}(#LL8nv97@@*6_YlDUa%1z@FOR*zP#x zQF}jbi%}kRSpd6hhPN($e{qIayX3=J)lm{0YY&W-)svrdUJU-8{<^ke3?FnUfa55} z)TGN9@}s;SxE!e@XIA+C9zJX;op;`%w`%+lBJ}0hCQ+tk7f8i zvX%oZ!yCz3Hn9wEB5T>qGJIg9UD7$SmN!_2ktRz?gJ*d5NSkh%y-Au#Ckd-uo zYdANGETpEFZ5Vr83g8;l0B8%-w;O!JSQGfgl8*L}7SAf@$7%5d^|`B1jNz@7Zp1%S8mf?(;B%e{%FG41ZKh z;WWVr25K1kSPg)xewe^|mOh2ypHm@r!33IE`V@vQr$XEUIavC5hT~L-7MQ?EEPV>Y zB~*whFaejPPhq%<3Xy>vEPXt~2`a=qm_U-HPhog86=D_SVCmx-UPOh+LJpQbp5d%Z z;nc$jdRh7ig_%O(Y=jw1=jc-z?kcA+u7@G?R5J7t6x>B2R6P$pKHnd0Wx^xauY-{MT|2Gmp< z)YDp+FXp_*A3BGANcjrjo-$v}W9R1AEVHJk^>GvVC@Uo&tqp;iGV<}$kDy|V?w;1Y z+@4k=Y2v4{J+0T7J*|658_S>|E7sH63>7a|k~Ye_pXO2|KSq_CmxGgQ@6`VE0+mQEqRmk zX3|Qt(8~k=^=mz8WxderA^!z?a1?1|)SyrUfFBFOEu@iKq+(0_;1~K+q>WTRSo&n6 zhfh|KCaRtkjUF~}!=+0}6H8^or5mUK#|=Qm`xlcYE`A^2>SGul_&>$7QNd)=#$zaTOY&lK$5YD0#}emu7ECm{K&&4{ZR1;Y2^{!`Uoo89rAP5t5C9l zw6Z|AK7x`>Rg}-AuR={7X{C;#Pu6gpv=SFG%)ewxNh_rceX=*LO43RtN1y0p=}gkf znS6ah6OVe*%FTRzLQ~7XkXHV})F<%rATaS@=o5H7yp}X_tp#fjx06P;gRf7j#e*rN zjVS<2pFk5&!Z1UhK$}+Vl4j`RH{xY)S`2*xpIYP}OJn5M9?DNV3|xCyPg<#$%xSSc zI19c!u=Ei>QXv0&Xk<=HvH`%+M~qmIF)bd3K8E29vQ0c8!-`9$s#~~CD{x7xZwhsy zjd;nM)-=WhSMpN}>#@X{c>KTI$Fyy70dd9DE%t^1pG!q^TI~jW5Esp9%@vJ27?9JN zAsT8iAg481G`3_wPODiom}Wpu>mQ=gLj!VJJ4M5#2IRCp5R4B?=Co=UJ9G;M#0P4G za$3%_l1l&#$Z7o=1}yRr%xPUaXl3MqA8L6WN)iGKwIp*|muI17w7^n4$(+{Zy->4I zawCGmqPp`6wW zP_j&D(*xcf_ME9@3)K8nW?PGo;!-)S(!Uzpc);@?a=!cVLH?oX zA-}if@xI|WG+lY@{0qNN7d{q0`FsB{_T}~e{eXWg{snVi_SKcvE$1JLuc9qRe$IXs z@MipAJT}7v{9~CMfPbTSR2fvltfT*F?REF|u+4debYMgxHHVz0BV z?0)bKqpeKc&IyjGTQ_UmVXtdLF@|w}T+y)ejWL>Y+Uw%?qd3FpZBVylgJbIUYj5K) z*2Nk;Fbw;6VRkC4>8=6bC=fnxe+~u!000;W z`CE@-uPcLMgoTBLg@uKMg@uKMg@uKMg^z@Vg@uKM2Qj8nXt$d*FaQ7m07*qoM6N<$ Eg6xFHdH?_b literal 0 HcmV?d00001 diff --git a/MyQrCode/Resources/eyes/eye_cloudCircle.png b/MyQrCode/Resources/eyes/eye_cloudCircle.png new file mode 100644 index 0000000000000000000000000000000000000000..c47f96ece159220a56dd8addbf04e2b55505fcc2 GIT binary patch literal 3208 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 literal 0 HcmV?d00001 diff --git a/MyQrCode/Resources/eyes/eye_explode.png b/MyQrCode/Resources/eyes/eye_explode.png new file mode 100644 index 0000000000000000000000000000000000000000..8cd21cdf1415306202f2c8cd3b3d22767e8c58d2 GIT binary patch literal 1945 zcmZWqdpOezA0LLH8Rl{h8)7(kkIQkHvKHxNbD3r?i)2DbLYMU`UfD*XLLJpaC!9r> zO>&ndLm{1$$0RiRH95%C54jxDPQCB@yzhD5^Lf6P=leXL&+~l0|9rl=yD8pCbwhO+ z42C3=b_Raw(APwKDKH~qBLxOiWsrAz1_27P=TvQ&DMHy{Ee^QZ6Q$<9+L?M788YS6 z@qcj2%KjJJ6PIXi4I%%Tx)B;08n2h%x8MAA?)=1R^wt)oneXgNl0^}NJE9zD14zrg zT)(_YsbTnz`<%eqg?tdt{h~{b2U` z_=V8>R^C6bTki*0k5GsQ1FqCOFW|vxY9IDslguOQFH}pnSzJP6I&(s#*Ln1~bY+t~ zvO1H1sdv>ki`@~O=+<)-r%W?8Sz4o>)*!zekWaf1Z31f9>+SPb-owci;B^aBDKSCB zvH<{h_w;<68=kPPPY6;PU?*U5ZvCFDT0-Jhf^+G5IX#6!&<^7%D10FCK_)&dwHZu- zN9b^FXPMu5Ha2&BCQCBjdQ=ZX&5cp9O2w2s?u{=<;}8Bk9g~XgzF1@^$)9)?7Fl{0 zl_fc_-=(#jwb~_J)6c&banL~^eS6TTZ;@6U^l7M{@piPK2kaLBHcl>&gw)Pn!6gYu zjXw}{B*n;CY`KLSQg&JI5*G92;sK6(`DMzCs9xm)|KcamF+Rr6GX-I&W{s$P+5aRl zQ2P^N6yV{SO-83fbtFgLM6p%d?w!Hh_K@H&~yr z>HAH#8bsCaOKJLk!SQ82@7Rm|9{Zx8q#9y?Zqw!-rsF)VCZpWJ4H0sF`q>Maud^(6 z`Q5h_aC(F~r{o~`shD|OQkua+r#b$!j>FUw-FC6wRH^7D|D3hl{O0503Af4<&&5$! zmrF-fsyu8sG{#bYhX0iLOq?EuJh^A8YQX4u^q(W0J zl{XeTU>U)rBnU&_zB%eJ+oj5F)s7xn=pbf{1!E){Lpo}Uiu`?#MRs(#dZDQuP%UMQ z!e`fUq;L5Cf!Mw9L@u1n2@WzQs14!N7BGDBq=;JcdDnjDhf2102+gW|x${q2Q=(a_ zv5aki+iV85Jmn;4@Nbai&qmFbM6-;IGg*Mj&;yj{9AhIp>sDsNv=;=Y%W>Ki4*rc- z3Pvc#wf_i7iEvb=ftf-z2M>CsAcP3D6cb?~N@NGDkTR>l79t$aS#j4XLyY6o5tWAY z(-sQ*Si$Do+4%M~RhRdJu5_a|xIJf*I`JF3N#+YF0Vr*K3-%m z`WDLYL$)gHdvX;lk|Y~bp};nHx5%jc%$Sn>dtV3vJmQ^+ZEv0Qg|vXkz)oW}{;e-$ z3ZMsTtU%~z2x%R;cv9(i1ir($Ta>~ z&X5*Bv-})xsE{1^-k?Bxt}X2IP}jXHU$$|W@Ags=QqiZ4DXf*FXcO2!GFMt8-UN*Y z+qybYe(7hM6vnG8iIoD@N-hf}EfJ-euLt|q9k3T)@lP+-S4rG{G}1+Jdi^t1j-++(u#@pKYg~>!5ar>3+l}Qem^LmYQ}6 zcUX%jMqfBOZ|G5EcW25q1-ry>k&m?zQFky}7(^cdZogt?a)lrs!Y(TIX)4r58_$^r zxZio9IpObt&PBstu|}CO53qSRvR!Lq48n(BSTMI-h}a%u;5YMd$1}U!xV69u=`2dKh;^#Eq+WdeuF_;C1Ufub%c*~hd)jP9aKmaAHY&cUhZq|p45LGw zq#9(S$aUDtby(#U!)Wgx6LNt%9WEYW{4a+8!uv}4uSi9XIyO*3x{lGU{`zytKT>v9 I?_jY11h(m*0RR91 literal 0 HcmV?d00001 diff --git a/MyQrCode/Resources/eyes/eye_eye.png b/MyQrCode/Resources/eyes/eye_eye.png new file mode 100644 index 0000000000000000000000000000000000000000..a12c3c1949ae3f1d12663a15dcdc5b6b56b3dec7 GIT binary patch literal 2268 zcmZ8jc|6mP8y{`Vnzl4YD_1Hra-`#%+mOgHg|xz$JJPqDUm}|;*E*bq4MjO}e31(C zNy*oJESVfDg)n3}=9usLy?%dv|9IZ-=l#5%=lSz_KX>sq=Hf6k3r&jlV}~;iIbMB-HgWJ( z^oIyxQ$4f`v3Ow#rNd0e#DZ9-^6G4vlyaqyc{ozhuql|B3d=6HGZOR5ysNcp;97{J zgO>9nyl?irdYQYqDH09M$%*I|m_GO=4 zSY^mJZ6S-;QNvZ`HT4CYD%EI#h-guXI z9=J7>cQ8~{W@+|Cb0{Xv=Jj^n6~KsfU+X0~#w;QKl_Wgf!=*tIuBNZgan!7uN+JO* ztIBB*lEr4Zps{<`2Xgf~wfPFrk~WAVss!Nr02qypyJ7dpUwNsxVmozB1#_o;cZ8rD&MtMxRxpEiMdG2KZ zE$ZV+o-HK0_D!=eWH!ZjsdSR^H{2~`W*Ce5hJ#Z&(IU6wrw}L874;SgqvWzT#ZL6+ z+>g+Tpg$Y|*Qn0IZy}21lD3ok8gJb*JMhBfoI{|y#MWTT)w+UisCT7&0{i>e&KEsi z)&TVBNf99DG?R#(R0J=2F@bA47S;=nim^KLu@N(3EpJ4B#PT8A4kSu}{gMw2Z)%JGxSR+&pFfOH|52hfk*?4Z zG6x))7@&_TLvOslxm2i@+L2)t&|UkH4Y}kqyb_1k4LG?joH`dXG9WEQdF*Svn|XYd z9L*Vw--XA9d#N@|i4wG$#4HokAeT}GA5^34rBYd93*JI5-*vQgPpfG-SJ8ub@gr8= z3zEC<#SQFL1sI-Ay!n2=$R`^U2$E# zHSANJoaNk`ajld$a;SmDRMDL@#c#dEdoj09^&*esU-{{*n?HnSIw#|Yy!QKJ#p84a zfoMZjosj;*=&VC@fwmo?g}CvlJqd zJ(@%g$n&_PgGtGTH=ESmO~t%z6Dt)r`4S7To$VvGAW6&bNu?aJe_f#Z`l9_K{7PxE z^0Rcx+r(nm5afVXnA1jWA+RZzi22y&lDD$$&8PNl@kFunt&N-_G6PnK)&}-tJqnC7 zVILHh$I)VZX-{5VA2Fc0U4!}33Y^t_VO81Z&&(PYERkRhUVJ+5j3zvpuyaJ%HQi3B`IkoFuyIy{0#ox9JFdsM!rf{ttNoI~(aYK(of&)uhyXPWtJS9}O^_LW-j#^+0xkU6jpaShG<7`#-iUT$!@DlxLqu3@ap2!E<|>#qG?u3^GrE zCz4yGse~j#kfI79(9FSKSkz&vi(BxO}2N_zCAi83MgoH*s zHS7fV6Yd0>kr0L^A5fT0o*)s#fdJ&m4~xc)@$60{CynpWd3_sLQ?%suGpq*XbJrBm zsr=yQe4-G6*kS`_ko1^TBLH zl(R_2+0NF4E>SKty+*C2Z1h#}PHNT&E68RpOvM=>CDR|Ei;j>~bOAl^Q|rMH^LIIj zC`aL^yK29J{2|)A>ZAyL!V!Q*Caxl(ZKcIs)7B*5OE9;HP$6Pl8AGt>+0t}*3^bBK zv~OM1EA{)kI8gk}ytbnV!m;e{m|B|#5I7wC$=y9G$Xg|f+np5iTmixofDiVZgB##u`8Vixfnub zCE*9MBDt#X%E6lvdwZr7x#z$7gSpm{xY7fs7$SW*P1*}1r#Ck@r1eJ-Q#Vv_WoIg* zGfGy7E?lI`FR-|M$?GSe3F$H(QuegA?BhGs5{PeFRCi7u+aYT2!-2X{{m zVn2|1UX>)^*A@MjbS{bkwoHWBdQ%OLsK@+or zxNKJZPJpZev+IzDB=e3@*iqM)C1bFo6Rs89gRp$z&^v<%=(P>Q_V7y_h%(!Q5VK~#$*JZj+6YKz1xrxUy{8C j)>RM-F_I884GZl+a$`{A@Rdhvzuy)MGaJ(vI3oF9vlCn` literal 0 HcmV?d00001 diff --git a/MyQrCode/Resources/eyes/eye_fireball.png b/MyQrCode/Resources/eyes/eye_fireball.png new file mode 100644 index 0000000000000000000000000000000000000000..2e3e1856046942f7f412d18f82e96d97ceaba975 GIT binary patch literal 2035 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 literal 0 HcmV?d00001 diff --git a/MyQrCode/Resources/eyes/eye_leaf.png b/MyQrCode/Resources/eyes/eye_leaf.png new file mode 100644 index 0000000000000000000000000000000000000000..019535ac9fd13ce6131b7cc687e397095b77bba9 GIT binary patch literal 1032 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 literal 0 HcmV?d00001 diff --git a/MyQrCode/Resources/eyes/eye_roundedOuter.png b/MyQrCode/Resources/eyes/eye_roundedOuter.png new file mode 100644 index 0000000000000000000000000000000000000000..b071fb202ffce4350bd7e090d66ef9b68526cf33 GIT binary patch literal 744 zcmeAS@N?(olHy`uVBq!ia0vp^A3&G`NH9p-ZS!MbU|R3#;uuoF_~ufh`Pdgln*yxt&2D$^5dcGvIG6zGnmSO0`GE@xN918KlmOL z+hN(OS+KrG_k-ZJ1K)*@9aw#XDgI*l$wRm9Jv`}ZHm8h@xlZp={L;U_Ci860F?eA7 zE3@c(*uSL=cjl_@U%5qh5lf9AgDbi%!a{D^RKINELL6$_xguWJr?LEi z$PeLd2d3X(`ajcnIW;p~Ke+w9d@85$HA4!jcT z3NkTjlF#4HCM*U6b!s}K0-O08P{D`fLW~M_Er0RbqxIw b(+ZfEtdO7c^SVO>C<%MI`njxgN@xNAMGHLW literal 0 HcmV?d00001 diff --git a/MyQrCode/Resources/eyes/eye_shield.png b/MyQrCode/Resources/eyes/eye_shield.png new file mode 100644 index 0000000000000000000000000000000000000000..2cfd051b9d643c16d3f5313f40dab91e1e34e170 GIT binary patch literal 1393 zcmai!eLT|%9LIk<8#b*ewTTONC^gxxhjPud8lDrG8Mae-RpI|`s@DqJiNaDe!t)M1%HAU9A*Rq0055n z_6Yo(sxQ+0Y=EFLck4tS4!#6-}{2*_iY{=IbG?-1|QE?!)BZTsI=k=8|2NPwLd z(%Z~DnoRD+3aNg2%|NWAWYW_g=k^N>oy)AaJ93+vuv9!0w+I0kI)L!wh-Ovua!C_& z!yb^JbkrJ`BOQLo7O;UY_8U`rejOEDS^0gjI={QJa!z@J_&{4`aRc6NtWV0B=TSR- zy_*YiI>EyHtHXRgOV8&gl64KS2XgZdQMhd-w1njzmn;wE+g3mhX9ia6kt=lbImLX2 zls72RR!g8Kc5g;AP^Hh)=_=d?4h|z^+4EkM$E%|F@1NVLgY<|o%O^KA=)OkIq{pqZ zLUo2h{M;I$*X6W~Qd)|0K+?d-0NOcn!$L+3k2T31(7k?3QKJ z0fCPmG$UG`)qfP%F@|R*2fWf+ z3a39}1?Cu+!Z}93QeWXJ({-2?(e)~&3#%N}x!-&`EP~Wv(GOZ@MWj`3X9*y5Jab?l-SrQG&q~Gp^GV zZlJD#sfqC@D4OVsY+Oh+5cHGg!LqUgEOyz`F*8B_BKTY$I(sXwavUSMy;Ra{EGf%< zec3Ab!yT=VyVKB5sB@%u@rU!fH0#JF#XB5cm`&ew5dtegHpK~=0EzBqqK?(1|y=&abOZZO{cj6Q24 z=|LbCQQ?p@Q|3+2rh2H&n${?D2&!drMHQ~8O_BTBzu`M6j2s4X>rVJNLTm`U*>cV- z<6fP7|IcB$j5|@PTVkP>{LXZ+I{59o(5V)hs=B6!H5T{v`2WAThP`4(&(f1S@_d$; zv99`)27t?g{Ih7-oa#IOiI(@0@yL+`{WRj81m@Qn&cEGfQ#80q(Z977) zWhr#cs3wl%(;tXvX`-{mRQ?02P*ely+Ly}i;B=2za2h*~hMZTY3ObnIbO2aLv8?Ceb zPX#E`U8~)yx!v5B1w%m&ho;&>9J;%>$2!xuusG`?d*0gtV|Di>!j}%%AalH zo;Zs{(Y|ZrkNq1!%mG8wBK)zoJhP@lj(@!jJ>s)G{NjUb6^~2Rd*$)(TAbE>1FioU Zra?SpH|9J$ngssBQap~}QRPla{|DhKiwyt( literal 0 HcmV?d00001 diff --git a/MyQrCode/Resources/eyes/eye_square.png b/MyQrCode/Resources/eyes/eye_square.png new file mode 100644 index 0000000000000000000000000000000000000000..09c39bc46e323ff50674609c3c39284d8347e0c8 GIT binary patch literal 239 zcmeAS@N?(olHy`uVBq!ia0vp^A3&Ie8AzU~{<08A@dx;XxW0b<`r^flbLPwe3S?wt z{QP+PC6G1S)5S5Qg7NJgR>lSg0fvL89hg)YFE#v|>(TK0e@-K3fzTus&q*bl7VX=Z z#hCX?`n6HR!2|;d9=7I#2_FLH=h?877w%#Mb3vlddB00D1EruUuu>oPZn$a*m-+Lr oaJM~EIzp5AehItjKs!}@8|M40+VeEI66j0@Pgg&ebxsLQ05w!sxc~qF literal 0 HcmV?d00001 diff --git a/MyQrCode/Resources/eyes/eye_squarePeg.png b/MyQrCode/Resources/eyes/eye_squarePeg.png new file mode 100644 index 0000000000000000000000000000000000000000..fc0a12348a7b182f5b66015d6109b8195ec2e00f GIT binary patch literal 1812 zcmV+v2kZEWP)?z(YzVYeD0SofmrXo zng1Vjj1Ts~w)4Sm@xeaW2m4?j?1O!<5B9-6*a!PyAMAsDumgOs5B9;GMs2UMV}QzD zt^e3*h&Qit(^yIEK!+l>`mgmsE> zf{#EJb3X-ztK8djQ?4Q|0wEy>^#ELD;W&cRYS$>0nu zm5~eX1h7=lkqZ7NtksYTuEAP0so*_WYfmb;f&rNP`2MGb_43oLt*7PnLVo_%WB~Ol zQo%b=>Z70hX1m$pH=MrSUY<=ushy;Q$3FSI(Idrr&GOv%SqYx{?8Q62hj;bIQ}zdk zi!XY7Z@q)X(CXl;pSSse+8bA`4gUBGN~zwlGI-_%rM9`lFD@! z%nkl62clqTa8TlaYz~_kJhH=qc|KxZ@W>Y&pz5e;!Qa{CKvhS~3Lg3^2kiNG1ry zp#WbChR>Z3(-$*WZp`E!6gKvc`0aL02>u1dy0s^_Q}_U>+fQm;iaks|_r`B z!o;H%Mc!UcJoqIAj_wDL6wDt{;AN0-@UJLP8bu7FB?{z|4W9TnBYm}im=?Zbr1qsm zga0JxokeW3g5qaM2H)&4(gGA%V5Hv71cR%LR2t}kx_WZKKVqb#Q7AEb#7K7&3qD|^ z`%q+_kzOSge20-*0Tc;ZjC3cV;J-7{BPjETk*diAf4|2l-3cf&(PgBoi3IPx{wW0>K&b~5nA04*uIaK>(ir?R3JpQ2 zAqvfF4E{BR0w@(wD6cWNKp`kbp@PQX-SUd&Prh@-Ok4 z&>6fZHSMx%FXCsD|I{+8H8|aK>|+|5j(sjgS)K^Y)X(^JT7O|0&-7o3-$atZm)edEJwRUfSc^}QY;fS(;1XPZ>)2=-Jfv8+wqo<} zA%Wc(fQ9UIk(k*Zt6c!ANX zTjQ32k>_p=)CPt(of?_mS8!@5e&0gJt+fZh^*3%UwgA$*POUEKd-&F+EM$P z779r0000Eakt!T9#pLcsD=BQ2i^efVDNPHb6Mw< G&;$S)+CC}( literal 0 HcmV?d00001 diff --git a/MyQrCode/Views/CreateQRCodeView.swift b/MyQrCode/Views/CreateQRCodeView.swift index ba507a5..2addfb4 100644 --- a/MyQrCode/Views/CreateQRCodeView.swift +++ b/MyQrCode/Views/CreateQRCodeView.swift @@ -73,6 +73,7 @@ struct CreateQRCodeView: View { // 通用状态 @State private var showingAlert = false @State private var alertMessage = "" + @State private var navigateToStyleView = false var body: some View { VStack(spacing: 0) { @@ -82,14 +83,26 @@ struct CreateQRCodeView: View { .navigationBarTitleDisplayMode(.inline) .toolbar { ToolbarItem(placement: .navigationBarTrailing) { - Button("创建") { createQRCode() } - .disabled(!canCreateQRCode()) - .font(.system(size: 16, weight: .semibold)) + Button("创建") { + if canCreateQRCode() { + navigateToStyleView = true + } + } + .disabled(!canCreateQRCode()) + .font(.system(size: 16, weight: .semibold)) } } .alert("提示", isPresented: $showingAlert) { Button("确定") { } } message: { Text(alertMessage) } + .background( + NavigationLink( + destination: QRCodeStyleView(qrCodeContent: generateQRCodeContent()), + isActive: $navigateToStyleView + ) { + EmptyView() + } + ) .onAppear { setupInitialFocus() } @@ -632,6 +645,129 @@ struct CreateQRCodeView: View { } } + // MARK: - 生成二维码内容 + private func generateQRCodeContent() -> String { + switch selectedQRCodeType { + case .mail: + var mailContent = "mailto:\(emailAddress)" + if !emailSubject.isEmpty || !emailBody.isEmpty || !emailCc.isEmpty || !emailBcc.isEmpty { + mailContent += "?" + var params: [String] = [] + if !emailSubject.isEmpty { + params.append("subject=\(emailSubject.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "")") + } + if !emailBody.isEmpty { + params.append("body=\(emailBody.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "")") + } + if !emailCc.isEmpty { + params.append("cc=\(emailCc.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "")") + } + if !emailBcc.isEmpty { + params.append("bcc=\(emailBcc.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) ?? "")") + } + mailContent += params.joined(separator: "&") + } + return mailContent + case .wifi: + var wifiContent = "WIFI:" + wifiContent += "S:\(wifiSSID);" + wifiContent += "T:\(wifiEncryptionType.rawValue.uppercased());" + if !wifiPassword.isEmpty { + wifiContent += "P:\(wifiPassword);" + } + wifiContent += ";" + return wifiContent + case .vcard: + var vcardContent = "BEGIN:VCARD\nVERSION:3.0\n" + if !contactFirstName.isEmpty || !contactLastName.isEmpty { + vcardContent += "N:\(contactLastName);\(contactFirstName);;;\n" + vcardContent += "FN:\(contactFirstName) \(contactLastName)\n" + } + if !contactPhone.isEmpty { + vcardContent += "TEL;TYPE=WORK,PREF:\(contactPhone)\n" + } + if !contactEmail.isEmpty { + vcardContent += "EMAIL:\(contactEmail)\n" + } + if !contactCompany.isEmpty { + vcardContent += "ORG:\(contactCompany)\n" + } + if !contactTitle.isEmpty { + vcardContent += "TITLE:\(contactTitle)\n" + } + if !contactAddress.isEmpty { + vcardContent += "ADR;TYPE=WORK:;;\(contactAddress);;;;\n" + } + if !contactWebsite.isEmpty { + vcardContent += "URL:\(contactWebsite)\n" + } + vcardContent += "END:VCARD" + return vcardContent + case .mecard: + var mecardContent = "MECARD:" + if !contactFirstName.isEmpty || !contactLastName.isEmpty { + mecardContent += "N:\(contactLastName),\(contactFirstName);" + } + if !contactNickname.isEmpty { + mecardContent += "NICKNAME:\(contactNickname);" + } + if !contactPhone.isEmpty { + mecardContent += "TEL:\(contactPhone);" + } + if !contactEmail.isEmpty { + mecardContent += "EMAIL:\(contactEmail);" + } + if !contactCompany.isEmpty { + mecardContent += "ORG:\(contactCompany);" + } + if !contactTitle.isEmpty { + mecardContent += "TITLE:\(contactTitle);" + } + if !contactAddress.isEmpty { + mecardContent += "ADR:,,\(contactAddress);" + } + if !contactWebsite.isEmpty { + mecardContent += "URL:\(contactWebsite);" + } + if !contactNote.isEmpty { + mecardContent += "NOTE:\(contactNote);" + } + mecardContent += ";" + return mecardContent + case .location: + return "geo:\(locationLatitude),\(locationLongitude)" + case .calendar: + let dateFormatter = DateFormatter() + dateFormatter.dateFormat = "yyyyMMdd'T'HHmmss'Z'" + dateFormatter.timeZone = TimeZone(abbreviation: "UTC") + let startDateString = dateFormatter.string(from: startDate) + let endDateString = dateFormatter.string(from: endDate) + + var icalContent = "BEGIN:VEVENT\n" + icalContent += "SUMMARY:\(eventTitle)\n" + if !eventDescription.isEmpty { + icalContent += "DESCRIPTION:\(eventDescription)\n" + } + if !eventLocation.isEmpty { + icalContent += "LOCATION:\(eventLocation)\n" + } + icalContent += "DTSTART:\(startDateString)\n" + icalContent += "DTEND:\(endDateString)\n" + icalContent += "END:VEVENT" + return icalContent + case .instagram, .facebook, .spotify, .twitter, .snapchat, .tiktok, .whatsapp, .viber: + return generateSocialMediaContent() + case .phone: + return "tel:\(phoneNumber)" + case .sms: + return "SMSTO:\(phoneNumber)" + case .url: + return urlString + default: + return content + } + } + // MARK: - Facebook ID提取辅助函数 private func extractFacebookId(from input: String) -> String { // 如果输入的是Facebook链接,提取用户名/ID diff --git a/MyQrCode/Views/QRCodeStyleView.swift b/MyQrCode/Views/QRCodeStyleView.swift new file mode 100644 index 0000000..0c1b8d6 --- /dev/null +++ b/MyQrCode/Views/QRCodeStyleView.swift @@ -0,0 +1,396 @@ +import SwiftUI +import QRCode +import CoreData + +// MARK: - 自定义二维码样式界面 +struct QRCodeStyleView: View { + let qrCodeContent: String + @Environment(\.dismiss) private var dismiss + @StateObject private var coreDataManager = CoreDataManager.shared + + // 颜色选择 + @State private var selectedForegroundColor: QRCodeColor = .black + @State private var selectedBackgroundColor: QRCodeColor = .white + + // 点类型选择 + @State private var selectedDotType: QRCodeDotType = .square + + // 眼睛类型选择 + @State private var selectedEyeType: QRCodeEyeType = .square + + // Logo选择 + @State private var selectedLogo: QRCodeLogo? = nil + + // 生成的二维码图片 + @State private var qrCodeImage: UIImage? + @State private var isLoading = false + + // 创建QRCode文档 + private func createQRCodeDocument() -> QRCode.Document { + let d = try! QRCode.Document(engine: QRCodeEngineExternal()) + + // 使用传入的二维码内容 + d.utf8String = qrCodeContent + + // 设置背景色 + d.design.backgroundColor(selectedBackgroundColor.cgColor) + + // 设置眼睛样式 + d.design.style.eye = QRCode.FillStyle.Solid(selectedForegroundColor.cgColor) + d.design.style.eyeBackground = selectedBackgroundColor.cgColor + + // 设置点样式 + d.design.shape.onPixels = selectedDotType.pixelShape + d.design.style.onPixels = QRCode.FillStyle.Solid(selectedForegroundColor.cgColor) + d.design.style.onPixelsBackground = selectedBackgroundColor.cgColor + + d.design.shape.offPixels = selectedDotType.pixelShape + d.design.style.offPixels = QRCode.FillStyle.Solid(selectedBackgroundColor.cgColor) + d.design.style.offPixelsBackground = selectedBackgroundColor.cgColor + + // 设置眼睛形状 + d.design.shape.eye = selectedEyeType.eyeShape + + // 如果有选择的Logo,设置背景图片 + if let selectedLogo = selectedLogo { + // 这里可以添加Logo图片设置 + // d.design.style.background = QRCode.FillStyle.Image(selectedLogo.image) + } + + return d + } + + var body: some View { + VStack(spacing: 0) { + // 二维码预览区域 + qrCodePreviewSection + + // 样式选择区域 + styleSelectionSection + } + .navigationTitle("自定义样式") + .navigationBarTitleDisplayMode(.inline) + .toolbar { + ToolbarItem(placement: .navigationBarTrailing) { + Button("保存") { + saveQRCode() + } + .font(.system(size: 16, weight: .semibold)) + } + } + .onAppear { + } + } + + // MARK: - 二维码预览区域 + private var qrCodePreviewSection: some View { + VStack(spacing: 16) { + QRCodeDocumentUIView(document: createQRCodeDocument()) + .frame(width: 300, height: 300) + } + .padding() + .background(Color(.systemBackground)) + } + + // MARK: - 样式选择区域 + private var styleSelectionSection: some View { + ScrollView { + VStack(spacing: 24) { + // 前景色选择 + colorSelectionSection( + title: "前景色", + colors: QRCodeColor.foregroundColors, + selectedColor: $selectedForegroundColor + ) + + // 背景色选择 + colorSelectionSection( + title: "背景色", + colors: QRCodeColor.backgroundColors, + selectedColor: $selectedBackgroundColor + ) + + // 点类型选择 + dotTypeSelectionSection + + // 眼睛类型选择 + eyeTypeSelectionSection + + // Logo选择 + logoSelectionSection + } + .padding() + } + .background(Color(.systemGroupedBackground)) + } + + // MARK: - 颜色选择区域 + private func colorSelectionSection( + title: String, + colors: [QRCodeColor], + selectedColor: Binding + ) -> some View { + VStack(alignment: .leading, spacing: 12) { + Text(title) + .font(.headline) + .foregroundColor(.primary) + + LazyVGrid(columns: Array(repeating: GridItem(.flexible()), count: 6), spacing: 12) { + ForEach(colors, id: \.self) { color in + Button(action: { + selectedColor.wrappedValue = color + }) { + RoundedRectangle(cornerRadius: 8) + .fill(color.color) + .frame(height: 40) + .overlay( + RoundedRectangle(cornerRadius: 8) + .stroke(selectedColor.wrappedValue == color ? Color.blue : Color.clear, lineWidth: 3) + ) + } + } + } + } + } + + // MARK: - 点类型选择区域 + private var dotTypeSelectionSection: some View { + VStack(alignment: .leading, spacing: 12) { + Text("点类型") + .font(.headline) + .foregroundColor(.primary) + + ScrollView(.horizontal, showsIndicators: false) { + HStack(spacing: 12) { + ForEach(QRCodeDotType.allCases, id: \.self) { dotType in + Button(action: { + selectedDotType = dotType + }) { + VStack(spacing: 8) { + if let image = loadImage(named: dotType.thumbnailName) { + Image(uiImage: image) + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 40, height: 40) + .background(Color.white) + .cornerRadius(8) + } else { + RoundedRectangle(cornerRadius: 8) + .fill(Color.gray.opacity(0.3)) + .frame(width: 40, height: 40) + .overlay( + Text("?") + .font(.caption) + .foregroundColor(.secondary) + ) + } + + Text(dotType.displayName) + .font(.caption) + .foregroundColor(.primary) + } + .padding(8) + .background( + RoundedRectangle(cornerRadius: 12) + .fill(selectedDotType == dotType ? Color.blue.opacity(0.1) : Color.clear) + .overlay( + RoundedRectangle(cornerRadius: 12) + .stroke(selectedDotType == dotType ? Color.blue : Color.clear, lineWidth: 2) + ) + ) + } + } + } + .padding(.horizontal) + } + } + } + + // MARK: - 眼睛类型选择区域 + private var eyeTypeSelectionSection: some View { + VStack(alignment: .leading, spacing: 12) { + Text("眼睛类型") + .font(.headline) + .foregroundColor(.primary) + + ScrollView(.horizontal, showsIndicators: false) { + HStack(spacing: 12) { + ForEach(QRCodeEyeType.allCases, id: \.self) { eyeType in + Button(action: { + selectedEyeType = eyeType + }) { + VStack(spacing: 8) { + if let image = loadImage(named: eyeType.thumbnailName) { + Image(uiImage: image) + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 40, height: 40) + .background(Color.white) + .cornerRadius(8) + } else { + RoundedRectangle(cornerRadius: 8) + .fill(Color.gray.opacity(0.3)) + .frame(width: 40, height: 40) + .overlay( + Text("?") + .font(.caption) + .foregroundColor(.secondary) + ) + } + + Text(eyeType.displayName) + .font(.caption) + .foregroundColor(.primary) + } + .padding(8) + .background( + RoundedRectangle(cornerRadius: 12) + .fill(selectedEyeType == eyeType ? Color.blue.opacity(0.1) : Color.clear) + .overlay( + RoundedRectangle(cornerRadius: 12) + .stroke(selectedEyeType == eyeType ? Color.blue : Color.clear, lineWidth: 2) + ) + ) + } + } + } + .padding(.horizontal) + } + } + } + + // MARK: - Logo选择区域 + private var logoSelectionSection: some View { + VStack(alignment: .leading, spacing: 12) { + Text("Logo") + .font(.headline) + .foregroundColor(.primary) + + ScrollView(.horizontal, showsIndicators: false) { + HStack(spacing: 12) { + // 无Logo选项 + Button(action: { + selectedLogo = nil + }) { + VStack(spacing: 8) { + RoundedRectangle(cornerRadius: 8) + .fill(Color.gray.opacity(0.3)) + .frame(width: 40, height: 40) + .overlay( + Text("无") + .font(.caption) + .foregroundColor(.secondary) + ) + + Text("无Logo") + .font(.caption) + .foregroundColor(.primary) + } + .padding(8) + .background( + RoundedRectangle(cornerRadius: 12) + .fill(selectedLogo == nil ? Color.blue.opacity(0.1) : Color.clear) + .overlay( + RoundedRectangle(cornerRadius: 12) + .stroke(selectedLogo == nil ? Color.blue : Color.clear, lineWidth: 2) + ) + ) + } + + // Logo选项 + ForEach(QRCodeLogo.allCases, id: \.self) { logo in + Button(action: { + selectedLogo = logo + }) { + VStack(spacing: 8) { + if let image = loadImage(named: logo.thumbnailName) { + Image(uiImage: image) + .resizable() + .aspectRatio(contentMode: .fit) + .frame(width: 40, height: 40) + .background(Color.white) + .cornerRadius(8) + } else { + RoundedRectangle(cornerRadius: 8) + .fill(Color.gray.opacity(0.3)) + .frame(width: 40, height: 40) + .overlay( + Text("?") + .font(.caption) + .foregroundColor(.secondary) + ) + } + + Text(logo.displayName) + .font(.caption) + .foregroundColor(.primary) + } + .padding(8) + .background( + RoundedRectangle(cornerRadius: 12) + .fill(selectedLogo == logo ? Color.blue.opacity(0.1) : Color.clear) + .overlay( + RoundedRectangle(cornerRadius: 12) + .stroke(selectedLogo == logo ? Color.blue : Color.clear, lineWidth: 2) + ) + ) + } + } + } + .padding(.horizontal) + } + } + } + + // MARK: - 保存二维码 + private func saveQRCode() { + guard let qrCodeImage = qrCodeImage else { return } + + // 保存到相册 + UIImageWriteToSavedPhotosAlbum(qrCodeImage, nil, nil, nil) + + // 保存到历史记录 + saveToHistory() + + dismiss() + } + + // MARK: - 保存到历史记录 + private func saveToHistory() { + let context = coreDataManager.container.viewContext + let historyItem = HistoryItem(context: context) + historyItem.id = UUID() + historyItem.dataType = DataType.qrcode.rawValue + historyItem.dataSource = DataSource.created.rawValue + historyItem.createdAt = Date() + historyItem.isFavorite = false + historyItem.qrCodeType = "custom" + historyItem.content = qrCodeContent + + do { + try context.save() + } catch { + print("保存到历史记录失败:\(error.localizedDescription)") + } + } + + // MARK: - 辅助函数 + private func loadImage(named name: String) -> UIImage? { + // 尝试从Bundle中加载图片 + if let path = Bundle.main.path(forResource: name, ofType: "png", inDirectory: "Resources/dots") { + return UIImage(contentsOfFile: path) + } + if let path = Bundle.main.path(forResource: name, ofType: "png", inDirectory: "Resources/eyes") { + return UIImage(contentsOfFile: path) + } + if let path = Bundle.main.path(forResource: name, ofType: "png", inDirectory: "Resources/logos") { + return UIImage(contentsOfFile: path) + } + return nil + } +} + +// MARK: - 预览 +#Preview { + QRCodeStyleView(qrCodeContent: "https://www.example.com") +} diff --git a/docs/CREATE_QRCODE_TO_STYLE_VIEW_README.md b/docs/CREATE_QRCODE_TO_STYLE_VIEW_README.md new file mode 100644 index 0000000..896fad7 --- /dev/null +++ b/docs/CREATE_QRCODE_TO_STYLE_VIEW_README.md @@ -0,0 +1,240 @@ +# 创建二维码界面跳转到自定义样式界面 + +## 概述 + +本文档描述了如何从创建二维码界面跳转到自定义样式界面的实现。用户现在可以在创建二维码时选择自定义样式,而不是直接生成标准二维码。 + +## 功能流程 + +### 1. 用户操作流程 +``` +创建二维码界面 → 填写内容 → 点击"创建"按钮 → 跳转到自定义样式界面 → 选择样式 → 保存二维码 +``` + +### 2. 技术实现 + +#### **CreateQRCodeView.swift 修改** + +**添加状态变量**: +```swift +@State private var navigateToStyleView = false +``` + +**修改创建按钮行为**: +```swift +Button("创建") { + if canCreateQRCode() { + navigateToStyleView = true + } +} +``` + +**添加NavigationLink导航**: +```swift +.background( + NavigationLink( + destination: QRCodeStyleView(qrCodeContent: generateQRCodeContent()), + isActive: $navigateToStyleView + ) { + EmptyView() + } +) +``` + +**新增二维码内容生成方法**: +```swift +private func generateQRCodeContent() -> String { + switch selectedQRCodeType { + case .mail: + // 生成邮件格式内容 + case .wifi: + // 生成WiFi格式内容 + case .vcard: + // 生成vCard格式内容 + case .mecard: + // 生成MeCard格式内容 + // ... 其他类型 + } +} +``` + +#### **QRCodeStyleView.swift 修改** + +**添加CoreData支持**: +```swift +import CoreData +@StateObject private var coreDataManager = CoreDataManager.shared +``` + +**移除NavigationView包装**: +```swift +// 移除了NavigationView包装,因为现在通过NavigationLink导航 +var body: some View { + VStack(spacing: 0) { + // 内容... + } + .navigationTitle("自定义样式") + .navigationBarTitleDisplayMode(.inline) + // ... +} +``` + +**修改保存方法**: +```swift +private func saveQRCode() { + guard let qrCodeImage = qrCodeImage else { return } + + // 保存到相册 + UIImageWriteToSavedPhotosAlbum(qrCodeImage, nil, nil, nil) + + // 保存到历史记录 + saveToHistory() + + dismiss() +} +``` + +**新增历史记录保存方法**: +```swift +private func saveToHistory() { + let context = coreDataManager.container.viewContext + let historyItem = HistoryItem(context: context) + historyItem.id = UUID() + historyItem.dataType = DataType.qrcode.rawValue + historyItem.dataSource = DataSource.created.rawValue + historyItem.createdAt = Date() + historyItem.isFavorite = false + historyItem.qrCodeType = "custom" + historyItem.content = qrCodeContent + + do { + try context.save() + } catch { + print("保存到历史记录失败:\(error.localizedDescription)") + } +} +``` + +## 支持的二维码类型 + +### 1. 邮件 (mailto:) +- 支持收件人、主题、正文、抄送、密送 +- 格式:`mailto:email?subject=xxx&body=xxx&cc=xxx&bcc=xxx` + +### 2. WiFi +- 支持SSID、密码、加密类型 +- 格式:`WIFI:S:SSID;T:ENCRYPTION;P:PASSWORD;;` + +### 3. vCard (3.0版本) +- 支持姓名、电话、邮箱、公司、职位、地址、网站 +- 格式:标准vCard 3.0格式 + +### 4. MeCard +- 支持姓名、昵称、电话、邮箱、公司、职位、地址、网站、备注 +- 格式:`MECARD:N:LastName,FirstName;NICKNAME:xxx;TEL:xxx;...;` + +### 5. 位置 +- 支持经纬度 +- 格式:`geo:latitude,longitude` + +### 6. 日历事件 +- 支持事件标题、描述、位置、开始时间、结束时间 +- 格式:标准iCalendar格式 + +### 7. 社交媒体 +- **Instagram**: `instagram://user?username=xxx` +- **Facebook**: `fb://profile/xxx` +- **Spotify**: `spotify:search:artist;song` +- **X (Twitter)**: `twitter://user?screen_name=xxx` +- **WhatsApp**: `whatsapp://send?phone=xxx` +- **Viber**: `viber://add?number=xxx` +- **TikTok**: `https://www.tiktok.com/@xxx` +- **Snapchat**: `https://snapchat.com/add/xxx` + +### 8. 电话和短信 +- **电话**: `tel:xxx` +- **短信**: `SMSTO:xxx` + +### 9. URL +- 直接使用输入的URL + +## 自定义样式功能 + +### 1. 颜色选择 +- **前景色**: 20种颜色(8种纯色 + 12种渐变色) +- **背景色**: 10种浅色系 + +### 2. 点类型选择 +- 40多种不同的点类型 +- 包括基础形状、特殊形状、抽象形状、动态形状 + +### 3. 眼睛类型选择 +- 40多种不同的眼睛类型 +- 包括基础形状、特殊形状、动态形状 + +### 4. Logo选择 +- 15种不同的Logo +- 包括社交媒体、通讯工具、其他服务 + +## 用户体验改进 + +### 1. 流程优化 +- 用户填写内容后,点击"创建"按钮 +- 通过NavigationLink导航到自定义样式界面 +- 可以预览和调整二维码样式 +- 最终保存到相册和历史记录 + +### 2. 数据持久化 +- 自定义样式生成的二维码会保存到历史记录 +- 类型标记为"custom" +- 可以在历史记录中查看和管理 + +### 3. 错误处理 +- 输入验证确保内容有效 +- 保存失败时的错误提示 +- 网络和权限问题的处理 + +## 技术要点 + +### 1. 状态管理 +- 使用`@State`管理界面状态 +- 使用`@StateObject`管理CoreData +- 使用`@Environment`获取dismiss环境 + +### 2. 数据传递 +- 通过参数传递二维码内容 +- 使用NavigationLink导航到自定义样式界面 +- 异步处理二维码生成 + +### 3. 内存管理 +- 及时释放图片资源 +- 避免内存泄漏 +- 优化大图片的处理 + +## 未来扩展 + +### 1. 样式模板 +- 预设样式模板 +- 用户自定义模板保存 +- 模板分享功能 + +### 2. 批量生成 +- 支持批量生成不同样式的二维码 +- 批量导出功能 + +### 3. 高级样式 +- 更多颜色选项 +- 自定义Logo上传 +- 动画效果 + +## 总结 + +通过这次修改,我们实现了从创建二维码界面到自定义样式界面的完整流程。用户现在可以: + +1. 在创建界面填写二维码内容 +2. 点击创建按钮通过NavigationLink导航到样式界面 +3. 选择喜欢的颜色、点类型、眼睛类型和Logo +4. 预览生成的二维码 +5. 保存到相册和历史记录 + +这个实现提供了更好的用户体验,让用户能够创建个性化的二维码,同时保持了原有的功能完整性。 diff --git a/docs/QRCODE_STYLE_VIEW_README.md b/docs/QRCODE_STYLE_VIEW_README.md new file mode 100644 index 0000000..7269424 --- /dev/null +++ b/docs/QRCODE_STYLE_VIEW_README.md @@ -0,0 +1,208 @@ +# 自定义二维码样式界面 + +## 概述 + +`QRCodeStyleView` 是一个功能丰富的自定义二维码样式界面,允许用户自定义二维码的外观,包括颜色、点类型、眼睛类型和Logo。 + +## 功能特性 + +### 1. 颜色选择 +- **前景色**: 8种纯色 + 12种渐变色 +- **背景色**: 10种浅色系 + +### 2. 点类型选择 +支持40多种不同的点类型,包括: +- 基础形状:方形、圆形、菱形、六边形等 +- 特殊形状:星形、心形、花朵、齿轮等 +- 抽象形状:抽象、斑点、电路、交叉线等 +- 动态形状:火焰、漩涡、波浪等 + +### 3. 眼睛类型选择 +支持40多种不同的眼睛类型,包括: +- 基础形状:方形、圆形、弧形等 +- 特殊形状:云朵、孔雀、UFO、泪滴等 +- 动态形状:火焰、爆炸、火球等 + +### 4. Logo选择 +支持15种不同的Logo: +- 社交媒体:Facebook、Instagram、X、TikTok等 +- 通讯工具:WhatsApp、Telegram、Viber等 +- 其他服务:Gmail、PayPal、Spotify等 + +## 界面布局 + +``` +┌─────────────────────────────────────┐ +│ 自定义样式 [保存] │ +├─────────────────────────────────────┤ +│ │ +│ 二维码预览区域 │ +│ │ +├─────────────────────────────────────┤ +│ 前景色选择 │ +│ [颜色网格] │ +│ │ +│ 背景色选择 │ +│ [颜色网格] │ +│ │ +│ 点类型选择 │ +│ [水平滚动选择] │ +│ │ +│ 眼睛类型选择 │ +│ [水平滚动选择] │ +│ │ +│ Logo选择 │ +│ [水平滚动选择] │ +└─────────────────────────────────────┘ +``` + +## 技术实现 + +### 核心文件 + +1. **QRCodeStyleView.swift** - 主界面文件 +2. **QRCodeStyleModels.swift** - 数据模型文件 + +### 数据模型 + +#### QRCodeColor +```swift +enum QRCodeColor: String, CaseIterable { + case black, white, red, blue, green, yellow, purple, orange, pink, cyan + case magenta, brown, gray, navy, teal, indigo, lime, maroon, olive, silver + // 渐变色 + case gradientRed, gradientBlue, gradientGreen, gradientPurple, gradientOrange + case gradientPink, gradientYellow, gradientCyan, gradientMagenta, gradientTeal + case gradientIndigo, gradientLime +} +``` + +#### QRCodeDotType +```swift +enum QRCodeDotType: String, CaseIterable { + case square, circle, roundedRect, squircle, diamond, hexagon, star, heart + case flower, gear, abstract, arrow, blob, circuit, crosshatch, crt + case curvePixel, diagonal, diagonalStripes, donut, dripHorizontal, dripVertical + case flame, grid2x2, grid3x3, grid4x4, horizontal, koala, pointy, razor + case roundedEndIndent, roundedPath, roundedTriangle, sharp, shiny, spikyCircle + case stitch, vertical, vortex, wave, wex +} +``` + +#### QRCodeEyeType +```swift +enum QRCodeEyeType: String, CaseIterable { + case square, circle, roundedRect, squircle, arc, barsHorizontal, barsVertical + case cloud, cloudCircle, corneredPixels, crt, diagonalStripes, dotDragHorizontal + case dotDragVertical, edges, explode, eye, fabricScissors, fireball, flame + case headlight, holePunch, leaf, peacock, pinch, pixels, roundedOuter + case roundedPointingIn, roundedPointingOut, shield, spikyCircle, squarePeg + case surroundingBars, teardrop, ufo, ufoRounded, usePixelShape +} +``` + +#### QRCodeLogo +```swift +enum QRCodeLogo: String, CaseIterable { + case scanMe, gmail, paypal, googlePlaystore, spotify, telegram, whatsApp + case linkedIn, tikTok, snapchat, youtube, x, pinterest, instagram, facebook +} +``` + +### 二维码生成 + +使用Core Image的`CIFilter.qrCodeGenerator()`生成基础二维码: + +```swift +let context = CIContext() +let filter = CIFilter.qrCodeGenerator() +filter.message = Data(qrCodeContent.utf8) +filter.correctionLevel = "M" + +if let outputImage = filter.outputImage { + let scaleX = 600 / outputImage.extent.width + let scaleY = 600 / outputImage.extent.height + let transform = CGAffineTransform(scaleX: scaleX, y: scaleY) + let scaledImage = outputImage.transformed(by: transform) + + if let cgImage = context.createCGImage(scaledImage, from: scaledImage.extent) { + let image = UIImage(cgImage: cgImage) + } +} +``` + +### 图片资源 + +所有样式预览图片存储在`Resources/`目录下: +- `Resources/dots/` - 点类型预览图片 +- `Resources/eyes/` - 眼睛类型预览图片 +- `Resources/logos/` - Logo预览图片 + +## 使用方法 + +### 1. 创建界面 +```swift +QRCodeStyleView(qrCodeContent: "https://www.example.com") +``` + +### 2. 自定义样式 +用户可以通过以下方式自定义二维码: +- 选择前景色和背景色 +- 选择点类型样式 +- 选择眼睛类型样式 +- 选择Logo(可选) + +### 3. 保存二维码 +点击右上角的"保存"按钮将生成的二维码保存到相册。 + +## 界面特性 + +### 响应式设计 +- 支持不同屏幕尺寸 +- 自适应布局 +- 流畅的滚动体验 + +### 实时预览 +- 选择样式后立即生成预览 +- 异步生成避免界面卡顿 +- 加载状态指示 + +### 用户友好 +- 直观的图标选择 +- 清晰的分类展示 +- 中文界面支持 + +## 扩展性 + +### 添加新颜色 +在`QRCodeColor`枚举中添加新的颜色类型。 + +### 添加新点类型 +1. 在`QRCodeDotType`枚举中添加新类型 +2. 在`Resources/dots/`目录添加预览图片 +3. 更新`displayName`和`pixelShape`属性 + +### 添加新眼睛类型 +1. 在`QRCodeEyeType`枚举中添加新类型 +2. 在`Resources/eyes/`目录添加预览图片 +3. 更新`displayName`和`eyeShape`属性 + +### 添加新Logo +1. 在`QRCodeLogo`枚举中添加新类型 +2. 在`Resources/logos/`目录添加Logo图片 +3. 更新`displayName`属性 + +## 注意事项 + +1. **图片资源**: 确保所有预览图片都已添加到Xcode项目中 +2. **性能优化**: 二维码生成在后台线程进行,避免界面卡顿 +3. **内存管理**: 及时释放不需要的图片资源 +4. **错误处理**: 处理图片加载失败的情况 + +## 未来改进 + +1. **更多样式**: 添加更多颜色、形状和Logo选项 +2. **自定义Logo**: 允许用户上传自定义Logo +3. **样式预设**: 提供预设的样式组合 +4. **导出选项**: 支持不同格式和尺寸的导出 +5. **动画效果**: 添加选择时的动画效果