斯威夫特:无法弄清楚如何保存用户离开表格视图的方式

Posted

技术标签:

【中文标题】斯威夫特:无法弄清楚如何保存用户离开表格视图的方式【英文标题】:Swift: Can't figure out how to save how user left tableview 【发布时间】:2017-06-08 22:19:29 【问题描述】:

使用 Swift 3

我已经在博客阅读器应用程序上工作了一段时间,但我一直被困在如何保存 tableview 就像用户离开它一样。

该应用程序通过我将数据输入到 mysql 数据库中来工作,该数据库使用 php 发送并使用 json 和 swift 3 接收以填充 tableview。我希望每天更新这个数据库。 tableview 中有两个部分,顶部的一个是 followArray,第二个是 mainArray,这是所有对象在 jsonArray 之后所在的位置。当用户单击关注按钮时,该单个单元格将移动到 followArray 中,用户可以在其中看到正在更新的博客并接收通知。

我尝试通过将整个数组保存到一个对象中来使用 UserDefaults,但它没有成功,因为当不需要保存整个数组时,使用 NSCoding 创建 NSData 对象是一种复杂的方式(我的猜测)。

我的问题,有没有一种简单的方法可以保存用户离开表格视图的方式?

例如:在“所有对象部分”中,假设我有 3 个单元格,用户单击 2 个单元格上的关注按钮,这 2 个单元格现在位于“已关注部分”中,其中 1 个单元格在“所有对象部分”中.如何保存此 tableview 的状态。我想保存被关注的单元格现在位于哪个部分以及更改后的按钮现在是一个关注按钮而不是关注按钮(在我隐藏一个按钮以显示另一个按钮时保存隐藏的启用代码)。

我使用 UserDefaults 还是 CoreData?也许是 CocoaPod 库?我是保存整个数组还是只保存它的哪个部分和 .hidden 代码?更新和添加新对象将如何影响它?

我对 Swift 还很陌生,如果您能提供帮助,我们将不胜感激。您需要了解应用程序如何工作的任何代码,只需询问它,因为我不知道需要显示哪些代码。我知道您不应该要求提供代码,但是如果可以的话,那就太好了,因为我已经尝试了几个月但没有任何进展。谢谢!

这是我处理传入 json 数据的方式:

MainController.swift

var jsonArray: NSMutableArray = []
var mainArray = [Blog]()
var followedArray = [Blog]()
var filteredArray = [Blog]()

// Title for Header
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? 

    if !(searchController.isActive && searchController.searchBar.text != "") 

        if section == 0 
            return "Followed Blogs"
        
        else 
            return "All Blogs"
        
    
    return "Filtered Blogs"


// Number of Rows in Section
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 

    if !(searchController.isActive && searchController.searchBar.text != "") 

        if section == 0 

            return followedArray.count
        
        else if (section == 1) 

            return mainArray.count
        

    
    return filteredArray.count



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

    let CellIdentifier = "Cell"
    var cell = tableView.dequeueReusableCell(withIdentifier: CellIdentifier) as! CustomCell

    if cell != cell 
        cell = CustomCell(style: UITableViewCellStyle.default, reuseIdentifier: CellIdentifier)
    

    // Configuring the cell
    var blogObject: Blog

    if !(searchController.isActive && searchController.searchBar.text != "") 
        if indexPath.section == 0 
            blogObject = followedArray[indexPath.row] 
            cell.populateCell(blogObject, isFollowed: true, indexPath: indexPath, parentView: self)
        
        else if indexPath.section == 1 
            blogObject = mainArray[indexPath.row] 
            cell.populateCell(blogObject, isFollowed: false, indexPath: indexPath, parentView: self)
        
    
    else 
        blogObject = filteredArray[indexPath.row] 
        cell.populateCell(blogObject, isFollowed: false, indexPath: indexPath, parentView: self)
    

    return cell


@IBAction func followButtonClick(_ sender: UIButton!) 

    // Adding row to tag
    let buttonPosition = (sender as AnyObject).convert(CGPoint.zero, to: self.myTableView)
    if let indexPath = self.myTableView.indexPathForRow(at: buttonPosition) 

        // Showing Status Labels
        let cell = self.myTableView.cellForRow(at: indexPath) as! CustomCell
        cell.firstStatusLabel.isHidden = false
        cell.secondStatusLabel.isHidden = false

        // Change Follow to Following
        (sender as UIButton).setImage(UIImage(named: "follow.png")!, for: .normal)
        cell.followButton.isHidden = true
        cell.followedButton.isHidden = false

        // Checking wether to import from mainArray or filteredArray to followedArray
        if !(searchController.isActive && searchController.searchBar.text != "") 

            self.myTableView.beginUpdates()

            // ----- Inserting Cell to followedArray -----
            followedArray.insert(mainArray[indexPath.row], at: 0)
            myTableView.insertRows(at: [IndexPath(row: 0, section: 0)], with: .fade)

            // ----- Removing Cell from mainArray -----
            mainArray.remove(at: indexPath.row)
            let rowToRemove = indexPath.row
            self.myTableView.deleteRows(at: [IndexPath(row: rowToRemove, section: 1)], with: .fade)

            self.myTableView.endUpdates()

            myTableView.reloadData()
        
        else 

            self.myTableView.beginUpdates()

            // ----- Inserting Cell to followedArray -----
            let blogObject: Blog = filteredArray[indexPath.row]
            let indexOfObjectInArray = mainArray.index(of: blogObject)

            followedArray.insert(blogObject, at: 0)

            // ----- Removing Cell from filteredArray -----
            filteredArray.remove(at: indexPath.row)
            blogArray.remove(at: indexOfObjectInArray!)
            let rowToRemove = indexPath.row
            self.myTableView.deleteRows(at: [IndexPath(row: rowToRemove, section: 0)], with: .fade)

            self.myTableView.endUpdates()

            myTableView.reloadData()
        
    


func retrieveDataFromServer() 

    let getDataURL = "http://exampleblog.com/receiving.php"
    let url: NSURL = NSURL(string: getDataURL)!

    do 

        let data: Data = try Data(contentsOf: url as URL)
        jsonArray = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! NSMutableArray

        // Looping through jsonArray
        for i in 0..<jsonArray.count 

            // Create Blog Object
            let bID: String = (jsonArray[i] as AnyObject).object(forKey: "id") as! String
            let bName: String = (jsonArray[i] as AnyObject).object(forKey: "blogName") as! String
            let bStatus1: String = (jsonArray[i] as AnyObject).object(forKey: "blogStatus1") as! String
            let bStatus2: String = (jsonArray[i] as AnyObject).object(forKey: "blogStatus2") as! String
            let bURL: String = (jsonArray[i] as AnyObject).object(forKey: "blogURL") as! String
            // New
            let bType: String = (jsonArray[i] as AnyObject).object(forKey: "blogType") as! String
            let bDate: String = (jsonArray[i] as AnyObject).object(forKey: "blogDate") as! String
            let bPop: String = (jsonArray[i] as AnyObject).object(forKey: "blogPop") as! String

            // Add Blog Objects to mainArray
            mainArray.append(Blog(blogName: bName, andBlogStatus1: bStatus1, andBlogStatus2: bStatus2, andBlogURL: bURL, andBlogID: bID, andBlogType: bType, andBlogDate: bDate, andBlogPop: bPop))

        
    
    catch 
        print("Error: (Retrieving Data)")
    

    myTableView.reloadData()

CustomCell.swift - 如何填充单元格enter code here

class CustomCell: UITableViewCell 

@IBOutlet weak var firstStatusLabel: UILabel!
@IBOutlet weak var secondStatusLabel: UILabel!
@IBOutlet weak var followButton: UIButton!
@IBOutlet weak var followedButton: UIButton!

override func awakeFromNib() 
    super.awakeFromNib()

    self.followButton.isHidden = true
    self.followedButton.isHidden = true


func populateCell(_ blogObject: Blog, isFollowed: Bool, indexPath: IndexPath, parentView: Any) 

    // Loading Status Labels
    self.firstStatusLabel.text = blogObject.blogStatus1
    self.secondStatusLabel.text = blogObject.blogStatus2
    self.firstStatusLabel.isHidden = true
    self.secondStatusLabel.isHidden = true

    if isFollowed 
        self.followedButton.tag = indexPath.row
        self.followedButton.addTarget(parentView, action: #selector(MainController.followedButtonClick(_:)), for: .touchUpInside)

        self.followedButton.isHidden = false
        self.followButton.isHidden = true

        // Status Labels
        self.firstStatusLabel.isHidden = false
        self.secondStatusLabel.isHidden = false

    
    else 
        self.followButton.tag = indexPath.row
        self.followButton.addTarget(parentView, action: #selector(MainController.followButtonClick(_:)), for: .touchUpInside)

        self.followedButton.isHidden = true
        self.followButton.isHidden = false

        // Status Labels
        self.firstStatusLabel.isHidden = true
        self.secondStatusLabel.isHidden = true

    


博客.swift

class Blog: NSObject 

// Strings
var blogName: String?
var blogStatus1: String?
var blogStatus2: String?
var blogURL: String?
var blogID: String?
var blogType: String?
var blogDate: String?
var blogPop: String?

override init() 



// Converting Strings into Objects
init(blogName bName: String,
     andBlogStatus1 bStatus1: String,
     andBlogStatus2 bStatus2: String,
     andBlogURL bURL: String,
     andBlogID bID: String,
     andBlogType bType: String,
     andBlogDate bDate: String,
     andBlogPop bPop: String)

    super.init()

    self.blogName = bName
    self.blogStatus1 = bStatus1
    self.blogStatus2 = bStatus2
    self.blogURL = bURL
    self.blogID = bID
    self.blogType = bType
    self.blogDate = bDate
    self.blogPop = bPop



【问题讨论】:

【参考方案1】:

有很多不同的方法可以实现您想要的,无论是在本地还是远程存储信息。如果博客 ID 是唯一的,您可以将它们作为字符串数组存储在默认值中:

UserDefaults.standard.set(followedBlogIds, forKey: "followedBlogIds")

然后您可以随时抓住它们,只需确保适当地打开/投射它们:

if let storedBlogIds = UserDefaults.standard.object(forKey: "followedBlogIds") as? [String] 
    //filter your blogs by id and put them in the appropriate
    //arrays for your table

【讨论】:

我试过这样做,但 UserDefaults 只允许常规数组,而不是我在 mainArray 中使用的那种数组,还是我错了? 你是对的 - 忘了你仅限于 plist 项目!猜你必须走 NSCoding 路线才能使用默认值直接存储博客。使用用户默认值使用不同的解决方案进行编辑 使用 blogIds 很聪明,它们是独一无二的。如何使用 ids 来显示数组。我该怎么办? 在您的retrieveDataFromServer 方法中,只需检查博客ID 是否与任何存储的ID 匹配。如果是这样,将其附加到 followArray 而不是主数组

以上是关于斯威夫特:无法弄清楚如何保存用户离开表格视图的方式的主要内容,如果未能解决你的问题,请参考以下文章

“使用未解析的标识符”我一生都无法弄清楚发生了啥。 (Xcode,斯威夫特)

我做了一个表格视图,即使在应用程序关闭后如何保存项目?

斯威夫特:没有一个名为

表格视图不显示数据,为啥? (斯威夫特 3)

如何将 JSON 令牌保存到用户默认值,然后在不同的视图中使用它?斯威夫特 4

无法弄清楚如何返回部分视图而不是全部