【问题标题】:Cocoa method to return a list of all letters in the current locale's alphabet?可可方法返回当前语言环境字母表中所有字母的列表?
【发布时间】:2010-07-01 20:09:41
【问题描述】:

我目前正在尝试使用delegate 和data source 实现UITableView,它尽可能接近地复制ABAddressBookUI 框架的ABPeoplePickerNavigationController 类的功能,但增加了以下功能:一次选择多个联系人(通过将附件视图添加/删除到相应的UITableViewCell 来指示)。

一切正常,除了为UITableView 提供本地化的“部分索引标题”(出现在屏幕右侧的滚动覆盖中的字母),应该由data source 返回方法:

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView

显然,我可以只返回一个包含 NSStrings A、B、C ...Z 的 NSArray,但理想情况下,我希望此方法返回所有(大写,如果适用)的数组当前语言环境的字母。

一个有希望的领先优势是:

[[NSLocalecurrentLocale ] objectForKey:@"NSLocaleExemplarCharacterSet" ]

但我找不到任何重要的文档,它返回一个 NSCharacterSet,我无法从中提取实际字符(如果我能做到,那么 NSCharacterSet 的 capitalizedLetterCharacterSet 也可能是有希望的起点)。

我还在AddressBookUI 框架上运行了otool -tV,它显示了对函数ABAddressBookCopySectionIndices() 的调用,可以将ABAddressBookRef 传递到该函数中以获得我正在寻找的确切内容……本地化字母表的 CFArray。 但是,这是一个私有函数,所以我不能在我的应用程序中使用它。

那么,有人知道 Cocoa Touch 是否支持这个功能吗?而且,如果没有,有没有关于ABAddressBookCopyIndices() 如何发挥其魔力的想法?我怀疑International Components for Unicode 库可能是关键,但我(目前)还不熟悉它的功能......

【问题讨论】:

标签: iphone objective-c cocoa-touch abaddressbook


【解决方案1】:

请不要假设部分索引应该是“大写字母”。这仅对某些欧洲语言有效。例如。日语或中文没有大写字母的概念,它们只是有太多的字母开头,但有一组习惯性的标签,通常用于现实世界的字典或现实世界的地址簿。

改为使用标准UILocalizedIndexedCollation。它完全满足您的需求。

【讨论】:

  • 非常感谢,宇治!我不敢相信我没有早点找到那门课。我用谷歌搜索了很多不同的短语来试图找到这个,但我想“整理”是我需要的。我知道许多语言中不存在大写字母,这就是为什么我在原始帖子中将大写字母放在括号中。我现在对其进行了编辑以使其更清晰。再次感谢。
  • 不客气 :) 请制作一个适用于任何语言的应用程序!
  • 但现在我在 SO 中发现了这个令人担忧的帖子:stackoverflow.com/questions/2909084/… 显然该方法存在,但尚未正确实施。天哪。
  • 很好的发现。在这种情况下,ABAddressBookCopySectionIndices() 中可能会发生一些更复杂的事情,因为我可以 NSLog() 返回的数组,它与系统通讯簿中显示的内容完全匹配。明天我会玩 UILocalizedIndexedCollat​​ion 并报告(因为我猜这有可能在 iOS 4 中得到修复)。要是我们被允许使用私有 API 就好了!
  • 该函数可能使用了 CLDR 的“索引字符”,正如我在这里描述的:stackoverflow.com/questions/1542781
【解决方案2】:

无聊就写给你

NSArray * charactersInCharacterSet(NSCharacterSet *charSet)
{
  NSMutableArray * array = [NSMutableArray array];
  NSData * data = [charSet bitmapRepresentation];
  const char* bytes = [data bytes];

  for (int i = 0; i < 8192; ++i)
  {
    if (bytes[i >> 3] & (((unsigned int)1) << (i & 7)))
    {
      [array addObject:[NSString stringWithFormat:@"%C", i]];
    }
  }
  return [NSArray arrayWithArray:array];
}

NSCharacterSet * charSet = [[[[NSLocale alloc] initWithLocaleIdentifier:@"sr_Cyrl_ME"] autorelease] objectForKey:NSLocaleExemplarCharacterSet];
NSArray * chars = charactersInCharacterSet(charSet);
for (NSString *str in chars)
{
  NSLog(@"%@", str);
}

这将为您提供集合中的字符数组。

【讨论】:

  • 请怜悯东亚人,不要使用它 :p 它会给出一个包含数千个字母的列表,使用频率差异很大;如果您将每 100 个元素作为部分标题,那将只选择很少使用的字符,这将完全没有用。
  • 我并没有真正回答这里的“真实”问题。但我回答了他的子问题。你的回答肯定更符合他的需要。
  • 非常感谢,乔希!那里的工作很棒。我对此表示赞同,因为我想说它提供了一些非常有用的功能,但我希望你不介意我接受 Yuji 的回答,因为它完美地回答了主要问题。
  • 没问题 :) 我实际上做了更多的测试,但在亚洲字符集之类的东西上失败得很厉害。用日本语言环境试了一下,结果是空的。需要一些爱才能使其正常工作。
猜你喜欢
  • 1970-01-01
  • 2020-05-01
  • 2019-02-02
  • 2020-07-25
  • 2019-05-21
  • 1970-01-01
  • 2011-06-06
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多