Как сохранить обязательную часть подпредставления в mainview на основе выбора ячеек tableview - PullRequest
4 голосов
/ 28 октября 2011

В настоящее время я анализирую некоторый xml, который выглядит следующим образом

<Rows>
<Row MANUFACTURERID="76" MANUFACTURERNAME="Fondont" ISMANU="F" ISAUTO="F"/>
<Row MANUFACTURERID="18" MANUFACTURERNAME="Anti" ISMANU="T" ISAUTO="T"/>
</Rows>

Я анализирую его, чтобы получить массив словарей (в каждом словаре есть четыре значения строки).

Затем я передаю ManufacturerName моему методу startSortingTheArray следующим образом:

if (dataSetToParse == @"ICMfg") // ICMfg is a string passed to this view from the parent view cell selection enabling me to pass different data sets to this view
    {
       //Filter results (ISAUTO = T)
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%K like %@",@"ISAUTO",@"T"];
        NSArray *filteredArray = [myDataArray filteredArrayUsingPredicate:predicate];
        //Passes Manufacturer strigs over to startSortingtheArray method
        [self startSortingTheArray:[filteredArray valueForKey:@"MANUFACTURER"]];
    }

Таким образом, здесь все ManufacturerNames отправляются моему методу в виде массива строк.Затем я использую этот массив для настройки всех моих разделов / index-scroller.Метод ниже показывает, как я это делаю.

//method to sort array and split for use with uitableview Index
- (IBAction)startSortingTheArray:(NSArray *)arrayData
{
    //If you need to sort incoming array alphabetically use this line of code
    //TODO: Check values coming in for capital letters and spaces etc
    sortedArray = [arrayData sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
    //If you want the standard array use this code
    //sortedArray = arrayData;

    self.letterDictionary = [NSMutableDictionary dictionary];
    sectionLetterArray = [[NSMutableArray alloc] init];

    //Index scrolling Iterate over values for future use
    for (NSString *value in sortedArray) 
    {
        // Get the first letter and its associated array from the dictionary.
        // If the dictionary does not exist create one and associate it with the letter.
        NSString *firstLetter = [[value substringWithRange:NSMakeRange(0, 1)] uppercaseString]; //uppercaseString puts lowercase values with uppercase

        NSMutableArray *arrayForLetter = [letterDictionary objectForKey:firstLetter];
        if (arrayForLetter == nil) 
        {
            arrayForLetter = [NSMutableArray array];
            [letterDictionary setObject:arrayForLetter forKey:firstLetter];

            [sectionLetterArray addObject:firstLetter]; // This will be used to set index scroller and section titles
        }
        // Add the value to the array for this letter
        [arrayForLetter addObject:value];
    }      
    //Reload data in table
    [self.tableView reloadData];
}

отсюда я делаю несколько вещей, чтобы настроить таблицу после [self.tableView reloadData]; вызывается,главное, что я установил ячейку со строковыми значениями массива.

//Display cells with data
    NSArray *keys = [self.letterDictionary objectForKey:[self.sectionLetterArray objectAtIndex:indexPath.section]];
    NSString *key = [keys objectAtIndex:indexPath.row];

    cell.textLabel.text = key;

когда ячейка затем выбрана, строковое значение внутри ячейки затем отправляется обратно в главное представление и используется позжев качестве параметра поиска ... Дело в том, что я устанавливаю несколько параметров, которые будут использоваться в качестве одной строки поиска.

Оглядываясь на XML, который я проанализировал

<Rows>
    <Row MANUFACTURERID="76" MANUFACTURERNAME="Fondont" ISMANU="F" ISAUTO="F"/>
    <Row MANUFACTURERID="18" MANUFACTURERNAME="Anti" ISMANU="T" ISAUTO="T"/>
</Rows>

Это значения столбцов в таблице SQl, имеющей ключевое значение MANUFACTURERID, которое также встречается в других таблицах, которые я анализирую.Я хотел бы использовать эти ключевые значения для ограничения / уточнения других запросов, но я просто не могу понять, как передать их в мое родительское представление, где я настраиваю все параметры поиска, и это мой вопрос, как мне сохранить словарь значений, которыйсвязан с выбором таблицы просмотра пользователей из подпредставления.Чтобы затем я мог передать одно или несколько из этих значений обратно в подпредставление другого набора данных, чтобы ограничить отображаемую информацию в зависимости от предыдущих выборов пользователей.

Это заняло у меня около часа, чтобы напечатать.Надеюсь, это имеет смысл, я все еще довольно новичок в разработке для iOS и Objective C, и эта концепция действительно расширяет мои возможности, и прежде чем я продолжу и в итоге собираю какую-то ерунду, которую мне придется исправить позже, я надеюсь, что этотили некоторые из вас смогут одолжить мне свой опыт такого рода, чтобы я мог сделать это правильно с первого раза:)

Если вам понадобится, чтобы я кое-что разъяснил или предоставил вам дополнительную информацию, которая поможет вампомогите мне просто дайте мне знать.

Заранее спасибо!

Ответы [ 3 ]

6 голосов
/ 31 октября 2011

Обычным шаблоном передачи информации в иерархии контроллера представления является использование делегирования.Вы можете добиться этого в своем сценарии, реализовав следующее:

1) Определите протокол в SearchParametersViewController, который представляет ваш родительский контроллер представления, который вы упомянули.

@protocol SearchParametersViewControllerDelegate <NSObject>
@optional
- (void)searchOptionsSelected:(NSArray *)selectedSearchOptions;
@end

2) Соответствует этому протоколу в вашем SearchOptionsSelectionViewController, который представляет контроллер табличного представления, у которого есть список выбора на выбор.Убедитесь, что вы импортировали или объявили форвард класса, в котором определен протокол (например, SearchParametersViewController).

#import "SearchParametersViewController.h"

@interface SearchOptionsSelectionViewController <SearchParametersViewControllerDelegate>

3) Определите свойство делегата в вашем SearchOptionsSelectionViewController (предполагается, что вы используете ARCна iOS 5.0, 4.x используйте unsafe_unretained вместо weak. Используйте assign, если проект использует ручное управление памятью).Этот объект делегата будет содержать ссылку на ваш родительский контроллер представления (например, SearchParametersViewController).Вы не хотите, чтобы это свойство сохранялось, чтобы избежать сохранения циклических / циклических ссылок, когда один объект ссылается на другой, который, в свою очередь, имеет ссылку на первый, и ни один объект никогда не освобождается.

@property (nonatomic, weak) id<SearchParametersViewControllerDelegate> delegate;

4) При создании экземпляра экземпляра SearchOptionsSelectionViewController внутри вашего родительского контроллера представления (SearchParametersViewController) установите свойство delegate для родительского экземпляра контроллера представления, как представлено ключевым словом self.Это гарантирует, что вы можете отправить сообщение (и соответствующие данные) в обратном направлении в иерархии контроллера представлений, однако отношения между объектами остаются слабосвязанными.Этот протокол делегата может быть согласован с любым другим контроллером представления, в контроллере представления выбора нет тесных связей с родительским контроллером представления, единственное, что их связывает, это гибкое принятие протокола делегирования контроллером представления выбора.

SearchOptionsSelectionViewController *selectionViewController = [[SearchOptionsSelectionViewController alloc] init];
selectionViewController.delegate = self;

5) Наконец, в методе делегата -tableView:didSelectRowAtIndexPath: представления вашего табличного представления SearchOptionsSelectionViewController передайте данные, соответствующие выбранной строке, вашему родительскому контроллеру представления (SearchParametersViewController) с помощью метода делегата, который вы определилив протоколе SearchParametersViewControllerDelegate.Вы должны использовать метод -respondsToSelector:, чтобы гарантировать, что объект делегата действительно реализует метод делегата -searchOptionsSelected:.Чтобы форсировать эту реализацию, измените @optional на @required над прототипом метода в определении протокола на шаге # 1.self.someDataArray представляет источник данных, который вы используете с контроллером представления таблицы выбора.Специфика метода протокола делегата и объекта (-ов) данных, отправляемых обратно в родительский контроллер представления, может быть изменена, важная вещь здесь - шаблон делегирования и отсутствие каких-либо тесно связанных отношений между экземплярами любого класса, но особенно в обратном направлении.иерархия контроллера представления.

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([self.delegate respondsToSelector:@selector(searchOptionsSelected:)])
    {
        NSArray *selectedObjs = [NSArray arrayWithObject:[self.someDataArray objectAtIndex:indexPath.row]];
        [self.delegate searchOptionsSelected:selectedObjs]
    }
}

6) Реализуйте метод делегата внутри SearchOptionsSelectionViewController.m

- (void)searchOptionsSelected:(NSArray *)selectedSearchOptions
{
    // do what you need to with selectedSearchOptions array
}

Дополнительное чтение:

Руководство по основам какао - делегаты и источники данных

Основные компетенции какао - протокол

3 голосов
/ 28 октября 2011

Вы можете использовать делегата приложения для достижения ваших целей здесь.

Я предполагаю, что ваше приложение имеет структуру, подобную этой.Прошу прощения за грубость этой модели.

Application delegate (A) --> Search Options View (B) --> Table where you do selections (C)
                      |
                      |
                      --> Some other view where you need the selection (D)

Ваша проблема в том, что вам нужна информация для передачи из C в D.

Достоинством вашего делегата приложения является универсальный доступ через [[UIApplication sharedApplication] delegate].Таким образом, вы можете получить указатель на него из любого места.Из C вы можете отправить информацию о выборе обратно в A. A может либо автоматически отправить ее в D, либо D может запросить ее у A, когда захочет.

Пара моментов:

  • Я не буду более подробно останавливаться на своем ответе в данный момент, потому что сейчас здесь пиво, плюс я мог неправильно понять ваше требование.Если вам что-то еще понадобится, я буду вставать по утрам в британское время, поэтому возможны некоторые задержки.
  • Некоторые люди недовольны использованием делегата приложения в качестве «дампа данных», как я и предлагал.Некоторые из этих людей предпочли бы создать целый синглтон-класс и рассматривать его как дамп данных.Кажется, это один из тех бесконечных аргументов, поэтому я стараюсь не вмешиваться.
1 голос
/ 28 октября 2011

У вас есть несколько вариантов, один из которых - использовать пользовательские настройки по умолчанию.Это может быть самым простым.

http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/Reference/Reference.html

Другой вариант - опубликовать уведомление с информацией.

http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nsnotificationcenter_Class/Reference/Reference.html

...