@ Ответ Paulw11 на настройку настраиваемого типа ячейки с свойством делегирования, который отправляет сообщения в представление таблицы, является хорошим путь к работе, но для этого требуется определенная работа.
Я думаю, что ходя по иерархии представлений ячейки таблицы, ища ячейку - плохая идея. Он хрупкий - если вы позже вложите свою кнопку в представление для целей макета, этот код, вероятно, сломается.
Использование тегов просмотра также является хрупким. Вы должны помнить о настройке тегов при создании ячейки, и если вы используете этот подход в контроллере представления, который использует теги просмотра для другой цели, у вас могут быть дублированные номера тегов, и ваш код может работать не так, как ожидалось.
Я создал расширение для UITableView, которое позволяет вам получить indexPath для любого представления, которое содержится в ячейке представления таблицы. Он возвращает Optional
, который будет равен нулю, если переданное представление фактически не попадает в ячейку представления таблицы. Ниже находится файл источника расширения в полном объеме. Вы можете просто поместить этот файл в свой проект, а затем использовать метод indexPathForView(_:)
, чтобы найти indexPath, который содержит любое представление.
//
// UITableView+indexPathForView.swift
// TableViewExtension
//
// Created by Duncan Champney on 12/23/16.
// Copyright © 2016-2017 Duncan Champney.
// May be used freely in for any purpose as long as this
// copyright notice is included.
import UIKit
public extension UITableView {
/**
This method returns the indexPath of the cell that contains the specified view
- Parameter view: The view to find.
- Returns: The indexPath of the cell containing the view, or nil if it can't be found
*/
func indexPathForView(_ view: UIView) -> IndexPath? {
let center = view.center
let viewCenter = self.convert(center, from: view.superview)
let indexPath = self.indexPathForRow(at: viewCenter)
return indexPath
}
}
Чтобы использовать его, вы можете просто вызвать метод в IBAction для кнопки, которая содержится в ячейке:
func buttonTapped(_ button: UIButton) {
if let indexPath = self.tableView.indexPathForView(button) {
print("Button tapped at indexPath \(indexPath)")
}
else {
print("Button indexPath not found")
}
}
(Обратите внимание, что функция indexPathForView(_:)
будет работать, только если объект представления, который он передал, содержится в ячейке, которая в настоящее время находится на экране. Это разумно, так как представление, которое не является на экране, фактически не относится к определенному indexPath, оно, вероятно, будет назначено другому indexPath, когда он содержит ячейку, перерабатывается.)
Вы можете загрузить рабочий демонстрационный проект, который использует указанное выше расширение из Github: TableViewExtension.git
Для этого вы можете использовать Arrays.copyOfRange ()
.
Arrays.copyOfRange()
появился в Java 1.6. Если у вас более старая версия, то внутри используется System.arraycopy(...)
. Вот как это реализовано:
public static <U> U[] copyOfRange(U[] original, int from, int to) {
Class<? extends U[]> newType = (Class<? extends U[]>) original.getClass();
int newLength = to - from;
if (newLength < 0) {
throw new IllegalArgumentException(from + " > " + to);
}
U[] copy = ((Object) newType == (Object)Object[].class)
? (U[]) new Object[newLength]
: (U[]) Array.newInstance(newType.getComponentType(), newLength);
System.arraycopy(original, from, copy, 0,
Math.min(original.length - from, newLength));
return copy;
}
Вы можете использовать байтовые буферы в качестве представлений поверх исходного массива.