Статьи

Разработка приложений для iPhone — модальные и навигационные контроллеры

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

Откройте приложение «SampeListApp».

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

Создайте пару словарей с двумя элементами, ключами будут «Article» и «Desc», а объектами — название статьи и ее описание.

Массив arrItems, который использовался для заполнения табличного представления, больше не является статическим массивом, так как мы будем продолжать добавлять элементы в массив. Так что измените его на «NSMutableArray»

Контроллер табличного представления находится внутри контроллера навигации. Таким образом, мы можем установить заголовок панели навигации с помощью свойства title контроллера табличного представления.

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

Мы также изменим цвет оттенка панели навигации и добавим элемент навигации «+». Мы добавим элементы в список, захватив событие щелчка этого элемента навигации.

После внесения изменений, упомянутых выше, ваш метод ‘viewDidLoad’ должен выглядеть следующим образом:

SPTTableViewController.m

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.title = @"Articles";

    self.navigationController.navigationBar.barTintColor = [UIColor redColor];

    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addArticle)];

    NSDictionary *dictIosArticle1 = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:@"iOS Application: Getting Started", @"iOS Application:Getting Started Description",nil] forKeys:[NSArray arrayWithObjects:@"Article",@"Desc", nil]];
    NSDictionary *dictIosArticle2 = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:@"MVC And Programming Basics", @"MVC And Programming Basics Desc",nil] forKeys:[NSArray arrayWithObjects:@"Article",@"Desc", nil]];
    NSDictionary *dictIosArticle3 = [[NSDictionary alloc] initWithObjects:[NSArray arrayWithObjects:@"View Controllers", @"View Controllers Desc",nil] forKeys:[NSArray arrayWithObjects:@"Article",@"Desc", nil]];

    arrItems = [[NSMutableArray alloc] initWithObjects:dictIosArticle1,dictIosArticle2,dictIosArticle3, nil];
}

Обратите внимание, что мы добавили обработчик события щелчка для элемента навигации «Добавить», а также установили цель как «себя»

Мы увидим реализацию метода в следующей части этого урока.

Оставьте количество разделов в табличном представлении равным 1.

Измените метод cellForRowAtIndexPath, чтобы отобразить название статьи. Мы также изменим размер шрифта и отобразим индикатор раскрытия для представления навигации.

SPTTableViewController.m

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }
        
    NSDictionary *dictTmp = [arrItems objectAtIndex:indexPath.row];
    cell.textLabel.text = [dictTmp objectForKey:@"Article"];

    cell.textLabel.font = [UIFont boldSystemFontOfSize:12.0];
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    return cell;
}

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

SPTTableViewController.m

 - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    return @"iOS";
} 
- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return 30.0f;
}

Теперь запустите приложение в симуляторе iOS 7

IOS симулятор

Создайте контроллер простого представления «SPTArticleDetailViewController», чтобы отобразить описание статей.

Поместите «UITextView» внутри представления и сопоставьте ему выход «txtDetails».

Попробуйте сделать текстовое представление недоступным для редактирования и недоступным для выбора с помощью инспектора атрибутов.

Создайте строковую переменную ‘strDesc’, используя объявления @property и @synthesize для хранения подробных описаний в классе ‘SPTArticleDetailViewController’

Установите заголовок этого контроллера представления в методе ‘viewDidLoad’

 self.title = @"Description";

Текст ‘txtDetails’ должен быть значением строки ‘strDesc’, которую можно установить в методе ‘viewWillAppear’

SPTArticleDetailViewController.m

 - (void) viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:YES];
    self.txtDetails.text = strDesc;
}

Значение ‘strDesc’ будет описанием статьи и должно быть установлено в ‘SPTTableViewController’ непосредственно перед тем, как мы вставим ‘SPTArticleDetailViewController’ в стек навигации.

Метод didSelectRowAtIndexpath в файле SPTTableViewController.m, который вызывается при выборе элемента списка, следует изменить следующим образом.

SPTTableViewController.m

 - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    
    SPTArticleDetailViewController *detailViewController = [[SPTArticleDetailViewController alloc] initWithNibName:@"SPTArticleDetailViewController" bundle:nil];
    
    // Pass the selected object to the new view controller.

    NSDictionary *dictTemp = [arrItems objectAtIndex:indexPath.row];
    detailViewController.strDesc = [dictTemp objectForKey:@"Desc"];
    
    // Push the view controller.
    [self.navigationController pushViewController:detailViewController animated:YES];
}

Не забудьте импортировать заголовочный файл SPTArticleDetailViewController в файл SPTTableViewController.m. В противном случае будет выдана ошибка.

Метод pushViewController помогает перенести контроллер представления в стек навигации.

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

IOS симулятор

Когда вы нажимаете кнопку «Статьи», iOS автоматически берет на себя отображение текущего видимого контроллера.

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

 - (NSArray *)popToViewController:(UIViewController *)viewController animated:(BOOL)animated; 
- (NSArray *)popToRootViewControllerAnimated:(BOOL)animated;

Эти методы возвращают массив контроллеров popped view.

Создайте еще один контроллер представления ‘SPTAddArticleViewController’, как показано ниже

окно списка файлов

Карта розеток для текстовых полей.

Мы разместим этот контроллер вида внутри контроллера навигации и добавим кнопки сохранения и отмены на панели навигации.

Добавьте действия кнопки также.

Создайте протокол для сохранения статьи. Мы делегируем действие сохранения в ‘SPTTableViewController’

Наконец, ‘SPTAddArticleViewController.h’ должен выглядеть так, как показано ниже

SPTAddArticleViewController.h

 @protocol SPTAddArticleDelegate <NSObject>

-(void) addArticleName:(NSString *)strName andArticleDesc:(NSString *) strArticleDesc;

@end

@interface SPTAddArticleViewController : UIViewController
@property (weak, nonatomic) IBOutlet UITextField *txtArticleName;
@property (weak, nonatomic) IBOutlet UITextField *txtArticleDesc;
@property (unsafe_unretained) id <SPTAddArticleDelegate> delegate;
- (void)saveAction;
- (void) cancelAction;
@end

Включите объявление @synthesize для свойства делегата.

Добавьте кнопки сохранения и отмены в методе viewDidLoad

SPTAddArticleViewController.m

 - (void)viewDidLoad
{
    [super viewDidLoad];
    self.title = @"Add Article";
    self.navigationController.navigationBar.barTintColor = [UIColor redColor];
    self.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemCancel target:self action:@selector(cancelAction)];
    self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave target:self action:@selector(saveAction)];
}

Теперь измените действия сохранения и отмены следующим образом. Посмотрите, как действие делегируется в методе saveAction.

SPTAddArticleViewController.m

 - (void)saveAction {
    
    [self dismissViewControllerAnimated:YES completion:nil];
    
    if((![self.txtArticleName.text isEqualToString:@""]) &&(![self.txtArticleDesc.text isEqualToString:@""]))
    {
        if([self.delegate respondsToSelector:@selector(addArticleName:andArticleDesc:)])
        {
            [self.delegate addArticleName:self.txtArticleName.text andArticleDesc:self.txtArticleDesc.text];
        }
    }
}

- (void)cancelAction{
    [self dismissViewControllerAnimated:YES completion:nil];

}

Метод dismissViewController используется для отклонения представленного контроллера представления SPTAddArticleViewController.

Класс ‘SPTTableViewController’ должен принять протокол, как показано ниже

SPTTableViewController.h

 #import "SPTAddArticleViewController.h"

@interface SPTTableViewController : UITableViewController<SPTAddArticleDelegate>
@property (nonatomic,strong) NSMutableArray *arrItems;
@end

В файле ‘SPTTableViewController.m’ создайте личную ссылку на ‘SPTAddArticleViewController’

SPTTableViewController.m

 @interface SPTTableViewController ()

@property(nonatomic,strong) SPTAddArticleViewController *addController;

@end

@implementation SPTTableViewController
@synthesize arrItems,addController;

Реализуйте метод протокола

SPTTableViewController.m

 -(void) addArticleName:(NSString *)strName andArticleDesc:(NSString *) strArticleDesc
{
    NSMutableDictionary *mutDict = [[NSMutableDictionary alloc] init];
    [mutDict setObject:strName forKey:@"Article"];
    [mutDict setObject:strArticleDesc forKey:@"Desc"];
    [arrItems addObject:mutDict];
    [self.tableView reloadData];
}

Метод reloadData помогает перезагрузить табличное представление с новым источником данных или измененным массивом.

Последний шаг — представить «SPTAddArticleController» по нажатию кнопки «+» или «Добавить» в SPTTableViewController.

Функция addArticle должна быть реализована, чтобы предложить цену этому уроку

SPTTableViewController.m

 -(void) addArticle
{
    addController = [[SPTAddArticleViewController alloc] initWithNibName:@"SPTAddArticleViewController" bundle:nil];
    addController.delegate = self;

    UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:addController];
    
    [self presentViewController:navController animated:YES completion:nil];
}

Контроллер объявил себя делегатом ‘SPTAddArticleViewController’

Метод presentViewController помогает в представлении модального контроллера представления.

Запустите приложение в симуляторе, нажмите кнопку «Добавить» и проверьте этот модальный контроллер вида.

IOS симулятор

Вывод

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

Вы можете скачать полные примеры кода здесь .

Мы рассмотрим еще одну интересную тему в моей следующей статье.