@ -19,6 +19,8 @@ struct HistoryView: View {
@ State private var refreshTrigger = false
@ State private var refreshTrigger = false
@ State private var isBatchDeleteMode = false
@ State private var isBatchDeleteMode = false
@ State private var selectedItemsForDelete : Set < UUID > = [ ]
@ State private var selectedItemsForDelete : Set < UUID > = [ ]
@ State private var itemToEdit : HistoryItem ?
@ State private var showingEditView = false
enum HistoryFilter : String , CaseIterable {
enum HistoryFilter : String , CaseIterable {
case all = " all "
case all = " all "
@ -195,6 +197,7 @@ Button("delete".localized, role: .destructive) {
// 当 C o r e D a t a 数 据 发 生 变 化 时 , 重 新 加 载 历 史 记 录
// 当 C o r e D a t a 数 据 发 生 变 化 时 , 重 新 加 载 历 史 记 录
loadHistoryItems ( )
loadHistoryItems ( )
}
}
. background ( editNavigationLink )
}
}
// MARK: - 加 载 历 史 记 录
// MARK: - 加 载 历 史 记 录
@ -281,6 +284,57 @@ Button("delete".localized, role: .destructive) {
showingDeleteAlert = true
showingDeleteAlert = true
}
}
// MARK: - 显 示 编 辑 界 面
private func showEditView ( for item : HistoryItem ) {
itemToEdit = item
showingEditView = true
}
// MARK: - 获 取 二 维 码 类 型
private func getQRCodeType ( from item : HistoryItem ) -> QRCodeType {
if let qrCodeTypeString = item . qrCodeType ,
let qrCodeType = QRCodeType ( rawValue : qrCodeTypeString ) {
return qrCodeType
}
return . text // 默 认 类 型
}
// MARK: - 获 取 样 式 数 据
private func getStyleData ( from item : HistoryItem ) -> QRCodeStyleData ? {
// 从 历 史 记 录 项 中 提 取 样 式 数 据
guard let jsonString = item . 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 var editNavigationLink : some View {
NavigationLink (
destination : Group {
if let itemToEdit = itemToEdit {
QRCodeStyleView (
qrCodeContent : itemToEdit . content ? ? " " ,
qrCodeType : getQRCodeType ( from : itemToEdit ) ,
existingStyleData : getStyleData ( from : itemToEdit ) ,
historyItem : itemToEdit
)
}
} ,
isActive : $ showingEditView
) {
EmptyView ( )
}
}
// MARK: - 批 量 删 除 相 关 方 法
// MARK: - 批 量 删 除 相 关 方 法
private func enterBatchDeleteMode ( ) {
private func enterBatchDeleteMode ( ) {
isBatchDeleteMode = true
isBatchDeleteMode = true
@ -384,6 +438,9 @@ Button("delete".localized, role: .destructive) {
onDelete : {
onDelete : {
showDeleteConfirmation ( for : item )
showDeleteConfirmation ( for : item )
} ,
} ,
onEdit : {
showEditView ( for : item )
} ,
isBatchDeleteMode : isBatchDeleteMode ,
isBatchDeleteMode : isBatchDeleteMode ,
isSelected : selectedItemsForDelete . contains ( item . id ? ? UUID ( ) ) ,
isSelected : selectedItemsForDelete . contains ( item . id ? ? UUID ( ) ) ,
onToggleSelection : {
onToggleSelection : {
@ -529,6 +586,7 @@ struct HistoryItemRow: View {
let item : HistoryItem
let item : HistoryItem
let onToggleFavorite : ( ) -> Void
let onToggleFavorite : ( ) -> Void
let onDelete : ( ) -> Void
let onDelete : ( ) -> Void
let onEdit : ( ( ) -> Void ) ?
let isBatchDeleteMode : Bool
let isBatchDeleteMode : Bool
let isSelected : Bool
let isSelected : Bool
let onToggleSelection : ( ) -> Void
let onToggleSelection : ( ) -> Void
@ -642,9 +700,28 @@ struct HistoryItemRow: View {
}
}
. padding ( . vertical , 8 )
. padding ( . vertical , 8 )
. swipeActions ( edge : . trailing , allowsFullSwipe : false ) {
. swipeActions ( edge : . trailing , allowsFullSwipe : false ) {
Button ( " delete " . localized , role : . destructive ) {
// 分 享 按 钮
onDelete ( )
Button ( action : {
shareItem ( item )
} ) {
Image ( systemName : " square.and.arrow.up " )
}
. tint ( . gray )
// 为 创 建 类 型 的 二 维 码 条 目 添 加 编 辑 按 钮
if item . dataType = = DataType . qrcode . rawValue &&
item . dataSource = = DataSource . created . rawValue ,
let onEdit = onEdit {
Button ( action : onEdit ) {
Image ( systemName : " pencil " )
}
. tint ( . blue )
}
}
Button ( action : onDelete ) {
Image ( systemName : " trash " )
}
. tint ( . red )
}
}
. background (
. background (
// 根 据 数 据 类 型 和 数 据 源 添 加 导 航 链 接
// 根 据 数 据 类 型 和 数 据 源 添 加 导 航 链 接
@ -701,6 +778,32 @@ struct HistoryItemRow: View {
)
)
}
}
// MARK: - 分 享 功 能
private func shareItem ( _ item : HistoryItem ) {
let content = item . content ? ? " "
let activityVC = UIActivityViewController (
activityItems : [ content ] ,
applicationActivities : nil
)
// 在 i P a d 上 需 要 设 置 p o p o v e r P r e s e n t a t i o n C o n t r o l l e r
if let windowScene = UIApplication . shared . connectedScenes . first as ? UIWindowScene ,
let window = windowScene . windows . first {
if let popover = activityVC . popoverPresentationController {
popover . sourceView = window
popover . sourceRect = CGRect ( x : window . bounds . midX , y : window . bounds . midY , width : 0 , height : 0 )
popover . permittedArrowDirections = [ ]
}
}
// 获 取 当 前 视 图 控 制 器 并 显 示 分 享 界 面
if let windowScene = UIApplication . shared . connectedScenes . first as ? UIWindowScene ,
let window = windowScene . windows . first ,
let rootViewController = window . rootViewController {
rootViewController . present ( activityVC , animated : true )
}
}
private func getQRCodeType ( from item : HistoryItem ) -> QRCodeType {
private func getQRCodeType ( from item : HistoryItem ) -> QRCodeType {
if let qrCodeTypeString = item . qrCodeType ,
if let qrCodeTypeString = item . qrCodeType ,
let qrCodeType = QRCodeType ( rawValue : qrCodeTypeString ) {
let qrCodeType = QRCodeType ( rawValue : qrCodeTypeString ) {