Table View - пример реализации

Создадим новый проект Xcode на основе шаблона приложения с одним видовым представлением. Преобразуем наш основной вид в вид в иерархии навигации, для этого выберем в Main.storyboard контроллер вида и выберем Editor->Embed In>Navigation Controller. Теперь наш видовой контроллер является корневым в стеке навигации.

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

Источник данных

Создадим источник данных для ячейки таблицы, унаследованный от NSObject. Назовем его dataObj.

Листинг dataObj.h h

#import <Foundation/Foundation.h>

@interface dataObj : NSObject

@property (copy)NSString* carName;
@property BOOL newCar;
@property BOOL sportCar;
@property BOOL rented;

@end

Файл реализации dataObj.m оставляем пустым.

Реализация UITableViewDataSource протокола

Перейдем в заголовочный файл ViewController.h и отредактируем его соответствующим образом.

Листинг ViewController.h h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController <UITableViewDataSource>
{
  NSMutableArray* dataArray; // массив для объектов источника данных
  IBOutlet UITableView *tableView1; // ссылка на таблицу
  
}

- (void)addDataToTable:(id)sender; // метод для добавления строки в таблицу

@end

Листинг файла ViewController.m m

#import "ViewController.h"
#import "dataObj.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
  [super viewDidLoad];
  // Do any additional setup after loading the view, typically from a nib.
  dataArray = [NSMutableArray array]; // создаем пустой массив для данных
  // создадим правую кнопку для добавления строк в таблицу
  UIBarButtonItem* rightButton = [[UIBarButtonItem alloc] 
      initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addDataToTable:)];
  [self navigationItem].rightBarButtonItem = rightButton;
}

- (void)didReceiveMemoryWarning {
  [super didReceiveMemoryWarning];
  // Dispose of any resources that can be recreated.
}

- (void)addDataToTable:(id)sender{
  dataObj* dt = [[dataObj alloc] init];
  dt.carName = @"New Car";
  [dataArray addObject:dt];
  [tableView1 reloadData];
}

#pragma mark - Table View Datasource реализация протокола

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  return dataArray.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell1" forIndexPath:indexPath];
  NSInteger row = indexPath.row;
  dataObj* dt = dataArray[row];
  cell.textLabel.text = dt.carName;
  
  return cell;
}

@end

При загрузке видового представления создаем правую кнопку в навигационном элементе панели навигации и назначаем ей обработчик события нажатия addDataToTable:.

Переходим в Interface Builder, связываем Table View с IBOutlet UITableView *tableView1 и назначаем data source нашего Table View контроллеру видового представления ViewController, либо можно сделать это программно в методе viewDidLoad, добавив строку tableView1.dataSource = self;.

Запустим приложение в симуляторе. Приложение запустится с пустой таблицей и при нажатии на кнопку "Добавить" в панели навигации будет добавляться строка с текстом "New Car". Каждая строка соответствует свойству carName из объекта dataObj, расположенному в массиве dataArray.

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

Реализация UITableViewController

Переходим в Interface Builder и добавляем элемент TableViewController, создаем переход от ячейки Prototype Cells в главном виде к TableViewController с эфектом перехода show.

Переходим к вновь размещенному TableViewController и в инспекторе атрибутов зададим параметр Content, как Static Cells, т.е. наше табличное представление будет реализовано статично. В поле Sections установим 2, теперь в нашей таблице реализовано 2 секции. Выберем Section-1 и в поле Rows вводим 1. Теперь мы имеем таблицу с двумя статичными секциями, в первой 1 строка, во второй 3.

Внимание использовать параметр Content, как Static Cells возможно только если Table View используется в составе TableViewController.

Создадим новый класс на основе UITableViewController, без создания xib и назовем его dataTableViewController. Свяжем наш Table View Controller в Storyboard с вновь созданным классом.

Листинг dataTableViewController.h

#import <UIKit/UIKit.h>

@class dataObj;

@interface dataTableViewController : UITableViewController
{
  // Пользовательские переключатели
  UISwitch* swNewCar;
  UISwitch* swSportCar;
  UISwitch* swRented;
  
  // Указатели на каждую из ячеек
  IBOutlet UITableViewCell *cellName;
  IBOutlet UITableViewCell *cellNewCar;
  IBOutlet UITableViewCell *cellSportCar;
  IBOutlet UITableViewCell *cellRented;
}

@property (retain, nonatomic)dataObj* dObj1;

@end

Здесь мы задекларировали три указателя на элементы переключателей, которые мы добавим к нашим ячейкам из второй секции. И создаем связь указателей собственно на ячейки, созданные в Interface Builder.

Переходим в dataTableViewController.m и отредактируем метод инициализации при загрузке контроллера:

- (void)viewDidLoad {
    [super viewDidLoad];
  cellName.textLabel.text = _dObj1.carName;
  // Создаем пользовательские switch элементы для секции 2 и инициализируем ячейки
  swNewCar = [[UISwitch alloc]init];
  cellNewCar.accessoryView = swNewCar;
  swNewCar.selected = _dObj1.newCar;
  cellNewCar.textLabel.text = @"Новая машина";
  
  swSportCar = [[UISwitch alloc]init];
  cellSportCar.accessoryView = swSportCar;
  swSportCar.selected = _dObj1.sportCar;
  cellSportCar.textLabel.text = @"Спортивная";
  
  swRented = [[UISwitch alloc]init];
  cellRented.accessoryView = swRented;
  swRented.selected = _dObj1.rented;
  cellRented.textLabel.text = @"Сдана в аренду";
}

При загрузке контроллера свойство с источником данных dataObj* dObj1 должно содержать сам источник данных, чтобы осуществить это возвращаемся к ViewController.m, добавим импорт заголовка вновь созданного класса #import "dataTableViewController.h" и добавим метод:

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  dataTableViewController *dest = (dataTableViewController*)[segue destinationViewController];
  dataObj* dt = dataArray[tableView1.indexPathForSelectedRow.row];
  dest.dObj1 = dt;
}

Этот метод вызывается всякий раз, когда контроллер навигации спускает текущий контроллер вида вниз по стеку, размещая на вершине destinationViewController. Поскольку у нас только один переход из данного вида к другому нас не интерисует свойство identifier объекта segue и поскольку мы уверенны в том, что destinationViewController является экземпляром класса dataTableViewController, то мы просто приводим тип данных и передаем источник данных в загружаемый dataTableViewController, соответствующий выбранной ячейке.

Запустим приложение и после добавления новой строки в первой таблице, нажав на созданную ячейку мы переходим ко второй таблице, принимающей примерно следующий вид:

Это всего лишь пример использования Table View и Table View Controller, в нем не приведен пример редактирования, поскольку его реализация более правильна на основе шаблона Master-Detail.

 
 
homeЗаметили ошибкукарта сайта 
   Made on a Mac