2016-09-24 138 views
0

我有一個應用程序,記錄每月的開支。我有一個費用實體與屬性,跟蹤當前月費用創建。然後我會在表格視圖中顯示每月的費用,如下所示。用戶只能轉左,右僅當在未來或過去的一個月如何用Swift處理空對象?

@IBAction func backMonthButtonPressed(sender: AnyObject) { 
    print("Back Button Pressed") 
    currentMonth = NSCalendar.currentCalendar().dateByAddingUnit(.Month, value: -1, toDate: currentMonth, options: [])! 
    if checkMonth(currentMonth) { 
     updateFetch() 
     setMonth() 
    } else { 
     currentMonth = NSCalendar.currentCalendar().dateByAddingUnit(.Month, value: 1, toDate: currentMonth, options: [])! 
    } 
    tableView.reloadData() 

} 

@IBAction func nextMonthButtonPressed(sender: AnyObject) { 

    print("Next Button Pressed") 

    currentMonth = NSCalendar.currentCalendar().dateByAddingUnit(.Month, value: 1, toDate: currentMonth, options: [])! 
    if checkMonth(currentMonth) { 
     updateFetch() 
     setMonth() 
    } else { 
     currentMonth = NSCalendar.currentCalendar().dateByAddingUnit(.Month, value: -1, toDate: currentMonth, options: [])! 
    } 
    tableView.reloadData() 
} 

func checkMonth(month : NSDate) -> Bool { 
    let app = UIApplication.sharedApplication().delegate as! AppDelegate 
    let context = app.managedObjectContext //scratch pad 

    let fetchRequest = NSFetchRequest(entityName: "Expense") 
    fetchRequest.predicate = NSPredicate(format: "month == %@", month.MonthYearDateFormatter()) 
    let count = context.countForFetchRequest(fetchRequest, error: nil) 
    if count > 0 { 
     print("There are expenses for this month \(month.MonthYearDateFormatter()). Show expenses") 
     return true 

    } else { 
     print("There are no expenses for this month \(month.MonthYearDateFormatter()). Do Nothing") 
     return false 
    } 
} 

我的問題是支出是這樣的,在用戶創建的費用在6月份並沒有創造不可能的情況8月份的費用。我如何讓用戶在8月份仍然可以看到他/她的費用而不會跳過它。有任何想法嗎?

+0

立即獲取所有費用並將它們存儲在數組中,並按月排序。然後只需瀏覽數組 – Paulw11

回答

1

我做了闡述之前的一些優化:

@IBAction func backMonthButtonPressed(sender: AnyObject) { 
    self.processMonth(step: -1) 
} 

@IBAction func nextMonthButtonPressed(sender: AnyObject) { 
    self.processMonth(step: 1) 
} 

// a method uses almost the same code for both cases, so it was merged 
func processMonth(step: Int) { 
    let direction = (step < 1 ? "Back" : "Next") 
    print("\(direction) Button Pressed") 

    currentMonth = NSCalendar.currentCalendar().dateByAddingUnit(.Month, value: step, toDate: currentMonth, options: [])! 

    //if checkMonth(currentMonth) { 
    // I wouldn't test this because it locks you out from seeing empty month. 
     updateFetch() 
     setMonth() 
    //} 

    tableView.reloadData() 
} 

的答案是什麼你究竟問:

如果您的UITableView數據源設置正確,你應該能夠去通過空個月,雖然

// changed return type from `Bool` to `void` as I suggested in the method not to test empty month, as it could be useless 

func checkMonth(month : NSDate) { 
    let app = UIApplication.sharedApplication().delegate as! AppDelegate 
    let context = app.managedObjectContext //scratch pad 

    let fetchRequest = NSFetchRequest(entityName: "Expense") 
    fetchRequest.predicate = NSPredicate(format: "month == %@", month.MonthYearDateFormatter()) 
    let count = context.countForFetchRequest(fetchRequest, error: nil) 
    if count > 0 { 
     print("There are expenses for this month \(month.MonthYearDateFormatter()). Show expenses") 

    } else { 
     print("There are no expenses for this month \(month.MonthYearDateFormatter()). Do Nothing") 
     // here you can make some additional actions, like seeting the empty table with "no expenses this month" 
    } 
} 

無論如何,@ Paulw11注意,如果您的數據源不是大小疲憊,您可以在viewDidLoad/viewDidAppear中獲取數據模型中的數據,然後根據currentMonth變量(關於用戶當前看到的月份)每月呈現數據。

因此,您只需在控制器的加載和每次用戶更改當前月視圖時調用setMonth()方法。

0

在@ Paulw11和@pedrouan的幫助下,我能夠做我想做的事。

抓取所有費用

func fetchExpenses() { 
    let app = UIApplication.sharedApplication().delegate as! AppDelegate 
    let context = app.managedObjectContext //scratch pad 
    let fetchRequest = NSFetchRequest(entityName: "Expense") 

    //Always Sort Budget by the date it's created 
    let sortDescriptor = NSSortDescriptor(key: "created", ascending: true) 
    fetchRequest.sortDescriptors = [sortDescriptor] 

    do { 
     let results = try context.executeFetchRequest(fetchRequest) 
     self.expenses = results as! [Expense] 
    } catch let err as NSError { 
     print(err.debugDescription) 
    } 
} 

設置約束,第一個和最後一個月以確定從過去的第一個和最後一個月

去多遠,用戶可以在viewDidLoad中通過幾個月導航

//If array is not empty, set first and last month 
    if expenses.count > 0 { 
     guard let first = expenses.first?.month else { 
      return 
     } 
     firstMonth = first 

     guard let last = expenses.last?.month else { 
      return 
     } 
     lastMonth = last 

    }else { 
     //Set current month to be first and last 
     firstMonth = currentMonth.MonthYearDateFormatter() 
     lastMonth = currentMonth.MonthYearDateFormatter() 
    } 

限制用戶

@IBAction func backMonthButtonPressed(sender: AnyObject) { 
    print("Back Button Pressed") 
    if currentMonth.MonthYearDateFormatter() != firstMonth { 
     self.processMonth(step: -1) 
    } 
} 

@IBAction func nextMonthButtonPressed(sender: AnyObject) { 

    print("Next Button Pressed") 
    if currentMonth.MonthYearDateFormatter() != lastMonth { 
     self.processMonth(step: 1) 
    } 
} 

返回當月的所有費用,如果有n一個清除提取並返回空表。

func updateFetch() { 
    setFetchResults() 

    do { 
     try self.fetchedResultsController.performFetch() 
    } catch { 
     let error = error as NSError 
     print("\(error), \(error.userInfo)") 
    } 
} 


func setFetchResults() { 

    let app = UIApplication.sharedApplication().delegate as! AppDelegate 
    let context = app.managedObjectContext //scratch pad 

    //Fetch Request 
    let fetchRequest = NSFetchRequest(entityName: "Expense") 

    let sortDescriptor = NSSortDescriptor(key: "created", ascending: false) 

    fetchRequest.predicate = NSPredicate(format: "month == %@", currentMonth.MonthYearDateFormatter()) 
    fetchRequest.sortDescriptors = [sortDescriptor] 
    let count = context.countForFetchRequest(fetchRequest, error: nil) 


    let controller = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: ad.managedObjectContext , sectionNameKeyPath: section, cacheName: nil) 

    //If there is none, empty fetch request 
    if count == 0 { 
     print("There are no expenses for this month. Show nothing") 
     controller.fetchRequest.predicate = NSPredicate(value: false) 
    } else { 
     print("There are expenses for this month. Show expenses") 
    } 

    fetchedResultsController = controller 
    controller.delegate = self 
} 

隨着pedroruan的processMonth(),我是能夠通過空tableViews導航,使用戶可以看到,八月是空的,同時仍然能夠去六月的月份。多謝你們。