为A到Z UITableView滚动添加节索引标题

时间:2016-01-19 23:34:43

标签: swift uitableview uiscrollview

我正在尝试为联系人表视图添加一些节标题。我在Array中有一个联系人列表,可能是这样的:

比尔Apple 波拉特
史蒂夫测试

我添加了以下内容:

func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    let currentCollation = UILocalizedIndexedCollation.currentCollation() as UILocalizedIndexedCollation
    let sectionTitles = currentCollation.sectionTitles as NSArray
    return sectionTitles.objectAtIndex(section) as? String
}

func sectionIndexTitlesForTableView(tableView: UITableView) -> [String]? {
    let currentCollation = UILocalizedIndexedCollation.currentCollation() as UILocalizedIndexedCollation
    return currentCollation.sectionIndexTitles as [String]
}

func tableView(tableView: UITableView, sectionForSectionIndexTitle title: String, atIndex index: Int) -> Int {
    let currentCollation = UILocalizedIndexedCollation.currentCollation() as UILocalizedIndexedCollation
    return currentCollation.sectionForSectionIndexTitleAtIndex(index)
}

这会让A-Z标题显示出来。但是,由于只有一个部分和一个数组来保存联系人,因此实际功能不起作用。

我们是否应该将Array排序为某种字母的Array?这样它有多个部分?或者有更简单的方法来解决这个问题吗?

3 个答案:

答案 0 :(得分:5)

  

我们是否应该将Array排序为某种字母数组?所以它有多个部分?

您添加了部分索引的委托方法,但您没有显示实际执行整理的任何代码。

此处的some sample code from NSHipster显示了如何使用UILocalizedIndexedCollation将对象数组(例如,联系人)整理成对象的一系列对象(例如,按部分分组的联系人):< / p>

let collation = UILocalizedIndexedCollation.currentCollation()
var sections: [[AnyObject]] = []
var objects: [AnyObject] = [] {
    didSet {
        let selector: Selector = "localizedTitle"
        sections = Array(count: collation.sectionTitles.count, repeatedValue: [])

        let sortedObjects = collation.sortedArrayFromArray(objects, collationStringSelector: selector)
        for object in sortedObjects {
            let sectionNumber = collation.sectionForObject(object, collationStringSelector: selector)
            sections[sectionNumber].append(object)
        }

        self.tableView.reloadData()
    }
}

您还希望更新剩余的tableView委托以使用sections数组:

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return sections.count
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return sections[section].count
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let contact = sections[indexPath.section][indexPath.row]
    ...
} 

仅供参考,您可以通过将collat​​ion属性分配给视图控制器来简化代理代码,而不是在每个委托方法中为(当前)排序规则重复声明局部变量。例如:

override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String {
    return collation.sectionTitles[section]
}

答案 1 :(得分:1)

如果您在与显示器类似的结构中准备数据,则tableview非常易于处理。

如您所知,您没有收到委托中的节头,而是IndexPath。因此,最方便的是重构您的数据以便IndexPath可以访问。

  • 将数据列表保留在后备存储中,该后备存储不直接用于表视图。这可以是用于在线应用程序的服务器,也可以是用于脱机应用程序的托管数据,或者如果数据不是太大则保存在内存中。后备存储优化用于搜索和过滤。
  • 为各个部分创建[ESSM #"job number here" 0]。在订购您的桌子时订购数组。
  • 在每个NSArray<DataNode*>中,你有元数据,如节的标题,折叠信息等和真实数据,如节标题节点(如果有这样的东西)和子节点作为DataNode地址的部分。再次按照您希望的方式进行排序。

所有委托功能现在都是一块蛋糕,或多或少地减少到

NSArray<DataNode*>

如果你有一个&#34; live-filter&#34;函数,用户键入几个字符,并且您希望将列表缩减为匹配项,实际上是从原始数据列表重建tableData.count // count of sections tableData[indexPath.section] // section header data tableData[indexPath.section].children.count // rows in section tableData[indexPath.section].children[indexPath.row] // row data 列表。

DataNode

在后台运行数据搜索和重组,并将带有NotificationCenter的新列表发送给代表。

代表将捕获更新的列表并将其放置到-(void) buildSearchresult:(NSString *)criteria { NSArray *result = [backingListService findWithCriteria:criteria]; NSArray *nodes = [displayListService structureResult:result withOption:OPTAlphaSort]; [[NotificationCenter defaultCenter] postNotification:@"listUpdate" object:nodes]; }

的位置
[self.tableView reloadData]

我就是这样做的: - )

答案 2 :(得分:0)

你好@StuartM这是Objective-C中的一个例子,你可以在Swift中重写。我发布它是因为这个算法运作良好。正如您所看到的,在UITableView的委托的numberOfsectionsInTableView中调用algo,因此索引每次都会重新计算,因为索引和节数取决于数组的内容。

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    // Create sections from raw list of all objects
    return [self numberOfsectionForObjectsList];
}


- (NSInteger)numberOfsectionForObjectsList
{

    NSMutableArray *tempAllObjects = [[NSMutableArray alloc] init];
    NSMutableArray *tempDigitsSection = nil;
    NSMutableArray *tempLetterSection = nil;
    NSMutableArray *tempIndex = [[NSMutableArray alloc] init];
    BOOL digitIndexCreated = NO;
    NSString *currentLetter = nil;

    for (id *object in allObjectsList)
    {
        if ([object login].length > 0)
        {
            NSString *firstLetter = [[object login] substringToIndex:1];
            NSCharacterSet *notDigits = [[NSCharacterSet decimalDigitCharacterSet] invertedSet];
            if ([firstLetter rangeOfCharacterFromSet:notDigits].location == NSNotFound) // firstLetter is a digit, not a letter
            {
                if (digitIndexCreated == NO)
                {
                    [tempIndex insertObject:@"#" atIndex:0];
                    tempDigitsSection = [[NSMutableArray alloc] init];
                    digitIndexCreated = YES;
                }

                [tempDigitsSection addObject:object];
            }
            else // firstLetter is a letter, not a digit
            {
                if ([firstLetter caseInsensitiveCompare:currentLetter] == NSOrderedSame) // Always the same first letter = same section
                {
                    [tempLetterSection addObject:object];
                }
                else // New first letter = new section
                {
                    if (tempLetterSection == nil)
                    {
                        tempLetterSection = [[NSMutableArray alloc] init];
                        [tempIndex addObject:[firstLetter uppercaseString]];
                    }
                    else
                    {
                        [tempAllObjects addObject:[tempLetterSection copy]];
                        [tempIndex addObject:[firstLetter uppercaseString]];
                        tempLetterSection = nil;
                        tempLetterSection = [[NSMutableArray alloc] init];
                    }

                    [tempLetterSection addObject:object];
                    currentLetter = firstLetter;
                }
            }
        }
    }

    if (tempDigitsSection != nil)
    {
        [tempAllObjects insertObject:tempDigitsSection atIndex:0];
    }
    if (tempLetterSection != nil)
    {
        [tempAllObjects addObject:tempLetterSection];
    }

    indexesList = [tempIndex copy];
    allObjectsList = nil;
    allObjectsList = [tempAllObjects copy];

    if ([allObjectsList count] > 0)
    {
        return [allObjectsList count];
    }
    else
    {
        return 1;
    }
}

我希望这可以帮助你,即使它可以被优化^^