2012-05-30 2 views
7

В настоящее время я создаю пользовательский вид сетки, а это значит, что я создаю класс, который имеет много общего с UITableView. Одна из вещей, которые я хочу получить, - это связь ячеек и вид сетки.Как UITableViewCell взаимодействует с UITableView?

Мне было интересно, как стол с таблицей обсуждает с табличным представлением. Например, как ячейка уведомляет представление таблицы о том, что ее кнопка удаления была нажата, и ячейка должна быть удалена из представления таблицы?

Существует несколько возможных сценариев, но я не уверен, какой из них используется Apple, так как заголовки UITableView или UITableViewCell показывают это (или я что-то пропускаю).

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

+1

KKGridView (on GitHub: https://github.com/kolinkrewinkel/KKGridView) - это классическая реализация со многими сходствами с UITableView и сложным набором внутренних методов, из которых вы можете получить вдохновение. – viggio24

+0

AQGridView (http://github.com/AlanQuatermain/AQGridView) также представляет собой реализацию, основанную на структуре UITableView. Но, насколько я знаю, невозможно поддерживать связь между двумя частями объекта (я мог ошибаться!). – Raspu

+0

Делегирование - это ключ. – Till

ответ

0

UITableViewCell элементы относятся к области UITableView. Таким образом, вы можете использовать его для связи между ячейками и tableView. В свою очередь UITableView имеет делегат и источник данных для связи с контроллером. Это может помочь.

+0

Спасибо за ваш ответ. Наличие ссылки с UITableViewCell на UITableView не является реальной проблемой. Мой вопрос касается связи между ячейкой и табличным представлением и как сохранить эту связь конфиденциальной. –

+0

Я хочу сказать, что контроллер должен решить, как бороться с нажатием кнопки. Таким образом, это может быть '[[(UITableView *) self.superview delegate] выполнитьSelector: @selector (someButtonPressedInCell :) withObject: self]' – voromax

0

Я не уверен, что необходим частный канал связи.

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

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

0

Вы можете использовать categories.

Вы объявляете свои частные методы в отдельной категории и помещаете их в отдельный файл. В файле реализации класса, который хочет использовать эти частные методы, вы импортируете этот файл с частной категорией и используете частные методы. Таким образом, public .h класса, который их использует, остается нетронутым.

Пример:

MyGridViewCell.h:

@interface MyGridViewCell : UIView 
// ... 
@end 

MyGridViewCell.m:

@implementation MyGridViewCell : UIView 
// ... 
@end 

Теперь частный категория методы интерфейса:

MyGridViewCellPrivate.h:

@interface MyGridViewCell (Private) 

- (void) privateMethod1; 

@end 

И реализация:

MyGridViewCellPrivate.м:

@implementation MyGridViewCell (Private) 

- (void) privateMethod1 
{ 
    // ... 
} 

@end 

Заголовок остается такой же, как раньше:

MyGridView.h:

@interface MyGridView : UIView 

- (void) publicMethod1; 

@end 

Но реализация может использовать частный API:

MyGridView.m:

#import "MyGridViewCell.h" 
#import "MyGridViewCellPrivate.h" 

- (void) publicMethod1 
{ 
    // Use privateMethod1 
} 
+0

Не могли бы вы объяснить этот подход более подробно? –

0

Вы можете иметь собственные пользовательские ячейки UIViews, которые имеют частное свойство типа вашего представления сетки. Когда вы добавляете эти ячейки в свой GridView, обновите это свойство в gridView.

У меня есть пользовательская сетка и делаю это так.

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

1

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

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath 

Однако , для понимания того, хотите ли вы добавить кнопку в ячейку tableview и выполнить ее, не входящую в стандартную библиотеку iOS, вы должны создать делегат в своей ячейке и установить файл данных datasource tableview в качестве делегата.

В основном вы бы подкласс UITableViewCell как так

MyCustomCell.h

@protocol MyCustomCellDelegate; 
@interface MyCustomCell : UITableViewCell 
@property (nonatomic, unsafe_unretained) id <MyCustomCellDelegate> delegate; //Holds a reference to our tableView class so we can call to it. 
@property (nonatomic, retain) NSIndexPath *indexPath; //Holds the indexPath of the cell so we know what cell had their delete button pressed 
@end 

/* Every class that has <MyCustomCellDelegate> in their .h must have these methods in them */ 
@protocol MyCustomCellDelegate <NSObject> 
- (void)didTapDeleteButton:(MyCustomCell *)cell; 
@end 

MyCustomCell.m

@synthesize delegate = _delegate; 
@synthesize indexPath = _indexPath; 
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier 
{ 
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 
    if (self) 
    { 
    /* Create a button and make it call to a method in THIS class called deleteButtonTapped */ 
    UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 
    button.frame = CGRectMake(5, 5, 25, 25); 
    [button addTarget:self action:@selector(deleteButtonTapped:) forControlEvents:UIControlEventTouchUpInside]; 

    } 
    return self; 
} 

/** 
* This is the method that is called when the button is clicked. 
* All it does is call to the delegate. (Whatever class we assigned to the 'delegate' property) 
*/ 
- (void)deleteButtonTapped:(id)sender 
{ 
    [self.delegate didTapDeleteButton:self]; 
} 

DataSource Ваш Tableview был бы выглядеть примерно так.

MyDataSource.h

/* We conform to the delegate. Which basically means "Hey you know those methods that we defined in that @protocol I've got them and you can safely call to them" */ 
@interface MyDataSource : UIViewController <MyCustomCellDelegate, UITableViewDelegate, UITableViewDataSource> 
@property (nonatomic,retain) NSArray *tableData;//We will pretend this is the table data 
@property (nonatomic,retain) UITableView *tableView;// We will pretend this is the tableview 

@end 

MyDataSource.m

//We will pretend we synthesized and initialized the properties 
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    MyCustomCell *cell = [tableView dequeueReusableCellWithIdentifier: @"MyCustomCell"]; 
    if (!cell) 
     cell = [[DownloadQueueCell alloc] initWithStyle: UITableViewCellStyleDefault reuseIdentifier: @"MyCustomCell"]; 
    cell.delegate = self;  // Make sure we set the cell delegate property to this file so that it calls to this file when the button is pressed. 
    cell.indexPath = indexPath;// Set the indexPath for later use so we know what row had it's button pressed. 
    return cell; 
} 


- (void)didTapDeleteButton:(MyCustomCell *)cell; 
{ 

    // From here we would likely call to the apple API to Delete a row cleanly and animated 
    // However, since this example is ignoring the fact that they exist 
    // We will remove the object from the tableData array and reload the data 
    [self.tableData removeObjectAtIndexPath:cell.indexPath]; 
    [self.tableView reloadData]; 

} 

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