如何有一个A-Z索引与NSFetchedResultsController [英] How to have a A-Z index with a NSFetchedResultsController
问题描述
我使用NSFetchedResultsController作为我的表视图,我想有一个索引A-Z。
问题是,如果我使用我想要的部分的实体的属性,它会返回尽可能多的部分,因为这个属性有不同的名称。
所以我想在NSManagedObject子类中添加另一个属性。这个属性只会是另一个的第一个字母。
所以我发现这个主题,其中他们解释如何做,但:
- 这是一个很老的,所以我想知道如果没有任何更好的选择现在
- 它在Objective-C,我必须承认,我不真的掌握这种语言。
虽然我试图做他们说的做,但它不工作。
class Currency:NSManagedObject {
@NSManaged var country:String
@NSManaged var code:String
func firstLetterCodeForSection() - >字符串{
self.willAccessValueForKey(firstLetterCodeForSection)
var tempString = self.valueForKey(code)!。uppercaseString
tempString.removeRange(Range(start:tempString.startIndex, (b)
func firstLetterCountryForSection() - > String {
self.willAccessValueForKey(firstLetterCountryForSection)
var tempString = self.valueForKey(country)!。uppercaseString
tempString.removeRange(Range(start:tempString.startIndex, ($ temp)
/ pre>
我设置 firstLetterCountryForSection
和 firstLetterCodeForSection
在实体
这里是我的NSFetchedResultsController:
fetchedResultsController = NSFetchedResultsController(fetchRequest:fetchRequest,managedObjectContext:managedContext,sectionNameKeyPath:firstLetterCountryForSection,cacheName:nil)
排序是基于代码
还是国家
。
...
我错过了什么或做错了什么?
感谢您的帮助!
更新:
我发现问题,我是把第一个字母子字符串,我实际上保留除第一个字母之外的所有字母...
我替换了
tempString.removeRange(Range(start:tempString.startIndex,end:advance(tempString.startIndex,1)))
由
tempString.removeRange(Range(start:advance tempString.startIndex,1),end:tempString.endIndex))
但现在我有另一个问题。我试过:
func firstLetterCountryForSection() - > String {}
var firstLetterCountryForSection:String {}
动态var firstLetterCountryForSection:String? {}
,结果是一样的,它的工作(至少它看起来像)。有什么不同?
再次感谢
解决方案当您应该使用动态变量时,尝试使用函数计算节:
dynamic var section:String? {
let characters = Array(code.uppercaseString)
返回字符[0]
}
,然后您的 fetchedResultsController
应如下所示:
fetchedResultsController = NSFetchedResultsController(fetchRequest:fetchRequest(),managedObjectContext:managedObjectContext !, sectionNameKeyPath:section,cacheName:root)
有关设置临时属性的详细信息,请参阅我的回答此处。
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
解决方案 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.
这篇关于如何有一个A-Z索引与NSFetchedResultsController的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!