How to have a A-Z index with a NSFetchedResultsController

最后都变了- 提交于 2020-02-04 12:51:35

问题


I'm using a NSFetchedResultsController for my table view and I would like to have an index A-Z.

The problem is that if I use the entity's attribute for which I want to have section, it will return as many section as there are different names for this attribute.

So I was thinking to add another attribute in my NSManagedObject subclass. This attribute would be only the first letter of the other one.

So I found out this topic where they explain how to do it but:

  • it's an pretty old one so I was wondering if there were not any better option now
  • it's in Objective-C and I have to confess that I don't really master this language.

Although I tried to do what they said to do but it didn't work.

class Currency: NSManagedObject {

    @NSManaged var country: String
    @NSManaged var code: String

    func firstLetterCodeForSection() -> String {
        self.willAccessValueForKey("firstLetterCodeForSection")
        var tempString = self.valueForKey("code")!.uppercaseString
        tempString.removeRange(Range(start: tempString.startIndex, end:advance(tempString.startIndex, 1)))
        self.didAccessValueForKey("firstLetterCodeForSection")
        return tempString
    }

    func firstLetterCountryForSection() -> String {
        self.willAccessValueForKey("firstLetterCountryForSection")
        var tempString = self.valueForKey("country")!.uppercaseString
        tempString.removeRange(Range(start: tempString.startIndex, end:advance(tempString.startIndex, 1)))
        self.didAccessValueForKey("firstLetterCountryForSection")
        return tempString
    }
}

I set firstLetterCountryForSection and firstLetterCodeForSection as transient in the entity

And here is my NSFetchedResultsController:

fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managedContext, sectionNameKeyPath: "firstLetterCountryForSection", cacheName: nil)

The sort is based whether on code or on country.

And... it doesn't work...

Am I missing something or doing something wrong?

Thanks for your help!

UPDATE:

I found the problem, it came from the line where I was substringing the first letter, I was actually keeping all the letters except the first one...

I replaced

tempString.removeRange(Range(start: tempString.startIndex, end:advance(tempString.startIndex, 1)))

by

tempString.removeRange(Range(start: advance(tempString.startIndex, 1), end:tempString.endIndex))

But now I have another questions. I tried it with:

func firstLetterCountryForSection() -> String { }

var firstLetterCountryForSection: String { }

dynamic var firstLetterCountryForSection: String? { }

and the result is the same, it's working (at least it looks like it). What's the difference? What's the best one to use?

Thanks again


回答1:


You're trying to use a function to calculate the section when you should be using a dynamic variable:

dynamic var section: String? {
    let characters = Array(code.uppercaseString)
    return characters[0]
}

and then your fetchedResultsController should look like this:

fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest(), managedObjectContext: managedObjectContext!, sectionNameKeyPath: "section", cacheName: "Root")

See my answer here for more info on setting up transient properties.



来源:https://stackoverflow.com/questions/28630745/how-to-have-a-a-z-index-with-a-nsfetchedresultscontroller

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!