import SwiftUI
import CoreData
import QRCode
internal import SwiftImageReadWrite
struct QRCodeDetailView : View {
let historyItem : HistoryItem
@ EnvironmentObject var coreDataManager : CoreDataManager
@ State private var qrCodeImage : UIImage ?
@ State private var showingShareSheet = false
@ State private var showingAlert = false
@ State private var alertMessage = " "
@ State private var navigateToStyleView = false
var body : some View {
ScrollView {
VStack ( spacing : 20 ) {
// 二 维 码 图 片
qrCodeStyleSection
// 解 析 后 的 详 细 信 息
parsedInfoSection
// 原 始 内 容
originalContentSection
// 操 作 按 钮
actionButtonsSection
// D e c o r a t e c o d e 按 钮
decorateCodeButton
}
. padding ( )
}
. navigationTitle ( getNavigationTitle ( ) )
. navigationBarTitleDisplayMode ( . inline )
. toolbar {
ToolbarItem ( placement : . navigationBarTrailing ) {
Button ( action : {
showingShareSheet = true
} ) {
Image ( systemName : " square.and.arrow.up " )
}
}
}
. onAppear {
generateQRCodeImage ( )
}
. sheet ( isPresented : $ showingShareSheet ) {
ShareSheet ( activityItems : [ historyItem . content ? ? " " ] )
}
. alert ( NSLocalizedString ( " tip " , comment : " Tip " ) , isPresented : $ showingAlert ) {
Button ( NSLocalizedString ( " confirm " , comment : " Confirm " ) ) { }
} message : {
Text ( alertMessage )
}
. background (
NavigationLink (
destination : QRCodeStyleView (
qrCodeContent : historyItem . content ? ? " " ,
qrCodeType : getQRCodeType ( ) ,
existingStyleData : getStyleData ( ) ,
historyItem : historyItem
) ,
isActive : $ navigateToStyleView
) {
EmptyView ( )
}
)
}
// MARK: - 二 维 码 图 片 视 图
private var qrCodeImageView : some View {
VStack ( spacing : 16 ) {
if let qrCodeImage = qrCodeImage {
Image ( uiImage : qrCodeImage )
. resizable ( )
. aspectRatio ( contentMode : . fit )
. frame ( width : 200 , height : 200 )
. cornerRadius ( 12 )
. shadow ( radius : 8 )
} else {
RoundedRectangle ( cornerRadius : 12 )
. fill ( Color . gray . opacity ( 0.3 ) )
. frame ( width : 200 , height : 200 )
. overlay (
ProgressView ( )
. scaleEffect ( 1.5 )
)
}
Text ( NSLocalizedString ( " scan_this_qr_code " , comment : " Scan this QR code " ) )
. font ( . caption )
. foregroundColor ( . secondary )
}
}
// MARK: - 解 析 后 的 详 细 信 息
private var parsedInfoSection : some View {
VStack ( alignment : . leading , spacing : 12 ) {
HStack {
Image ( systemName : " info.circle " )
. font ( . title2 )
. foregroundColor ( . green )
Text ( NSLocalizedString ( " parsed_info " , comment : " Parsed Information " ) )
. font ( . headline )
Spacer ( )
}
if let content = historyItem . content {
let parsedData = QRCodeParser . parseQRCode ( content )
VStack ( alignment : . leading , spacing : 8 ) {
HStack {
Image ( systemName : parsedData . icon )
. font ( . title3 )
. foregroundColor ( . green )
Text ( parsedData . title )
. font ( . title3 )
. fontWeight ( . medium )
Spacer ( )
}
if let subtitle = parsedData . subtitle {
Text ( subtitle )
. font ( . body )
. foregroundColor ( . secondary )
. multilineTextAlignment ( . leading )
}
}
. padding ( )
. background ( Color . green . opacity ( 0.1 ) )
. cornerRadius ( 8 )
}
}
. padding ( )
. background ( Color ( . systemBackground ) )
. cornerRadius ( 12 )
. shadow ( radius : 2 )
}
// MARK: - 原 始 内 容
private var originalContentSection : some View {
VStack ( alignment : . leading , spacing : 12 ) {
HStack {
Image ( systemName : " doc.text " )
. font ( . title2 )
. foregroundColor ( . purple )
Text ( NSLocalizedString ( " original_content " , comment : " Original Content " ) )
. font ( . headline )
Spacer ( )
}
if let content = historyItem . content {
ScrollView {
Text ( content )
. font ( . system ( . body , design : . monospaced ) )
. foregroundColor ( . secondary )
. multilineTextAlignment ( . leading )
. padding ( )
. frame ( maxWidth : . infinity , alignment : . leading )
}
. frame ( maxHeight : 200 )
. background ( Color . purple . opacity ( 0.1 ) )
. cornerRadius ( 8 )
}
}
. padding ( )
. background ( Color ( . systemBackground ) )
. cornerRadius ( 12 )
. shadow ( radius : 2 )
}
// MARK: - 二 维 码 样 式 信 息
private var qrCodeStyleSection : some View {
VStack ( spacing : 0 ) {
if let styleData = getStyleData ( ) {
// 使 用 样 式 生 成 二 维 码 预 览
VStack ( spacing : 16 ) {
// 样 式 预 览 二 维 码
if let previewImage = generateStylePreviewImage ( styleData : styleData ) {
Image ( uiImage : previewImage )
. resizable ( )
. aspectRatio ( contentMode : . fit )
. frame ( maxWidth : 200 , maxHeight : 200 )
. padding ( )
. background ( Color . white )
. cornerRadius ( 12 )
. shadow ( radius : 4 )
}
// 样 式 标 签
HStack ( spacing : 8 ) {
Label ( NSLocalizedString ( " custom " , comment : " Custom " ) , systemImage : " paintpalette " )
. font ( . caption )
. padding ( . horizontal , 8 )
. padding ( . vertical , 4 )
. background ( Color . purple . opacity ( 0.2 ) )
. foregroundColor ( . purple )
. cornerRadius ( 6 )
}
}
. padding ( )
. background ( Color . purple . opacity ( 0.05 ) )
. cornerRadius ( 12 )
} else {
// 标 准 样 式 预 览
VStack ( spacing : 16 ) {
if let standardImage = generateStandardQRCodeImage ( ) {
Image ( uiImage : standardImage )
. resizable ( )
. aspectRatio ( contentMode : . fit )
. frame ( maxWidth : 200 , maxHeight : 200 )
. padding ( )
. background ( Color . white )
. cornerRadius ( 12 )
. shadow ( radius : 4 )
}
Label ( NSLocalizedString ( " standard " , comment : " Standard " ) , systemImage : " qrcode " )
. font ( . caption )
. padding ( . horizontal , 8 )
. padding ( . vertical , 4 )
. background ( Color . gray . opacity ( 0.2 ) )
. foregroundColor ( . gray )
. cornerRadius ( 6 )
}
. padding ( )
. background ( Color . gray . opacity ( 0.05 ) )
. cornerRadius ( 12 )
}
}
. padding ( )
}
// MARK: - 操 作 按 钮
private var actionButtonsSection : some View {
VStack ( spacing : 12 ) {
// 收 藏 按 钮
Button ( action : toggleFavorite ) {
HStack {
Image ( systemName : historyItem . isFavorite ? " heart.fill " : " heart " )
. foregroundColor ( historyItem . isFavorite ? . red : . gray )
Text ( historyItem . isFavorite ? NSLocalizedString ( " unfavorite " , comment : " Unfavorite " ) : NSLocalizedString ( " favorite " , comment : " Favorite " ) )
. fontWeight ( . medium )
}
. frame ( maxWidth : . infinity )
. padding ( )
. background ( historyItem . isFavorite ? Color . red . opacity ( 0.1 ) : Color . gray . opacity ( 0.1 ) )
. foregroundColor ( historyItem . isFavorite ? . red : . gray )
. cornerRadius ( 10 )
}
// 复 制 内 容 按 钮
Button ( action : copyContent ) {
HStack {
Image ( systemName : " doc.on.doc " )
. foregroundColor ( . blue )
Text ( NSLocalizedString ( " copy_content " , comment : " Copy Content " ) )
. fontWeight ( . medium )
}
. frame ( maxWidth : . infinity )
. padding ( )
. background ( Color . blue . opacity ( 0.1 ) )
. foregroundColor ( . blue )
. cornerRadius ( 10 )
}
// 打 开 链 接 按 钮 ( 如 果 是 U R L 类 型 )
if let content = historyItem . content , canOpenURL ( content ) {
Button ( action : { openURL ( content ) } ) {
HStack {
Image ( systemName : " arrow.up.right.square " )
. foregroundColor ( . green )
Text ( NSLocalizedString ( " open_link " , comment : " Open Link " ) )
. fontWeight ( . medium )
}
. frame ( maxWidth : . infinity )
. padding ( )
. background ( Color . green . opacity ( 0.1 ) )
. foregroundColor ( . green )
. cornerRadius ( 10 )
}
}
}
. padding ( )
. background ( Color ( . systemBackground ) )
. cornerRadius ( 12 )
. shadow ( radius : 2 )
}
// MARK: - 生 成 二 维 码 图 片
private func generateQRCodeImage ( ) {
guard let content = historyItem . content else { return }
do {
let imageData = try QRCode . build
. text ( content )
. quietZonePixelCount ( 3 )
. foregroundColor ( CGColor ( srgbRed : 1 , green : 0 , blue : 0.6 , alpha : 1 ) )
. backgroundColor ( CGColor ( srgbRed : 0 , green : 0 , blue : 0.2 , alpha : 1 ) )
. background . cornerRadius ( 3 )
. onPixels . shape ( QRCode . PixelShape . CurvePixel ( ) )
. eye . shape ( QRCode . EyeShape . Teardrop ( ) )
. generate . image ( dimension : 600 , representation : . png ( ) )
self . qrCodeImage = UIImage ( data : imageData )
} catch {
print ( " 生成二维码失败: \( error ) " )
}
}
// MARK: - 切 换 收 藏 状 态
private func toggleFavorite ( ) {
historyItem . isFavorite . toggle ( )
coreDataManager . save ( )
let message = historyItem . isFavorite ? NSLocalizedString ( " added_to_favorites " , comment : " Added to favorites " ) : NSLocalizedString ( " removed_from_favorites " , comment : " Removed from favorites " )
alertMessage = message
showingAlert = true
}
// MARK: - 复 制 内 容
private func copyContent ( ) {
if let content = historyItem . content {
UIPasteboard . general . string = content
alertMessage = NSLocalizedString ( " content_copied_to_clipboard " , comment : " Content copied to clipboard " )
showingAlert = true
}
}
// MARK: - 检 查 是 否 可 以 打 开 U R L
private func canOpenURL ( _ string : String ) -> Bool {
guard let url = URL ( string : string ) else { return false }
return UIApplication . shared . canOpenURL ( url )
}
// MARK: - 打 开 U R L
private func openURL ( _ string : String ) {
guard let url = URL ( string : string ) else { return }
UIApplication . shared . open ( url )
}
}
// MARK: - 分 享 表 单
struct ShareSheet : UIViewControllerRepresentable {
let activityItems : [ Any ]
func makeUIViewController ( context : Context ) -> UIActivityViewController {
let controller = UIActivityViewController ( activityItems : activityItems , applicationActivities : nil )
return controller
}
func updateUIViewController ( _ uiViewController : UIActivityViewController , context : Context ) { }
}
# Preview ( " Wi‑ Fi " ) {
let ctx = PreviewData . context
let item = PreviewData . wifiSample ( in : ctx )
NavigationView { QRCodeDetailView ( historyItem : item ) }
}
# Preview ( " URL " ) {
let ctx = PreviewData . context
let item = PreviewData . urlSample ( in : ctx )
NavigationView { QRCodeDetailView ( historyItem : item ) }
}
# Preview ( " SMS " ) {
let ctx = PreviewData . context
let item = PreviewData . smsSample ( in : ctx )
NavigationView { QRCodeDetailView ( historyItem : item ) }
}
# Preview ( " vCard " ) {
let ctx = PreviewData . context
let item = PreviewData . vcardSample ( in : ctx )
NavigationView { QRCodeDetailView ( historyItem : item ) }
}
# Preview ( " Instagram " ) {
let ctx = PreviewData . context
let item = PreviewData . instagramSample ( in : ctx )
NavigationView { QRCodeDetailView ( historyItem : item ) }
}
# Preview ( " WhatsApp " ) {
let ctx = PreviewData . context
let item = PreviewData . whatsappSample ( in : ctx )
NavigationView { QRCodeDetailView ( historyItem : item ) }
}
# Preview ( " Viber " ) {
let ctx = PreviewData . context
let item = PreviewData . viberSample ( in : ctx )
NavigationView { QRCodeDetailView ( historyItem : item ) }
}
# Preview ( " Text " ) {
let ctx = PreviewData . context
let item = PreviewData . textSample ( in : ctx )
NavigationView { QRCodeDetailView ( historyItem : item ) }
}
# Preview ( " MeCard " ) {
let ctx = PreviewData . context
let item = PreviewData . mecardSample ( in : ctx )
NavigationView { QRCodeDetailView ( historyItem : item ) }
}
// MARK: - P r e v i e w D a t a
private enum PreviewData {
static let context : NSManagedObjectContext = {
let container = NSPersistentContainer ( name : " MyQrCode " )
let description = NSPersistentStoreDescription ( )
description . type = NSInMemoryStoreType
container . persistentStoreDescriptions = [ description ]
container . loadPersistentStores { _ , _ in }
return container . viewContext
} ( )
private static func makeBaseItem ( in context : NSManagedObjectContext , content : String , qrType : QRCodeType , favorite : Bool = false ) -> HistoryItem {
let item = HistoryItem ( context : context )
item . id = UUID ( )
item . content = content
item . dataType = DataType . qrcode . rawValue
item . dataSource = DataSource . created . rawValue
item . createdAt = Date ( )
item . isFavorite = favorite
item . qrCodeType = qrType . rawValue
return item
}
static func wifiSample ( in context : NSManagedObjectContext ) -> HistoryItem {
let content = " WIFI:T:WPA;S:MyNetwork;P:MyPassword;; "
return makeBaseItem ( in : context , content : content , qrType : . wifi , favorite : true )
}
static func urlSample ( in context : NSManagedObjectContext ) -> HistoryItem {
let content = " https://www.example.com "
return makeBaseItem ( in : context , content : content , qrType : . url )
}
static func smsSample ( in context : NSManagedObjectContext ) -> HistoryItem {
let content = " SMSTO:+1 (555) 123-4567:Hello "
return makeBaseItem ( in : context , content : content , qrType : . sms )
}
static func vcardSample ( in context : NSManagedObjectContext ) -> HistoryItem {
let content = " " "
BEGIN : VCARD
VERSION : 3.0
N : Doe ; John ; ; ;
FN : John Doe
TEL ; TYPE = WORK , CELL : ( 123 ) 456 - 7890
EMAIL ; TYPE = PREF , INTERNET : john . doe @ example . com
ORG : Example Company
TITLE : Software Engineer
ADR ; TYPE = WORK : ; ; 123 Main St ; Anytown ; CA ; 12345 ; USA
URL : https : // e x a m p l e . c o m
END : VCARD
" " " .trimmingCharacters(in: .whitespacesAndNewlines)
return makeBaseItem ( in : context , content : content , qrType : . vcard )
}
static func instagramSample ( in context : NSManagedObjectContext ) -> HistoryItem {
let content = " instagram://user?username=example_user "
return makeBaseItem ( in : context , content : content , qrType : . instagram )
}
static func whatsappSample ( in context : NSManagedObjectContext ) -> HistoryItem {
let content = " whatsapp://send?phone=+1234567890 "
return makeBaseItem ( in : context , content : content , qrType : . whatsapp )
}
static func textSample ( in context : NSManagedObjectContext ) -> HistoryItem {
let content = " Hello, this is a text message! "
return makeBaseItem ( in : context , content : content , qrType : . text )
}
static func viberSample ( in context : NSManagedObjectContext ) -> HistoryItem {
let content = " viber://add?number=+1234567890 "
return makeBaseItem ( in : context , content : content , qrType : . viber )
}
static func mecardSample ( in context : NSManagedObjectContext ) -> HistoryItem {
let content = " MECARD:N:Doe,John;NICKNAME:Johnny;TEL:+1234567890;EMAIL:john.doe@example.com;ORG:Example Company;TITLE:Software Engineer;ADR:123 Main St,Anytown,CA,12345,USA;URL:https://example.com;NOTE:This is a note; "
return makeBaseItem ( in : context , content : content , qrType : . mecard )
}
}
// MARK: - 样 式 信 息 辅 助 方 法
extension QRCodeDetailView {
// MARK: - 生 成 样 式 预 览 图 片
private func generateStylePreviewImage ( styleData : QRCodeStyleData ) -> UIImage ? {
guard let content = historyItem . content else { return nil }
do {
var qrCodeBuilder = try QRCode . build
. text ( content )
. quietZonePixelCount ( 0 )
// 设 置 前 景 色
if let foregroundColor = getColorFromString ( styleData . foregroundColor ) {
qrCodeBuilder = qrCodeBuilder . foregroundColor ( foregroundColor )
}
// 设 置 背 景 色
if let backgroundColor = getColorFromString ( styleData . backgroundColor ) {
qrCodeBuilder = qrCodeBuilder . backgroundColor ( backgroundColor )
}
// 设 置 背 景 圆 角
qrCodeBuilder = qrCodeBuilder . background . cornerRadius ( 3 )
// 设 置 点 类 型
if let dotType = getDotTypeFromString ( styleData . dotType ) {
qrCodeBuilder = qrCodeBuilder . onPixels . shape ( dotType )
}
// 设 置 眼 睛 类 型
if let eyeType = getEyeTypeFromString ( styleData . eyeType ) {
qrCodeBuilder = qrCodeBuilder . eye . shape ( eyeType )
}
// 设 置 L o g o ( 如 果 有 的 话 )
if let logo = styleData . logo , ! logo . isEmpty {
if let logoTemplate = getLogoFromString ( logo ) {
qrCodeBuilder = qrCodeBuilder . logo ( logoTemplate )
}
}
// 生 成 图 片
let imageData = try qrCodeBuilder . generate . image ( dimension : 300 , representation : . png ( ) )
return UIImage ( data : imageData )
} catch {
print ( " 生成样式预览图片失败: \( error ) " )
return nil
}
}
// MARK: - 生 成 标 准 二 维 码 图 片
private func generateStandardQRCodeImage ( ) -> UIImage ? {
guard let content = historyItem . content else { return nil }
do {
let imageData = try QRCode . build
. text ( content )
. quietZonePixelCount ( 0 )
. foregroundColor ( CGColor ( srgbRed : 0 , green : 0 , blue : 0 , alpha : 1 ) )
. backgroundColor ( CGColor ( srgbRed : 1 , green : 1 , blue : 1 , alpha : 1 ) )
. generate . image ( dimension : 300 , representation : . png ( ) )
return UIImage ( data : imageData )
} catch {
print ( " 生成标准二维码图片失败: \( error ) " )
return nil
}
}
// MARK: - 颜 色 转 换
private func getColorFromString ( _ colorString : String ) -> CGColor ? {
if let color = QRCodeColor ( rawValue : colorString ) {
return color . cgColor
}
return nil
}
// MARK: - 点 类 型 转 换
private func getDotTypeFromString ( _ dotTypeString : String ) -> QRCodePixelShapeGenerator ? {
if let dotType = QRCodeDotType ( rawValue : dotTypeString ) {
return dotType . pixelShape
}
return nil
}
// MARK: - 眼 睛 类 型 转 换
private func getEyeTypeFromString ( _ eyeTypeString : String ) -> QRCodeEyeShapeGenerator ? {
if let eyeType = QRCodeEyeType ( rawValue : eyeTypeString ) {
return eyeType . eyeShape
}
return nil
}
// MARK: - L o g o 转 换
private func getLogoFromString ( _ logoString : String ) -> QRCode . LogoTemplate ? {
// 检 查 是 否 是 自 定 义 L o g o
if logoString . hasPrefix ( " custom_ " ) {
// 从 样 式 数 据 中 获 取 自 定 义 L o g o 图 片
if let styleData = getStyleData ( ) ,
let customImage = styleData . customLogoImage ,
let cgImage = customImage . cgImage {
return QRCode . LogoTemplate . CircleCenter ( image : cgImage , inset : 0 )
}
} else {
// 预 设 L o g o
if let logo = QRCodeLogo ( rawValue : logoString ) ,
let image = logo . image ,
let cgImage = image . cgImage {
return QRCode . LogoTemplate . CircleCenter ( image : cgImage )
}
}
return nil
}
// MARK: - 从 J S O N 字 符 串 解 析 样 式 数 据
private func getStyleData ( ) -> QRCodeStyleData ? {
guard let jsonString = historyItem . qrCodeStyleData ,
let jsonData = jsonString . data ( using : . utf8 ) else {
return nil
}
do {
let styleData = try JSONDecoder ( ) . decode ( QRCodeStyleData . self , from : jsonData )
return styleData
} catch {
print ( " ❌ 样式数据JSON解码失败: \( error ) " )
return nil
}
}
// MARK: - 显 示 名 称 转 换 方 法 ( 保 留 原 有 方 法 )
private func getColorDisplayName ( _ colorString : String ) -> String {
if let color = QRCodeColor ( rawValue : colorString ) {
switch color {
case . black : return NSLocalizedString ( " black " , comment : " Black " )
case . white : return NSLocalizedString ( " white " , comment : " White " )
case . red : return NSLocalizedString ( " red " , comment : " Red " )
case . blue : return NSLocalizedString ( " blue " , comment : " Blue " )
case . green : return NSLocalizedString ( " green " , comment : " Green " )
case . yellow : return NSLocalizedString ( " yellow " , comment : " Yellow " )
case . purple : return NSLocalizedString ( " purple " , comment : " Purple " )
case . orange : return NSLocalizedString ( " orange " , comment : " Orange " )
case . pink : return NSLocalizedString ( " pink " , comment : " Pink " )
case . cyan : return NSLocalizedString ( " cyan " , comment : " Cyan " )
case . magenta : return NSLocalizedString ( " magenta " , comment : " Magenta " )
case . brown : return NSLocalizedString ( " brown " , comment : " Brown " )
case . gray : return NSLocalizedString ( " gray " , comment : " Gray " )
case . navy : return NSLocalizedString ( " navy " , comment : " Navy " )
case . teal : return NSLocalizedString ( " teal " , comment : " Teal " )
case . indigo : return NSLocalizedString ( " indigo " , comment : " Indigo " )
case . lime : return NSLocalizedString ( " lime " , comment : " Lime " )
case . maroon : return NSLocalizedString ( " maroon " , comment : " Maroon " )
case . olive : return NSLocalizedString ( " olive " , comment : " Olive " )
case . silver : return NSLocalizedString ( " silver " , comment : " Silver " )
}
}
return colorString
}
private func getDotTypeDisplayName ( _ dotTypeString : String ) -> String {
if let dotType = QRCodeDotType ( rawValue : dotTypeString ) {
return dotType . displayName
}
return dotTypeString
}
private func getEyeTypeDisplayName ( _ eyeTypeString : String ) -> String {
if let eyeType = QRCodeEyeType ( rawValue : eyeTypeString ) {
return eyeType . displayName
}
return eyeTypeString
}
private func getLogoDisplayName ( _ logoString : String ) -> String {
if let logo = QRCodeLogo ( rawValue : logoString ) {
return logo . displayName
}
return logoString
}
// MARK: - 获 取 二 维 码 类 型
private func getQRCodeType ( ) -> QRCodeType {
if let qrCodeTypeString = historyItem . qrCodeType ,
let qrCodeType = QRCodeType ( rawValue : qrCodeTypeString ) {
return qrCodeType
}
return . text // 默 认 返 回 t e x t 类 型
}
// MARK: - 获 取 导 航 标 题
private func getNavigationTitle ( ) -> String {
if let qrCodeTypeString = historyItem . qrCodeType ,
let qrCodeType = QRCodeType ( rawValue : qrCodeTypeString ) {
return qrCodeType . displayName
}
return NSLocalizedString ( " qr_code_detail " , comment : " QR Code Detail " )
}
// MARK: - D e c o r a t e c o d e 按 钮
private var decorateCodeButton : some View {
VStack ( spacing : 16 ) {
Button ( action : {
navigateToCustomStyle ( )
} ) {
HStack ( spacing : 12 ) {
Image ( systemName : " paintpalette.fill " )
. font ( . title2 )
. foregroundColor ( . white )
Text ( NSLocalizedString ( " decorate_code " , comment : " Decorate Code " ) )
. font ( . headline )
. fontWeight ( . semibold )
. foregroundColor ( . white )
Spacer ( )
Image ( systemName : " chevron.right " )
. font ( . system ( size : 14 , weight : . medium ) )
. foregroundColor ( . white . opacity ( 0.8 ) )
}
. padding ( . horizontal , 20 )
. padding ( . vertical , 16 )
. background (
LinearGradient (
gradient : Gradient ( colors : [ Color . purple , Color . blue ] ) ,
startPoint : . leading ,
endPoint : . trailing
)
)
. cornerRadius ( 12 )
. shadow ( color : . purple . opacity ( 0.3 ) , radius : 8 , x : 0 , y : 4 )
}
. buttonStyle ( PlainButtonStyle ( ) )
// 如 果 有 现 有 样 式 , 显 示 提 示
if getStyleData ( ) != nil {
HStack {
Image ( systemName : " info.circle.fill " )
. font ( . caption )
. foregroundColor ( . orange )
Text ( NSLocalizedString ( " qr_code_has_style " , comment : " This QR code has custom style, tap to edit " ) )
. font ( . caption )
. foregroundColor ( . secondary )
Spacer ( )
}
. padding ( . horizontal , 4 )
}
}
. padding ( )
. background ( Color ( . systemBackground ) )
. cornerRadius ( 12 )
. shadow ( radius : 2 )
}
// MARK: - 跳 转 到 自 定 义 样 式 界 面
private func navigateToCustomStyle ( ) {
navigateToStyleView = true
}
}