【问题标题】:Getting information to pass between TableViewControllers once an event date has passed - Swift一旦事件日期过去,获取在 TableViewControllers 之间传递的信息 - Swift
【发布时间】:2018-11-01 20:30:46
【问题描述】:

我目前正在开发一个应用程序,该应用程序会在新音乐发布时通知用户。用户输入艺术家、专辑、发行日期(他们使用日期选择器选择日期)并将其保存到列表中。当天,他们收到通知说这张专辑今天发行。

一旦日期过去,我希望它脱离 FreshListTableViewController 并进入 ReleasedTableViewController。

感谢您的帮助。

下面是 FreshReleaseTableViewController 的代码:

 import UIKit
 import CoreData
 import UserNotifications

 class FreshReleaseTableViewController: UITableViewController{


    var freshreleases = [Release_Date]()

let dateFormatter = DateFormatter()

override func viewDidLoad() {
    super.viewDidLoad()

    //create a new button
    let button = UIButton.init(type: .custom)
    //set image for button
    button.setImage(UIImage(named: "Mic App Logo.png"), for: UIControlState.normal)

    dateFormatter.dateStyle = .full
    dateFormatter.timeStyle = .none


    //let button1 = UIButton()
    //button1.addTarget(self, action: #selector(editAction), for: .touchUpInside)

    //self.tableView.backgroundColor = UIColor.white

}


@objc func editAction() {
    let viewController = AddfreshreleaseViewController()
    navigationController?.present(viewController, animated: true, completion: nil)
}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)


    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let context = appDelegate.persistentContainer.viewContext

    let fetchRequest = Release_Date.fetchRequest() as NSFetchRequest<Release_Date>

    let sortDescriptor1 = NSSortDescriptor(key: "artist", ascending: true)
    let sortDescriptor2 = NSSortDescriptor(key: "album", ascending: true)
    fetchRequest.sortDescriptors = [sortDescriptor1, sortDescriptor2]
    do {
        freshreleases = try context.fetch(fetchRequest)
    } catch let error {
        print("Could not fetch because of error: \(error).")
    }
    tableView.reloadData()
}


// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    return freshreleases.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {



    let cell = tableView.dequeueReusableCell(withIdentifier: "FreshReleaseCellIdentifier", for: indexPath)

    let freshrelease = freshreleases[indexPath.row]

        cell.textLabel?.numberOfLines = 0


    let artist = freshrelease.artist ?? ""
    let album = freshrelease.album ?? ""
    cell.textLabel?.text = artist + "'s '\nnew album '" + album + "'\nreleases"

    if let date = freshrelease.release_date as Date? {
        cell.detailTextLabel?.text = dateFormatter.string(from: date)
    } else {
        cell.detailTextLabel?.text = ""
    }

    return cell
}


// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    // Return false if you do not want the specified item to be editable.
    return true
}



// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if freshreleases.count > indexPath.row {
        let freshrelease = freshreleases[indexPath.row]

        // Remove notification
        if let identifier = freshrelease.release_dateId {
            let center = UNUserNotificationCenter.current()
            center.removePendingNotificationRequests(withIdentifiers: [identifier])
        }


        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let context = appDelegate.persistentContainer.viewContext
        context.delete(freshrelease)
        freshreleases.remove(at: indexPath.row)
        do {
            try context.save()
        } catch let error {
            print("Could not save \(error)")
        }
        tableView.deleteRows(at: [indexPath], with: .fade)

    }

}



@available(iOS 11.0, *)

override func tableView(_ tableView: UITableView,
               leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?

{
    let modifyAction = UIContextualAction(style: .normal, title:  "Edit", handler: { (ac:UIContextualAction, view:UIView, success:(Bool) -> Void) in
        print("Update action ...")
        let MainStoryboard = UIStoryboard(name: "Main", bundle: Bundle.main)
        let vc : UIViewController = MainStoryboard.instantiateViewController(withIdentifier: "FreshReleaseEdit") as UIViewController
        self.present(vc, animated: true, completion: nil)
        success(true)

    })
    modifyAction.title = "Edit"
    modifyAction.backgroundColor = .blue


    return UISwipeActionsConfiguration(actions: [modifyAction])

}


/*
// Override to support rearranging the table view.
override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {

}
*/

override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
    return true
}

}

下面是 ReleasedTableViewController 的代码:

 import UIKit
 import CoreData
 import UserNotifications

 class ReleasedTableViewController: UITableViewController{

var freshreleases = [Release_Date]()

let dateFormatter = DateFormatter()

override func viewDidLoad() {
    super.viewDidLoad()

    //create a new button
    let button = UIButton.init(type: .custom)
    //set image for button
    button.setImage(UIImage(named: "Mic App Logo.png"), for: UIControlState.normal)



    dateFormatter.dateStyle = .full
    dateFormatter.timeStyle = .none

    //self.tableView.backgroundColor = UIColor.white

}

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    let appDelegate = UIApplication.shared.delegate as! AppDelegate
    let context = appDelegate.persistentContainer.viewContext

    let fetchRequest = Release_Date.fetchRequest() as NSFetchRequest<Release_Date>

    let sortDescriptor1 = NSSortDescriptor(key: "album", ascending: true)
    let sortDescriptor2 = NSSortDescriptor(key: "artist", ascending: true)
    fetchRequest.sortDescriptors = [sortDescriptor1, sortDescriptor2]
    do {
        freshreleases = try context.fetch(fetchRequest)
    } catch let error {
        print("Could not fetch because of error: \(error).")
    }
    tableView.reloadData()
}


// MARK: - Table view data source

override func numberOfSections(in tableView: UITableView) -> Int {
    // #warning Incomplete implementation, return the number of sections
    return 1
}

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    // #warning Incomplete implementation, return the number of rows
    return freshreleases.count
}

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {



    let cell = tableView.dequeueReusableCell(withIdentifier: "FreshReleaseCellIdentifier", for: indexPath)

    let freshrelease = freshreleases[indexPath.row]

    cell.textLabel?.numberOfLines = 0


    let artist = freshrelease.artist ?? ""
    let album = freshrelease.album ?? ""
    cell.textLabel?.text = artist + "'s \nnew album '" + album + "'\nreleases"

    if let date = freshrelease.release_date as Date? {
        cell.detailTextLabel?.text = dateFormatter.string(from: date)
    } else {
        cell.detailTextLabel?.text = ""
    }

    return cell
}


// Override to support conditional editing of the table view.
override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    // Return false if you do not want the specified item to be editable.
    return true
}



// Override to support editing the table view.
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if freshreleases.count > indexPath.row {
        let freshrelease = freshreleases[indexPath.row]

        // Remove notification
        if let identifier = freshrelease.release_dateId {
            let center = UNUserNotificationCenter.current()
            center.removePendingNotificationRequests(withIdentifiers: [identifier])
        }


        let appDelegate = UIApplication.shared.delegate as! AppDelegate
        let context = appDelegate.persistentContainer.viewContext
        context.delete(freshrelease)
        freshreleases.remove(at: indexPath.row)
        do {
            try context.save()
        } catch let error {
            print("Could not save \(error)")
        }
        tableView.deleteRows(at: [indexPath], with: .fade)

    }
}



@available(iOS 11.0, *)
override func tableView(_ tableView: UITableView,
                        leadingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration?



{
    let modifyAction = UIContextualAction(style: .normal, title:  "Update", handler: { (ac:UIContextualAction, view:UIView, success:(Bool) -> Void) in
        print("Update action ...")
        success(true)
    })
    modifyAction.title = "Edit"
    modifyAction.backgroundColor = .blue

    return UISwipeActionsConfiguration(actions: [modifyAction])
}

/*
 // Override to support rearranging the table view.
 override func tableView(_ tableView: UITableView, moveRowAt fromIndexPath: IndexPath, to: IndexPath) {

 }
 */

override func tableView(_ tableView: UITableView, canMoveRowAt indexPath: IndexPath) -> Bool {
    return true
}

}

【问题讨论】:

    标签: swift uitableview datepicker viewcontroller


    【解决方案1】:

    抱歉,您的问题需要进一步说明。

    根据你提到的:

    一旦日期过去,我希望它从 FreshListTableViewController 并进入 已发布TableViewController。

    你的意思是它目前没有更新吗?当我查看代码时,我看不到您提到的部分。意思是说,我看到您正在使用appDelegate.persistentContainer.viewContext,但没有看到更新以检查已发布的专辑。

    如果我的理解是正确的,您可能希望在您的 CoreData 中包含 release_date 属性,并在您的 CoreData 中按当前日期进行过滤。 如果您使用的是.xcdatamodeld 文件,请在存储日期的内部添加一个release_date 属性。

    在您的 FreshReleaseTableViewController 中,

    // ==== Filter by date
        let startOfToday = Calendar.current.startOfDay(Date()) as! NSDate
        var predicate = NSPredicate(format: "(your_date_attribute_name) > %@)", startOfToday)
        fetchRequest.predicate = predicate
    // ======
    

    ReleaseTableViewController 反之亦然,

    // ==== Filter by date
    let startOfToday = Calendar.current.startOfDay(Date()) as! NSDate
    var predicate = NSPredicate(format: "(your_date_attribute_name) < %@)", startOfToday)
    fetchRequest.predicate = predicate
    // ======
    

    【讨论】:

    • 是的,我正在为如何让它准确地做到这一点而苦苦挣扎。我没有任何更新来检查已发布的专辑。因此,当日期过去时,什么都没有发生,它只是继续坐在那张桌子上,但我希望它移动到另一张桌子上。我正在寻求整个过程的帮助。
    • 嘿@sckring,我已经编辑了我的答案,我认为您正在寻找什么?无论如何,我认为标签应该是 CoreData 而不是 TableVC。您应该使用 NSPredicate 获取您的 CoreData。
    • 谢谢,这很有道理。我假设代码在 viewWillAppear 函数下,因为那是我已经定义 fetchRequest 的地方?但是,我现在收到此错误 - 无法将类型“[NSPredicate]”的值分配给类型“NSPredicate?”
    • 抱歉回复晚了。我知道了。我的错。它可能只是在寻找一个 nspredicate 而不是数组。删除方括号。可能改用谓词。
    • 别担心,感谢您的帮助。我目前收到以下错误代码:2018-11-05 18:50:23.657088-0500 新版本 [12541:3087197] *** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“无法解析格式字符串 "'release_date' > %@)"'
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-25
    • 1970-01-01
    • 2012-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多