项目重构

数据结构设计

摒弃原来的多层结构,只用一层数据结构设计,并且使用relationships 关系

account设计(兼顾账户和第二类型)

  1. accountID

  2. balance(余额)

  3. counted

  4. icon

  5. name

  6. note

  7. type

    1. 支出
    2. 收入
    3. 普通账户
    4. 信用账户
    5. 投资账户
    6. 借贷账户
  8. billingData: 账单日 credit

  9. creditLimit: 额度 credit

  10. repaymentDate: 还款日 credit

  11. rate: 百分比:利息什么的 installment , loan

  12. autoCalculate installment, loan

  13. installmentType : installment, loan

  14. destinationAccount : loan

  15. installmentTimes: 期数 loan

  16. installmentType: 年月日 loan

  17. isDEBJ: 等额本金 loan

  18. isMoneyIn: 进、出 loan

  19. person: 借贷对象 loan

  20. state: 是否结清 loan

  21. timesInterest: 单次利息 loan

  22. timesLeft: 剩余期数 loan

ios 读取csv文件

最终代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
      
.fileImporter(isPresented: $imported, allowedContentTypes: [.delimitedText], allowsMultipleSelection: false){ result in
do {

guard let fileUrl: URL = try result.get().first else {return}

if (CFURLStartAccessingSecurityScopedResource(fileUrl as CFURL)) { //不在这个if里就出错,唉
//理由:iOS的沙盒机制保护需要我们申请临时调用url的权限

guard let data = String(data: try Data(contentsOf: fileUrl), encoding: .utf8) else { return }


handleSSJdataCSV(data: data)
//done accessing the url
CFURLStopAccessingSecurityScopedResource(fileUrl as CFURL)
}
else {
print("Permission error!")
}
} catch {
// Handle failure.
print ("error reading: \(error.localizedDescription)")
}
}

//数据格式处理代码
func handleSSJdataCSV(data : String){
var csvToStruct = [SSJdata]()

//split the long string into an array of "rows " of sata. each row is a string
//detect "/n" carriage return , then split
var rows = data.components(separatedBy: "\n")

let columnCount = rows.first?.components(separatedBy: ",").count
//remove the header rows
rows.removeFirst()

//loop around each row and split into columns
for row in rows{
let csvColumes = row.components(separatedBy: ",")
if csvColumes.count == columnCount{
let genericStruct = SSJdata.init( raw: csvColumes)
csvToStruct.append(genericStruct!)
}

}
print(csvToStruct)

for singleRecord in csvToStruct{
print(singleRecord.recordType)
}
//done accessing the url
}

参考文献:
https://stackoverflow.com/questions/67731694/how-do-i-save-an-imported-file-name-as-string-after-importing-file-in-swiftui

1
2
3
4
5
//不太管用
let fileUrl = try res.get()
self.fileName = fileUrl.lastPathComponent // <--- the file name you want

let fileData = try Data(contentsOf: fileUrl)

https://betterprogramming.pub/importing-and-exporting-files-in-swiftui-719086ec712
有大用
https://github.com/acwright/ImportExport
上面那个链接内容的示范工程

SwiftUI页面跳转

  1. TabView

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    struct ContentView: View {
    @State private var selection : Tab = .home
    enum Tab {
    case home
    case journal
    case statistics
    case settings
    // case test
    case test2
    }
    var body: some View {
    TabView(selection: $selection){
    HomeView()
    .tabItem {
    Label("主页", systemImage : "house")
    }
    .tag(Tab.home)
    ViewJournal()
    .tabItem {
    Label("流水", systemImage:"newspaper")
    }
    .tag(Tab.journal)

    ViewStatistics()
    .tabItem {
    Label("统计", systemImage:"waveform.path.ecg")
    }
    .tag(Tab.statistics)

    ViewSettings()
    .tabItem {
    Label("设置", systemImage:"seal")
    }
    .tag(Tab.settings)
    }
    }
    }
  2. NavigationLink

    1
    2
    3
    4
    5
    6
    7
    8
    NavigationView {
    VStack {
    NavigationLink(destination: Text("点击后显示的视图内容")) {
    Text("可点击内容")
    }
    }
    .navigationBarTitle("这是顶部标题")
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    NavigationView {
    List(0..<3) { i in
    NavigationLink(
    destination: Text("点击列表页后进入的页面 (i)")) {
    Text("列表序号 (i)")
    }
    }
    .navigationBarTitle("标题")
    }
  3. sheet向上拉起

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    import SwiftUI
    struct ContentView:View {
    var body: some View{
    TestSheet()
    }
    }
    struct TestSheet: View {
    @State private var popoverIsShown = false
    var body: some View {
    Button("显示 Sheet") {
    self.popoverIsShown = true
    }
    .sheet(isPresented: self.$popoverIsShown) {
    RandomSheet(popoverIsShown: self.$popoverIsShown)
    }
    }
    }

    struct RandomSheet: View {
    @Binding var popoverIsShown: Bool
    var body: some View {
    Button("关闭") { self.popoverIsShown = false }
    }
    }
  4. ActionSheet

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Button("显示Sheet页") {
    showingSheet = true//点击后改显示
    }
    .actionSheet(isPresented: $showingSheet) {
    ActionSheet(
    title: Text("你想在这个页面放点啥?弹出一个提示,还可以修改信息等操作"),
    message: Text("如果要关闭此页只需要向下滑动或者点击下面的按钮..."),
    buttons: [.default(Text("关闭此面"))]
    )
    }
  5. popover

popover是一个专用的修改器来显示弹出窗口,在iPadOS上它显示为浮动气球,而在iOS上则像一张纸一样滑到屏幕上。

要显示弹出窗口,您需要某种状态来确定该弹出窗口当前是否可见,但仅此而已–与警报和操作表不同,弹出窗口可以包含所需的任何视图。因此,只要将您需要的任何东西放在弹出窗口中,SwiftUI就会处理其余的工作。

例如,当点击一个按钮时,将显示一个弹出视图:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
struct ContentView: View {
@State private var showingPopover = false
var body: some View {
Button("显示菜单") {
showingPopover = true
}
.popover(isPresented: $showingPopover) {
Text("你要的内容在这里!")
.font(.headline)
.padding()
}
}
}

  1. alert
    1
    Alert(title: Text("弹出的标题!"), message: Text("这是消息的内容"), dismissButton: .default(Text("OK")))

参考资料:
http://www.neter8.com/ios/127.html