У меня есть UITableView
с 5 UITableViewCells
. Каждая ячейка содержит элемент, UIButton
который настроен следующим образом:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier = @"identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
[cell autorelelase];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 5, 40, 20)];
[button addTarget:self action:@selector(buttonPressedAction:) forControlEvents:UIControlEventTouchUpInside];
[button setTag:1];
[cell.contentView addSubview:button];
[button release];
}
UIButton *button = (UIButton *)[cell viewWithTag:1];
[button setTitle:@"Edit" forState:UIControlStateNormal];
return cell;
}
Мой вопрос заключается в следующем: в buttonPressedAction:
методе, как узнать, какая кнопка была нажата. Я рассмотрел использование тегов, но я не уверен, что это лучший маршрут. Я хотел бы иметь возможность как-то пометить indexPath
на элемент управления.
- (void)buttonPressedAction:(id)sender
{
UIButton *button = (UIButton *)sender;
// how do I know which button sent this message?
// processing button press for this row requires an indexPath.
}
Какой стандартный способ сделать это?
Редактировать:
Я вроде решил это следующим образом. Я все еще хотел бы иметь мнение, является ли это стандартным способом сделать это или есть лучший способ?
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSString *identifier = @"identifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
if (cell == nil) {
cell = [[UITableView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
[cell autorelelase];
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 5, 40, 20)];
[button addTarget:self action:@selector(buttonPressedAction:) forControlEvents:UIControlEventTouchUpInside];
[cell.contentView addSubview:button];
[button release];
}
UIButton *button = (UIButton *)[cell.contentView.subviews objectAtIndex:0];
[button setTag:indexPath.row];
[button setTitle:@"Edit" forState:UIControlStateNormal];
return cell;
}
- (void)buttonPressedAction:(id)sender
{
UIButton *button = (UIButton *)sender;
int row = button.tag;
}
Важно отметить, что я не могу установить тег при создании ячейки, поскольку вместо этого ячейка может быть удалена. Это очень грязно. Должен быть лучший способ.
ios
iphone
uitableview
uibutton
узда
источник
источник
Ответы:
В примере аксессуаров Apple используется следующий метод:
Затем в обработчике касания извлекается координата касания и из этой координаты вычисляется индексный путь:
источник
Я обнаружил, что метод использования суперпредставления суперпредставления для получения ссылки на indexPath ячейки работает отлично. Спасибо iphonedevbook.com (macnsmith) за текст ссылки
источник
Вот как я это делаю. Просто и лаконично:
источник
CGPointZero
вместоCGPointMake(0, 0)
;-)Нашел хорошее решение этой проблемы в другом месте, не возиться с тегами на кнопке:
источник
buttonPressedAction:
ноbuttonPressedAction:forEvent:
.Как насчет отправки информации, как
NSIndexPath
вUIButton
использовании инъекции выполнения.1) Вам нужно время выполнения при импорте
2) добавить статическую константу
3) добавить
NSIndexPath
к вашей кнопке во время выполнения, используя:(void) setMetaData: (id) target withObject: (id) newObj
4) при нажатии кнопки получить метаданные, используя:
(ID) Metadata: (ID) целевой
наслаждаться
источник
To to (@Vladimir) отвечает: Swift:
Хотя проверка
indexPath != nil
дает мне палец ... "NSIndexPath не является подтипом NSString"источник
В Swift 4.2 и iOS 12 вы можете выбрать один из 5 следующих полных примеров , чтобы решить вашу проблему.
# 1. Использование
UIView
'sconvert(_:to:)
иUITableView
'indexPathForRow(at:)
# 2. Использование
UIView
'sconvert(_:to:)
иUITableView
' sindexPathForRow(at:)
(альтернатива)Это альтернатива предыдущего примера , когда мы переходим
nil
кtarget
параметруaddTarget(_:action:for:)
. Таким образом, если первый респондент не реализует действие, оно будет отправлено следующему респонденту в цепочке респондентов до тех пор, пока не будет найдена правильная реализация.# 3. Использование
UITableView
«ю.ш.indexPath(for:)
шаблона и делегатаВ этом примере мы устанавливаем контроллер представления в качестве делегата ячейки. При нажатии на кнопку ячейки запускается вызов соответствующего метода делегата.
# 4. Использование
UITableView
«SindexPath(for:)
и закрытие для делегированияЭто альтернатива предыдущему примеру, где мы используем замыкание вместо объявления протокола-делегата для обработки нажатия кнопки.
# 5. Использование
UITableViewCell
'saccessoryType
иUITableViewDelegate
'tableView(_:accessoryButtonTappedForRowWith:)
Если кнопка является
UITableViewCell
«s стандарт управления аксессуаром, любое нажатие на нее вызовет вызовUITableViewDelegate
» сtableView(_:accessoryButtonTappedForRowWith:)
, что позволяет получить соответствующий путь индекса.источник
источник
Я бы использовал свойство tag, как вы сказали, установив тег следующим образом:
затем получить тег внутри buttonPressedAction примерно так:
Или
источник
tag
является целым числом кажется немного неуклюжим для кодирования / декодирования индексных путей в теги представления.Хотя мне нравится способ тегов ... если вы не хотите использовать теги по какой-либо причине, вы можете создать элемент
NSArray
готовых кнопок:затем создайте эти кнопки перед рендерингом tableView и вставьте их в массив.
Тогда внутри
tableView:cellForRowAtIndexPath:
функции вы можете сделать:Тогда в
buttonPressedAction:
функции вы можете сделатьисточник
ОБРАЩАТЬСЯ С РАЗДЕЛАМИ - я сохранил NSIndexPath в пользовательском UITableViewCell
IN CLKIndexPricesHEADERTableViewCell.xib
В IB Добавьте UIButton в XIB - НЕ добавляйте действие!
Добавить выход @property (сохранить, неатомный) IBOutlet UIButton * buttonIndexSectionClose;
НЕ CTRL + DRAG действие в IB (сделано в коде ниже)
В viewForHeaderInSection (также должен работать для cellForRow .... и т. Д., Если в вашей таблице только 1 раздел)
... используйте раздел, чтобы получить данные для вашей ячейки
...заполните это
ПОЛЬЗОВАТЕЛЬ нажимает кнопку УДАЛИТЬ на заголовке раздела, и это вызывает
В этом примере я добавил кнопку «Удалить», поэтому для ее подтверждения должен отображаться UIAlertView.
Я сохраняю раздел и ключ в словарь, хранящий информацию о разделе в иваре в ВК
источник
источник
Это работает и для меня, спасибо @Cocoanut
Я обнаружил, что метод использования суперпредставления суперпредставления для получения ссылки на indexPath ячейки работает отлично. Спасибо iphonedevbook.com (macnsmith) за текст ссылки
источник
Вы можете использовать шаблон тега:
источник
Я что-то упускаю? Разве вы не можете просто использовать отправителя для идентификации кнопки. Отправитель предоставит вам такую информацию:
Затем, если вы хотите изменить свойства кнопки, произнесите фоновое изображение, которое вы только что сказали отправителю:
Если вам нужен тег, то метод ACBurk подойдет.
источник
На самом деле довольно просто:
Работает хорошо для меня: P
если вы хотите изменить настройку целевого действия, вы можете включить в метод параметр события, а затем использовать касания этого события, чтобы разрешить координаты касания. Координаты все еще должны быть разрешены в границах сенсорного просмотра, но это может показаться некоторым людям проще.
источник
создайте массив nsmutable и поместите все кнопки в этот массив usint [массив addObject: yourButton];
в методе нажатия кнопки
-
источник
Небольшой вариант ответа Cocoanuts (который помог мне решить эту проблему), когда кнопка находилась в нижнем колонтитуле таблицы (что мешает вам найти «нажатую ячейку»):
источник
Я всегда использую теги.
Вам нужно создать подкласс
UITableviewCell
и обработать нажатие кнопки оттуда.источник
Это просто; сделать кастомную ячейку и взять розетку кнопки
изменить идентификатор в вышеуказанном методе на
(UIButton *)
Вы можете получить значение, которое нажимается на кнопку, выполнив sender.tag.
источник
Создайте подкласс для кнопки для сохранения требуемого значения, возможно, создайте протокол (ControlWithData или что-то еще). Установите значение при добавлении кнопки в ячейку табличного представления. В вашем событии касания проверьте, подчиняется ли отправитель протоколу, и извлеките данные. Обычно я храню ссылку на фактический объект, который отображается в ячейке табличного представления.
источник
SWIFT 2 ОБНОВЛЕНИЕ
Вот как узнать, какая кнопка была нажата + отправить данные другому ViewController с этой кнопки,
indexPath.row
как я полагаю, в этом смысл большинства!Для тех, кто использует класс ViewController и добавил tableView, я использую ViewController вместо TableViewController, поэтому я вручную добавил tableView для доступа к нему.
Вот код для передачи данных в другой VC при нажатии этой кнопки и передачи ячейки
indexPath.row
источник
Обратите внимание, здесь я использую пользовательскую ячейку, этот код отлично работает для меня
источник
Решение Криса Швердта, но потом в Свифте, сработало для меня:
источник
Эта проблема состоит из двух частей:
1) Получение индекса пути
UITableViewCell
которого содержит нажатыеUIButton
Есть несколько предложений, таких как:
Обновление
UIButton
«Stag
вcellForRowAtIndexPath:
методе с использованием индекса путей вrow
значение. Это не очень хорошее решение, так как требуетtag
постоянного обновления и не работает с табличными представлениями с несколькими разделами.Добавление
NSIndexPath
свойства в пользовательской ячейке и обновить его вместоUIButton
«сtag
вcellForRowAtIndexPath:
методе. Это решает проблему с несколькими разделами, но все же не очень хорошо, поскольку требует постоянного обновления.Сохранение слабой ссылки на родителя
UITableView
в пользовательской ячейке при ее создании и использованиеindexPathForCell:
метода для получения пути индекса. Кажется, немного лучше, нет необходимости что-либо обновлять вcellForRowAtIndexPath:
методе, но все равно требуется установка слабой ссылки при создании пользовательской ячейки.Использование
superView
свойства ячейки для получения ссылки на родителяUITableView
. Нет необходимости добавлять какие-либо свойства в пользовательскую ячейку, и нет необходимости устанавливать / обновлять что-либо при создании / позже. Но ячейкаsuperView
зависит от деталей реализации iOS. Так что его нельзя использовать напрямую.Но это может быть достигнуто с помощью простого цикла, поскольку мы уверены, что рассматриваемая ячейка должна быть в UITableView:
Таким образом, эти предложения могут быть объединены в простой и безопасный пользовательский метод ячейки для получения пути индекса:
Отныне этот метод можно использовать для определения того, какая из
UIButton
них нажата.2) Информирование других сторон о событии нажатия кнопки
После того, как внутренне узнают, какая
UIButton
нажата в какой пользовательской ячейке с точным индексным путем, эта информация должна быть отправлена другим сторонам (наиболее вероятно, контроллер представления, обрабатывающийUITableView
). Таким образом, это событие нажатия кнопки может быть обработано на уровне абстракции и логики, аналогичномdidSelectRowAtIndexPath:
методу делегата UITableView.Для этого можно использовать два подхода:
а) Делегирование: пользовательская ячейка может иметь
delegate
свойство и определять протокол. Когда кнопка нажата, она просто выполняет методы делегата для своегоdelegate
свойства. Но этоdelegate
свойство должно быть установлено для каждой пользовательской ячейки при их создании. В качестве альтернативы, пользовательская ячейка может выбрать выполнение своих методов делегата и для родительского табличного представленияdelegate
.b) Центр уведомлений: настраиваемые ячейки могут определять имя настраиваемого уведомления и публиковать это уведомление с указанием пути индекса и представления родительской таблицы в
userInfo
объекте. Не нужно ничего устанавливать для каждой ячейки, достаточно просто добавить наблюдателя для уведомления пользовательской ячейки.источник
Я использую решение, которое подкласс,
UIButton
и я подумал, что я должен просто поделиться им здесь, коды в Swift:Затем не забудьте обновить его indexPath в
cellForRow(at:)
Поэтому, отвечая на событие кнопки, вы можете использовать его как
источник