Показаны сообщения с ярлыком строки. Показать все сообщения
Показаны сообщения с ярлыком строки. Показать все сообщения

среда, 8 января 2014 г.

UITableView в нутри UIViewContrloller. IOS программирование

В этой статье я опишу как сделать полноценную таблицу UITableView  в вашем UIViewController. Так как работать с UITableViewController несколько сложнее. Этот метод поможет вам сэкономить время. Пример будет показана на основе работы с Xcode 4.6 и использованием stroryboard. Удобство такого метода даёт возможность размещать на вашем UIViewController и другие элементы кроме таблици UITableView, такие как NavigationBar или UITabbar  и они будут нормально смотрется, а не ездить за последней строчкой таблици(вдруг кто сталкивался с проблемой).  Для начала вам необходимо создать проект, описывать эти простые действия я не буду так как в интернетах полно документации как это сделать. И так разместите на вашем UIViewController элемент UITableView как показано на рисунке:


Теперь создайте класс в своем приложении или используйте класс который создал за вас Xcode. Я назвал свой katalog. Привяжите его к вашему UIViewController если это все таки новый класс и новый UIViewController. Иначе если вы используете уже созданный то делать этого не придется.
Теперь необходимо немного модифицировать h файл:
вот мой katalog.h
#import
@interface katalog : UIViewController {
IBOutlet UITableView *table;
}

@end
Обратите внимание на это означает, что этот класс будет делегатом для таблици и источником данных.
IBOutlet UITableView *table; это аутлет для нашего UITableView его нужно подвязать к таблице нажатием правой кнопкой мыши на элементе UITableView и перетянув от New Referencing Outler  к вашему класу в левой колонке где показаны все Scene – активности вашего приложения.
Теперь приступим к реализации нашего m файла, в моём случае это katalog.m. В метод - (void)viewDidLoad я добавил 2 строки:
[table setDelegate: self];
[table setDataSource: self];
Указывая уже объекту table  кто будет делегатом и источником данных для него (по сути для таблици).
Поскольку наш класс является делегатом и источником данных для таблици необходимо реализовать стандартные методы для UITableView, изначально в m файле их нет поэтому придется добавить. В таблице будет две секции без названия и в каждой их них по одной строке с какими либо данными. Все это опишем в методах таблици.
Вот листинг кода который необходимо добавить в m файл:
#pragma mark – Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
#warning Potentially incomplete method implementation.
// Количество секций в таблице.
return 2;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
#warning Incomplete method implementation.
// Вернуть количество строк в секции.
return 1;
}
/*
Сформировать строки таблици
*/
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSString *lang = [userDefaults objectForKey:@"lang"];
static NSString *CellIdentifier = @»Cell»;
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] ;
}
if(indexPath.row==0 && indexPath.section==0){
cell.text = @»Первая строка»;
//сформировать дату и перевести её в строку
//это просто пример какие данные можно добавить в таблицу
NSDate *d = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd_HH:mm:ss"];
[formatter setTimeZone:[NSTimeZone timeZoneWithName:@"..."]];
NSString *date = [formatter stringFromDate:d];
cell.detailTextLabel.text = date;
}else if(indexPath.section==1){
cell.text = @»Вторая строка»;
cell.detailTextLabel.text = @»ваши данные»;
}
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
#pragma mark – Table view delegate
/*
Обработка событий нажатия на строки таблици
*/
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row==0 && indexPath.section==0){
//нажали на первую строку в первой секции
}else{
//нажали на другую строку
}
}

Конечно неплохо было бы изменить немножко внешний вид таблицы, для этого в настройках UITableView в storyboard и поставил опцию Grupped в параметре Style как показано на рисунке:

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

UITableView в нутри UIViewContrloller. Часть 2 – большие списки

В предыдущей части я описывал как создавать таблицы внутри UIViewContrloller, простейшим способом. Теперь поговорим о создании таблиц с большим количеством строк и сложными механизмами их формирования. Как создать проект и разместить UITableView описывать не буду можете посмотреть в предыдущей части. В данном примере мы будем выводить большое количество данных в качестве строк в таблицу. Для начала подправим наш h файл, если помните у меня это попрежнему katalog.h вот как он будет выглядеть:
#import
@interface katalog : UIViewController {
IBOutlet UITableView *table;
}
@property (strong,nonatomic)NSMutableArray* listOfItems;
-(void) prepereList;
@end

На самом деле я добавил только свойство listOfItems в качестве данных для него будет некий массив элементов в последствии строк. И добавил еще вспомогательный метод -(void) prepereList; – который будет готовить данные для выгрузки в таблицу, собственно наполнять listOfItems.
Релизация этого метода в m файле:
-(void) prepereList{
NSMutableArray *marray = //предположим что такой массив данных у вас есть, если нет то можете воспользоватся любыми примерами по формированию данных этого типа
//создадим объект типа массив для ключей уже существующих  значений из marray нашего массива данных строк
NSArray *keylist = [[NSArray alloc] initWithArray:marray];
//объявим наше свойство listOfItems.
listOfItems = [[NSMutableArray alloc] init];
NSDictionary *emDict = [NSDictionary dictionaryWithObject:keylist forKey:@"Sometext"]; //создадим ключ секцию и в качестве NSDictionary сохраним объект массив
//присвоим данные нашему списку элементов таблици
[listOfItems addObject:emDict];
}
Также не забудьте сделать @synthesize listOfItems;
Конечно кажется что метод несколько замутный и излишне орудует массивами. Дело в том что именно этот способ подходит мне для дальнейшей работы с данными, если захотите его упростить то можете это делать.
Далее незабываем включить наш метод в метод viewDidLoad
- (void)viewDidLoad
{
[super viewDidLoad];
[table setDelegate: self];
[table setDataSource: self];
[self prepereList];
}
Несколько изменятся методы по работе с таблицей относительно первой статье:
#pragma mark – Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [listOfItems count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSDictionary *dictionary = [listOfItems objectAtIndex:section];
NSArray *array = [dictionary objectForKey:@"Sometext"];
NSLog(@»%d»,[array count]);
return [array count];
}
/*
Сформировать строки таблици
*/
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @»Cell»;
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] ;
}
NSDictionary *dictionary = [listOfItems objectAtIndex:indexPath.section];
NSMutableArray *marray = [dictionary objectForKey:@"Sometext"];
NSDictionary *d = [marray objectAtIndex:indexPath.row];
NSString *code =  [d valueForKey:@"code"];
cell.text = @»Maintext»;
UIFont *myFont = [ UIFont fontWithName: @"System" size: 17.0 ];
cell.textLabel.font = myFont;
cell.tag = 1;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
cell.detailTextLabel.text = @»datail»;
return cell;
}
#pragma mark – Table view delegate
/*
Обработка событий нажатия на строки таблици
*/
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if(indexPath.row==0 && indexPath.section==0){
//нажали на первую строку в первой секции
}else{
//нажали на другую строку
}
}
Немного не понятно откуда берутся данные, но сама реализация направлена на то, что бы показать как вывести большое количество строк автоматически, а не на то как сформировать данные для таблицы. Так что уж простите что не акцентирую внимание на этом.

Есть ещё один метод для формирования заголовков секций таблици, можете добавить его прямо в m  файд:
/**
заголовки секций
*/
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
NSString *sectioname = @»Заголовок»;
return sectioname;
}
Вызов этого метода генерирует сам TableView, и искать его он будет в нашем классе, так как именно наш класс katalog.m – делегат таблици. В качестве входного параметра section используется номер секции, в данном примере у меня одна секция и проверять это значения смысла нет. Поэтому я просто верну  название строкой. Можете скомпилировать проект и посмотреть как изменится вид таблици, над списокм появится заголовок.