Как сохранить nsdictionary вложенного представления в mainview на основе выбора tableviewcell

#iphone #ios #uitableview #nsxmlparser

#iPhone #iOS #uitableview #nsxmlparser

Вопрос:

В настоящее время я анализирую некоторый 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"]];
    }
 

Итак, отсюда все имена производителей отправляются в мой метод в виде массива строк. Затем я использую этот массив для настройки всех моих разделов / 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];
}
 

отсюда я делаю несколько действий, связанных с настройкой tableview после вызова [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, которое также встречается в других таблицах, которые я анализирую. Я хотел бы использовать эти ключевые значения для ограничения / уточнения других запросов, но я просто не могу понять, как передать их в мой parentview, где я настраиваю все параметры поиска, это мой вопрос, как я могу сохранить словарь значений, который связан с выбором пользователей tableview из вложенного представления. Чтобы затем я мог передать одно или некоторые из этих значений обратно в вложенное представление другого набора данных, чтобы ограничить отображаемую информацию в зависимости от предыдущих выборов пользователя.

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

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

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

Комментарии:

1. Вы можете определить, сколько усилий вы вложили в этот вопрос. Совершенно ясно, что вы пытаетесь сделать, каковы ваши мотивы и в чем заключается ваша проблема. Вносит освежающие изменения!

Ответ №1:

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

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
}
 

Дальнейшее чтение:

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

Основные компетенции Cocoa — протокол

Комментарии:

1. Идеальный.. На самом деле я уже начал идти по этому пути и дошел до того, что могу передать значение массива в родительское представление. Но спасибо вам за это объяснение, поскольку оно объясняет мне, что я сделал: P 100 баллов для вас, сэр! 🙂

2. Я могу назначить награду через 19 часов! лол.. они будут у вас завтра: P еще раз спасибо.

3. с удовольствием! : P просто приятно получить окончательный ответ, что я на этот раз двигаюсь в правильном направлении, лол

4. Отлично, спас мой день! Просто небольшое примечание: SearchOptionsSelectionViewController.m на шаге 6 должно быть SearchParametersViewController.m (родительское)

Ответ №2:

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

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

 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. да, эта структура в значительной степени именно то, с чем я работаю. Я изучил возможность создания своего собственного одноэлементного класса .. и понимаю, как это сделать (вроде), но основная проблема, с которой я сталкиваюсь, заключается в том, как вызывать его, когда это необходимо, в правильном порядке и т.д. Спасибо за сообщение, которое я буду публиковать еще некоторое время, так что, возможно, увидимся, когда ты проснешься: P, чувак, я тусуюсь за пивом в час!

2. Пиво — это угощение… Просто чтобы сказать, что я не выступаю за синглтон, я бы использовал делегат приложения. Я просто предвосхищал критику.

3. лол, да, я понял это 🙂 Я пока взгляну на некоторые заметки по обоим вопросам, прежде чем приступлю к кодированию: P

4. Я мог бы настроить делегат для передачи значений обратно в пользовательский NSObject, верно?… Мне нужно больше читать .. : P

Ответ №3:

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

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

Комментарии:

1. круто, теперь я буду читать оба полностью … 🙂 Я рад, что вы смогли понять, что я пытаюсь сделать … его так сложно объяснить

2. ха-ха, ты слишком старался. Я просто просмотрел до конца и прочитал, чтобы узнать, что вам нужно. lol

3. ахах, да, я перечитывал то, что написал, и подумал, может быть, мне стоит опубликовать это внизу вверху .. но остался с тем, что я сделал, и попытался сделать описательный заголовок. : P

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

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