Как реплицировать метки времени звонка iPhone Недавние звонки - PullRequest
0 голосов
/ 29 ноября 2011

Допустим, что мой UITableView заполняется массивом X количества NSDates.Как я могу отсортировать их так, чтобы UITableView имитировал приложение Phone на iPhone, но таким образом, чтобы в UITableView был раздел для каждого дня, который представлен датой (или несколькими датами) в массиве?

Редактировать: Прорыв!Чтобы выяснить, сколько разделов мне нужно, я использую это:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    NSArray* array = [[NSUserDefaults standardUserDefaults] objectForKey:@"mapSaveDataKey"];
    NSMutableArray* dateStrings = [[NSMutableArray alloc] init];
    for(NSArray* innerArray in array)
        [dateStrings addObject:[dateFormatter stringFromDate:[innerArray objectAtIndex:13]]];

    NSArray *cleanedArray = [[NSSet setWithArray:dateStrings] allObjects];

    return [cleanedArray count];
}

Взяв массив строк DateStrings, отформатированных NSDates, используя NSDateFormatter со следующими настройками:

[dateFormatter setTimeStyle:NSDateFormatterNoStyle];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setDoesRelativeDateFormatting:YES];

Iможет получить список строковых дат, причем каждая строка в один и тот же день одинакова независимо от времени.Затем я могу использовать NSSet для получения массива с теми же строками, исключая дубликаты, и счетчик этого массива - это количество секций, которое мне нужно.Отлично.

Теперь перейдем к самой трудной части: как я могу взять этот массив строк (или исходный массив NSDates) и выяснить, сколько дубликатов есть на каждый день, и использовать эту информацию, чтобы решить, сколько строкнужны в каждом разделе UITableView?И чтобы сделать вещи более сложными, их нужно заказывать от недавнего к старому.(Существует также вопрос выяснения, какие ячейки должны идти в каком разделе, но это можно выяснить позже)

Решено благодаря красноречивому решению от Оле Бегеманна.+100 к вам Я использую этот цикл, чтобы выяснить, когда в моем массиве мне нужно начинать для каждого раздела:

int offset = 0;
for(int idx = 0; idx < [tableViewOutlet numberOfSections]; idx++) {
    if(idx == indexPath.section)
        break;
    offset += [tableViewOutlet numberOfRowsInSection:idx];
}

Ответы [ 2 ]

2 голосов
/ 01 декабря 2011

Лично я бы не использовал форматеры даты.Обработка строк выглядит несколько «грязно», если у вас есть больше «числовых» значений (дат).Используя NSDateComponents, также легко отделить дату от временных составляющих NSDate.Следующий пример кода довольно длинный, но он должен быть простым для понимания.Учитывая массив (выборка) NSDate объектов (в переменной dates), он генерирует словарь sections.

Ключами словаря являются NSDate экземпляры, которые представляют определенный деньих компонент времени - mignight в часовом поясе используемого календаря).Значения словаря - это массивы, содержащие фактические даты, которые относятся к определенному разделу (отсортированы).Вы должны быть в состоянии заполнить табличное представление этой информацией.

// Sample data: an array of dates
NSArray *dates = [NSArray arrayWithObjects:
    [NSDate dateWithTimeIntervalSince1970:1322756697],
    [NSDate dateWithTimeIntervalSince1970:1322727896],
    [NSDate dateWithTimeIntervalSince1970:1322699096],
    [NSDate dateWithTimeIntervalSince1970:1322695496],
    [NSDate dateWithTimeIntervalSince1970:1322677496],
    [NSDate dateWithTimeIntervalSince1970:1322504696],
    nil];

// First we sort the dates
NSArray *sortedDates = [dates sortedArrayUsingSelector:@selector(compare:)];

NSCalendar *calendar = [NSCalendar currentCalendar];
NSTimeZone *utc = [NSTimeZone timeZoneForSecondsFromGMT:0];
[calendar setTimeZone:utc];

// Populate the sections dictionary
NSMutableDictionary *sections = [NSMutableDictionary dictionary];
for (NSDate *date in sortedDates) {
    NSDateComponents *dateComps = [calendar components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit fromDate:date];
    NSDate *dateRepresentingThisDay = [calendar dateFromComponents:dateComps];
    NSMutableArray *datesOnThisDay = [sections objectForKey:dateRepresentingThisDay];
    if (datesOnThisDay == nil) {
        // This day is new.
        // Create an empty array and add it to the dictionary under this day as key.
        datesOnThisDay = [NSMutableArray array];
        [sections setObject:datesOnThisDay forKey:dateRepresentingThisDay];
    }
    [datesOnThisDay addObject:date];
}

// Output the result    
NSLog(@"Found %u sections.", [sections count]);
NSArray *sortedDays = [[sections allKeys] sortedArrayUsingSelector:@selector(compare:)];
for (NSDate *day in sortedDays) {
    NSLog(@"Section: %@", day);
    NSArray *datesOnThisDay = [sections objectForKey:day];
    for (NSDate *date in datesOnThisDay) {
        NSLog(@"-- Entry: %@", date);
    }
}

Редактировать: я использовал этот вопрос как возможность написать в блоге об этой проблеме .

0 голосов
/ 01 декабря 2011

Я действительно думаю, что вы должны использовать базовые данные и NSFetchResultController, он сделает всю работу за вас -

Будет долго объяснять все необходимые шаги, но в строках -

  1. Добавьте основные данные в ваше приложение.
  2. Создайте класс и базовый объект данных, например, с именем (Date).
  3. Установите свойства для объекта (например, «текст»)., "дата" и т. д.).
  4. Выполните итерацию вашего массива и создайте сущность для каждого объекта в массиве, которая будет содержать дату объекта. (Вы можете сделать это в обеденном приложении или в любом другомвремя, подходящее для вашего приложения)
  5. Теперь, когда у вас есть готовые сущности, вы можете использовать NSFetchResultController для настройки представления таблицы.
  6. Вам потребуетсяпередайте свойство date в операцию выборки как sectionNameKeyPath , это сообщит контроллеру результатов выборки, что вы хотите отсортировать разделы по дате.

    aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:YourContext sectionNameKeyPath:@"date" cacheName:nil];
    
  7. тогда вам нужно будет добавить эти функцииИоны к вашему виду таблицы, они сделают всю работу за вас:

        - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
            NSInteger count = [[[self fetchedResultsController] sections] count];
            return count;
       }
    
        - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
           NSInteger numberOfRows = 0;
    
          if ([[[self fetchedResultsController] sections] count] > 0) {
           id <NSFetchedResultsSectionInfo> sectionInfo = [[[self fetchedResultsController] sections] objectAtIndex:section];
           numberOfRows = [sectionInfo numberOfObjects];
          }
    
         return numberOfRows;
        }
    
        - (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView {
          return [[self fetchedResultsController] sectionIndexTitles];
        }
    
        - (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index {
          return [[self fetchedResultsController] sectionForSectionIndexTitle:[title capitalizedString] atIndex:index];
         }
    
        - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section { 
             id <NSFetchedResultsSectionInfo> sectionInfo = [[[self fetchedResultsController] sections] objectAtIndex:section];
            return [sectionInfo name];
         }
    

Вы можете увидеть пример от Apple здесь: http://developer.apple.com/library/ios/#samplecode/DateSectionTitles/Introduction/Intro.html

Надеюсь, что это будетпомощь

...