У меня есть табличное представление с кнопками, и я хочу использовать indexpath.row при нажатии на одну из них. Это то, что у меня есть сейчас, но всегда 0
var point = Int()
func buttonPressed(sender: AnyObject) {
let pointInTable: CGPoint = sender.convertPoint(sender.bounds.origin, toView: self.tableView)
let cellIndexPath = self.tableView.indexPathForRowAtPoint(pointInTable)
println(cellIndexPath)
point = cellIndexPath!.row
println(point)
}
swift
button
touch
nsindexpath
Винсент
источник
источник
Ответы:
У giorashc почти все было в порядке со своим ответом, но он упустил из виду тот факт, что в ячейках есть дополнительный
contentView
слой. Таким образом, мы должны пойти на один слой глубже:Это связано с тем, что внутри иерархии представлений у tableView есть ячейки в качестве подпредставлений, которые впоследствии имеют свои собственные «представления содержимого», поэтому вы должны получить супервизор этого представления содержимого, чтобы получить саму ячейку. В результате, если ваша кнопка содержится в подпредставлении, а не непосредственно в представлении содержимого ячейки, вам придется пройти на несколько уровней глубже, чтобы получить к ней доступ.
Вышеупомянутый - один из таких подходов, но не обязательно лучший. Несмотря на то, что он функциональный, он предполагает детали о
UITableViewCell
том, что Apple никогда не обязательно документировала, например, иерархию представлений. Это может быть изменено в будущем, и в результате приведенный выше код может вести себя непредсказуемо.В результате вышеизложенного из соображений долговечности и надежности я рекомендую использовать другой подход. В этой ветке есть много альтернатив, и я рекомендую вам прочитать их, но мой личный фаворит:
Удерживайте свойство замыкания в своем классе ячейки, пусть метод действия кнопки вызывает это.
Затем, когда вы создаете свою ячейку
cellForRowAtIndexPath
, вы можете присвоить значение своему закрытию.Переместив сюда свой код обработчика, вы можете воспользоваться уже существующим
indexPath
аргументом. Это гораздо более безопасный подход, чем тот, который указан выше, поскольку он не полагается на недокументированные черты характера.источник
Мой подход к такого рода проблемам - использовать протокол делегата между ячейкой и табличным представлением. Это позволяет вам сохранить обработчик кнопок в подклассе ячейки, что позволяет назначить обработчик действия касания ячейке прототипа в Interface Builder, сохраняя при этом логику обработчика кнопок в контроллере представления.
Это также позволяет избежать потенциально хрупкого подхода к навигации по иерархии представлений или использования
tag
свойства, которое имеет проблемы при изменении индексов ячеек (в результате вставки, удаления или переупорядочения).CellSubclass.swift
ViewController.swift
источник
buttonTapped
является функцией делегата и находится в контроллере представления. В моем примереsomeButtonTapped
это метод действия в ячейке@IBAction func someButtonTapped(sender: UIButton) { self.delegate?.buttonTapped(self) }
ОБНОВЛЕНИЕ : получение indexPath ячейки, содержащей кнопку (как раздел, так и строку):
Использование положения кнопки
Внутри вашего
buttonTapped
метода вы можете захватить позицию кнопки, преобразовать ее в координату в tableView, а затем получить indexPath строки по этой координате.ПРИМЕЧАНИЕ . Иногда вы можете столкнуться с крайним случаем, когда использование функции
view.convert(CGPointZero, to:self.tableView)
приводит к поискуnil
строки в точке, даже если там есть ячейка tableView. Чтобы исправить это, попробуйте передать реальную координату, которая немного смещена от начала координат, например:Предыдущий ответ: Использование свойства тега (возвращает только строку)
Вместо того, чтобы лазить по деревьям супервизора, чтобы захватить указатель на ячейку, которая содержит UIButton, существует более безопасный и повторяемый метод, использующий свойство button.tag, упомянутое Антонио выше, описанное в этом ответе и показанное ниже:
В
cellForRowAtIndexPath:
установке свойства тега:Затем в
buttonClicked:
функции вы ссылаетесь на этот тег, чтобы получить строку indexPath, в которой расположена кнопка:Я предпочитаю этот метод, так как обнаружил, что раскачивание в деревьях супервизора может быть рискованным способом разработки приложения. Кроме того, для объективного C я использовал эту технику в прошлом и был доволен результатом.
источник
indexPath.section
в дополнение кindexPath.row
(без сброса свойства тега какindexPath.section
),cellForRowAtIndexPath:
вы можете просто изменить тег наbutton.tag = indexPath
, а затем вbuttonClicked:
функции, к которой вы можете получить доступ, используяsender.tag.row
иsender.tag.section
.Используйте расширение для UITableView, чтобы получить ячейку для любого представления:
Ответ @ Paulw11 о настройке пользовательского типа ячейки со свойством делегата, который отправляет сообщения в табличное представление, - хороший способ, но для его настройки требуется определенный объем работы.
Я думаю, что ходить по иерархии представлений ячейки таблицы в поисках ячейки - плохая идея. Он хрупкий - если позже вы поместите кнопку в представление для целей макета, этот код, скорее всего, сломается.
Использование тегов просмотра также ненадежно. Вы должны не забыть настроить теги при создании ячейки, и если вы используете этот подход в контроллере представления, который использует теги представления для другой цели, вы можете иметь повторяющиеся номера тегов, и ваш код может не работать должным образом.
Я создал расширение для UITableView, которое позволяет вам получить indexPath для любого представления, содержащегося в ячейке представления таблицы. Он возвращает значение
Optional
nil, если переданное представление фактически не попадает в ячейку табличного представления. Ниже представлен полный исходный файл расширения. Вы можете просто поместить этот файл в свой проект, а затем использовать включенныйindexPathForView(_:)
метод для поиска indexPath, содержащего любое представление.Чтобы использовать его, вы можете просто вызвать метод в IBAction для кнопки, содержащейся в ячейке:
(Обратите внимание, что
indexPathForView(_:)
функция будет работать только в том случае, если переданный ей объект представления содержится в ячейке, которая в данный момент отображается на экране. Это разумно, поскольку представление, которое не отображается на экране, на самом деле не принадлежит конкретному indexPath; скорее всего, быть назначенным другому indexPath, когда содержащая его ячейка перерабатывается.)РЕДАКТИРОВАТЬ:
Вы можете скачать рабочий демонстрационный проект, в котором используется указанное выше расширение, из Github: TableViewExtension.git
источник
Для
Swift2.1
Я нашел способ сделать это, надеюсь, это поможет.
источник
У вас есть кнопка (myButton) или любое другое представление в ячейке. Назначьте тег в cellForRowAt как это
Теперь у вас tapFunction или любой другой. Извлеките его вот так и сохраните в локальной переменной.
После этого вы можете использовать в любом месте этот currentCellNumber, чтобы получить indexPath.row выбранной кнопки.
Наслаждайтесь!
источник
В Swift 4 просто используйте это:
источник
tableView
- это переменная выхода, на которую необходимо ссылаться до того, как этот ответ заработает.Очень просто получить Index Path Swift 4, 5
Как получить IndexPath внутри Btn Click:
источник
Поскольку отправителем обработчика событий является сама кнопка, я бы использовал
tag
свойство кнопки для хранения индекса, инициализированного вcellForRowAtIndexPath
.Но приложив немного больше усилий, я бы поступил совершенно по-другому. Если вы используете настраиваемую ячейку, я бы подошел к проблеме следующим образом:
cellForRowAtIndexPath
источник
Увидев предложение Paulw11 об использовании обратного вызова делегата, я хотел немного подробнее остановиться на нем / выдвинуть другое аналогичное предложение. Если вы не хотите использовать шаблон делегата, вы можете быстро использовать закрытие следующим образом:
Ваш класс ячейки:
Ваш
cellForRowAtIndexPath
метод:источник
Я нашел очень простой способ управления любой ячейкой в tableView и collectionView с помощью класса Model, и это отлично работает.
Сейчас действительно есть гораздо лучший способ справиться с этим. Это будет работать для управления ячейкой и значением.
Вот мой результат (снимок экрана), так что посмотрите это:
RNCheckedModel
, напишите код, как показано ниже.источник
Я использовал метод convertPoint, чтобы получить точку из tableview и передать эту точку методу indexPathForRowAtPoint, чтобы получить indexPath
источник
Попробуйте использовать #selector для вызова действия IB. В cellforrowatindexpath
Таким образом, вы можете получить доступ к indexpath внутри метода editButtonPressed
источник
В моем случае у меня есть несколько разделов, и индекс раздела и строки жизненно важен, поэтому в таком случае я просто создал свойство в UIButton, которое я установил indexPath ячейки следующим образом:
Затем установите свойство в cellForRowAt следующим образом:
Затем в handleTapAction вы можете получить indexPath следующим образом:
источник
Swift 4 и 5
Метод 1 с использованием делегата протокола
Например, у вас есть
UITableViewCell
имяMyCell
Теперь создайте
protocol
Следующим шагом создайте расширение
UITableView
В вашей
UIViewController
реализации протоколMyCellDelegate
Метод 2 с использованием замыканий
В
UIViewController
источник
В Swift 3. Также используются операторы защиты, избегая длинной цепочки скобок.
источник
Иногда кнопка может находиться внутри другого представления UITableViewCell. В этом случае superview.superview может не выдавать объект ячейки и, следовательно, indexPath будет равен нулю.
В этом случае мы должны продолжать поиск супервизора, пока не получим объект ячейки.
Функция для получения объекта ячейки с помощью супервизора
Теперь мы можем получить indexPath при нажатии кнопки, как показано ниже.
источник
источник