Подтвердить что ты не робот

AccessoryButtonTappedForRowWithIndexPath: не вызывается

Я создаю кнопку раскрытия сведений, которая заполняется с помощью массива.... Однако accessoryButtonTappedForRowWithIndexPath: функция не вызывается в моем классе. Это делегат TableviewDelegate и TableviewDatasource.

- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath{
    NSLog(@"reaching accessoryButtonTappedForRowWithIndexPath:");
    [self performSegueWithIdentifier:@"modaltodetails" sender:[self.eventsTable cellForRowAtIndexPath:indexPath]];
}

NSLog не печатает на консоль, что наводит меня на мысль, что функция не вызывается... Это, конечно, когда я выбираю ячейку. На скриншоте ниже показано, как у меня настроена ячейка.

enter image description here

4b9b3361

Ответ 1

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

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

Ответ 2

В документе сказано, что метод tableView:accessoryButtonTappedForRowWithIndexPath: не вызывается, если для строки в indexPath установлено вспомогательное представление. Метод вызывается только в том случае, если свойство accessoryView имеет значение nil и когда используется и установлено свойство accessoryType для отображения встроенного вспомогательного представления.

Насколько я понимаю, accessoryView и accessoryType являются взаимоисключающими. При использовании accessoryType система будет вызывать tableView:accessoryButtonTappedForRowWithIndexPath:, как и ожидалось, но вы должны сами обработать другой случай.

То, как Apple это делает, показано в примере проекта Accessory SDK. В методе cellForRowAtIndexPath делегата источника данных они устанавливают цель/действие для пользовательской вспомогательной кнопки. Поскольку нельзя передать indexPath действию, они вызывают вспомогательный метод для извлечения соответствующего indexPath и передают результат методу делегата:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    ...

    UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
    ...

    // set the button target to this table view controller so we can interpret touch events and map that to a NSIndexSet
    [button addTarget:self action:@selector(checkButtonTapped:event:) forControlEvents:UIControlEventTouchUpInside];
    ...
    cell.accessoryView = button;

    return cell;
}


- (void)checkButtonTapped:(id)sender event:(id)event{
    NSSet *touches = [event allTouches];
    UITouch *touch = [touches anyObject];
    CGPoint currentTouchPosition = [touch locationInView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint: currentTouchPosition];
    if (indexPath != nil){
        [self tableView: self.tableView accessoryButtonTappedForRowWithIndexPath: indexPath];
    }
}

По какой-то причине ваша установка, кажется, падает в случае accessoryView. Вы пытались установить accessoryType с кодом вместо использования Interface Builder?

Ответ 3

Это кажется очень актуальным...

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

Кнопка раскрытия подробностей. Пользователи нажимают этот элемент, чтобы просмотреть подробную информацию о элементе списка. (Обратите внимание, что вы можете использовать этот элемент в представлениях, отличных от представлений таблиц, для получения дополнительных сведений о чем-либо, см. "Подробные раскрывающиеся кнопки" для получения дополнительной информации.) В виде таблицы используйте кнопку раскрытия подробностей в строке, чтобы отображать сведения о элемент списка. Обратите внимание, что кнопка раскрытия подробностей, в отличие от индикатора раскрытия, может выполнять действие, которое является отдельным от выбора строки. Например, в Избранном телефоне нажатие на строку инициирует вызов контакту; нажатие кнопки раскрытия подробностей в строке показывает больше информации о контакте.

Ответ 4

Преобразование верхнего ответа в Swift 3:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    ...
    let unseletcedImage = UIImage(named: "<imagename>")
    let seletcedImage = UIImage(named: "<imagename>")
    let button = UIButton(type: .custom)
    // match the button size with the image size
    let frame = CGRect(x: CGFloat(0.0), y: CGFloat(0.0), width: CGFloat((unseletcedImage?.size.width)!), height: CGFloat((unseletcedImage?.size.height)!))
    button.frame = frame
    button.setBackgroundImage(unseletcedImage, for: .normal)
    button.setBackgroundImage(seletcedImage, for: .selected)
    cell?.accessoryView = button
    let action = #selector(checkButtonTapped(sender:event:))
    (cell?.accessoryView as? UIButton)?.addTarget(self, action: action, for: .touchUpInside)
    ....
    return cell!

}

@objc func checkButtonTapped(sender: UIButton?, event: UIEvent) {
    let touches = event.allTouches
    let touch = touches!.first
    guard let touchPosition = touch?.location(in: self.tableView) else {
        return
    }
    if let indexPath = tableView.indexPathForRow(at: touchPosition) {
        tableView(self.tableView, accessoryButtonTappedForRowWith: indexPath)
    }
}

Ответ 5

В соответствии с документацией UITableViewCellAccessoryType ожидается поведение:

typedef enum : NSInteger {    
UITableViewCellAccessoryNone,   
UITableViewCellAccessoryDisclosureIndicator,   
UITableViewCellAccessoryDetailDisclosureButton,   
UITableViewCellAccessoryCheckmark,   
UITableViewCellAccessoryDetailButton } UITableViewCellAccessoryType;

Константы UITableViewCellAccessoryNone У ячейки нет аксессуары вид. Это значение по умолчанию.

UITableViewCellAccessoryDisclosureIndicator В ячейке есть аксессуар управление в форме шеврона. Этот элемент управления указывает, что нажатие ячейка активирует push-действие. Элемент управления не отслеживает.

UITableViewCellAccessoryDetailDisclosureButton У ячейки есть информация и изображение шеврона как контент. Этот элемент управления указывает, что нажатие на ячейку позволяет пользователю настроить содержимое ячеек. контроль дорожек.

UITableViewCellAccessoryCheckmark Ячейка имеет галочку на своем правая сторона. Этот элемент управления не отслеживает. Делегат от представление таблицы может управлять отметками в секции строк (возможно ограничение галочки на один ряд раздела) в tableView: didSelectRowAtIndexPath: метод.

UITableViewCellAccessoryDetailButton У ячейки есть информационная кнопка без шеврона. Этот элемент управления указывает, что нажатие на ячейку отображает дополнительную информацию о содержимом ячеек. Контроль треки.

Ответ 6

нарисован на месте.

Если вы измените на "DetailDisclosure" в Storyboard, тогда будет срабатывать метод. (xCode 4.6 DP3)

Ответ 7

Это еще один способ обработки кнопки раскрытия с помощью раскадровки. Вы должны щелкнуть ячейку просмотра таблицы и перейти к инспектору соединений. Существует раздел под названием Triggered Segues, и вы можете перетащить его из строки выбора в UIViewController, к которой вы хотите перейти. Сег будет происходить автоматически, и вы можете захватить prepareForSegue, чтобы зафиксировать уведомление, когда оно будет.
Аксессуар функцииButtonTappedForRowWithIndexPath никогда не вызывается для кнопки раскрытия. Он запрашивается только для подробной кнопки раскрытия.

Ответ 8

Мой tableView accessoryButtonTappedForRowWithIndexPath(…) не вызывался, когда была нажата кнопка Раскрытие подробностей. В конце концов я обнаружил, что проблема была просто в том, что делегат tableView не был установлен:

self.tableView.delegate = self