2つのファイルがあります。
MyTabelCell.Swift関数でindexPath.rowを取得できますか?
これがmyTableCell.Swiftです
import UIKit
import Parse
import ActiveLabel
class myTableCell : UITableViewCell {
//Button
@IBOutlet weak var commentBtn: UIButton!
@IBOutlet weak var likeBtn: UIButton!
@IBOutlet weak var moreBtn: UIButton!
override func awakeFromNib() {
super.awakeFromNib()
}
@IBAction func likeBtnTapped(_ sender: AnyObject) {
//declare title of button
let title = sender.title(for: UIControlState())
//I want get indexPath.row in here!
}
これがmyTableViewController.Swiftです
class myTableViewController: UITableViewController {
//Default func
override func viewDidLoad() {
super.viewDidLoad()
//automatic row height
tableView.estimatedRowHeight = 450
tableView.rowHeight = UITableViewAutomaticDimension
}
// cell config
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//define cell
let cell = tableView.dequeueReusableCell(withIdentifier: "myTableCell", for: indexPath) as! myTableCell
}
ご覧のとおり... liktBtnTapped関数myTableCellでindexPath.rowを取得しようとしています。
IndexPath.rowにアクセスまたは取得する方法を教えてください。
特定のタイプの親ビューを見つけるために、UIResponder
(UIView
から継承する)で使用できる再帰メソッドを使用してUIResponder
拡張を作成しました。
import UIKit
extension UIResponder {
func next<T: UIResponder>(_ type: T.Type) -> T? {
return next as? T ?? next?.next(type)
}
}
これを使用して、セルのテーブルビューとインデックスパスの便利な読み取り専用の計算プロパティでUITableViewCell
を拡張できます。
extension UITableViewCell {
var tableView: UITableView? {
return next(UITableView.self)
}
var indexPath: IndexPath? {
return tableView?.indexPath(for: self)
}
}
これを例で使用する方法を次に示します。
@IBAction func likeBtnTapped(_ sender: AnyObject) {
//declare title of button
let title = sender.title(for: UIControlState())
//I want get indexPath.row in here!
indexPath.flatMap { print($0) }
}
Swift 4 +
セル内でこれを試してください。
func getIndexPath() -> IndexPath? {
guard let superView = self.superview as? UITableView else {
print("superview is not a UITableView - getIndexPath")
return nil
}
indexPath = superView.indexPath(for: self)
return indexPath
}
簡単..ボタンアクション内で次のように実行できます。
let section = 0
let row = sender.tag
let indexPath = IndexPath(row: row, section: section)
let cell: myTableCell = self.feedTableView.cellForRow(at: indexPath) as! myTableCell
その後、cellForRowAtIndexPath
で:
// add the row as the tag
cell.button.tag = indexPath.row
スウィフト4.1。ここで、IndexPathを取得する関数を作成しました。 UIView(UIButton、UITextFieldなど)とUITableViewオブジェクトを渡すだけで、IndexPathを取得できます。
func getIndexPathFor(view: UIView, tableView: UITableView) -> IndexPath? {
let point = tableView.convert(view.bounds.Origin, from: view)
let indexPath = tableView.indexPathForRow(at: point)
return indexPath
}
Swift 4.2の別のアプローチであり、スーパービューが常にテーブルビューであることを前提としない
extension UITableViewCell{
var tableView:UITableView?{
return superview as? UITableView
}
var indexPath:IndexPath?{
return tableView?.indexPath(for: self)
}
}
使用例
@IBAction func checkBoxAction(_ sender: UIButton) {
guard let indexPath = indexPath else { return }
sender.isSelected = !sender.isSelected
myCustomCellDelegate?.checkBoxTableViewCell(didSelectCheckBox: sender.isSelected, for: indexPath)
}
それを行う別の方法
import UIKit
import Parse
import ActiveLabel
class myTableCell : UITableViewCell {
//Button
@IBOutlet weak var commentBtn: UIButton!
@IBOutlet weak var likeBtn: UIButton!
@IBOutlet weak var moreBtn: UIButton!
override func awakeFromNib() {
super.awakeFromNib()
}
}
class myTableViewController: UITableViewController {
//Default func
//assuming you have an array for your table data source
var arrayOfTitles = [String]()
override func viewDidLoad() {
super.viewDidLoad()
//automatic row height
tableView.estimatedRowHeight = 450
tableView.rowHeight = UITableViewAutomaticDimension
}
// cell config
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
//define cell
let cell = tableView.dequeueReusableCell(withIdentifier: "myTableCell", for: indexPath) as! myTableCell
cell.commentBtn.tag = indexPath.row
cell.commentBtn.addTarget(self, action: #selector(likeBtnTapped(_:), forControlEvents:.TouchUpInside)
//cell config end
@IBAction func likeBtnTapped(sender: UIButton) {
let btn = sender
let indexP = NSIndexPath(forItem: btn.tag, inSection: 0)
let cell = tableView.dequeueReusableCell(withIdentifier: "myTableCell", for: indexP) as! myTableCell
//I want get indexPath.row in here!
let title = arrayOfTitles[indexP.row]
//declare title of button
cell.commentBtn.setTitle(title, forState: UIControlState.Normal)
}
}
セルクラスにプロパティindexPath
を作成し、セルが再利用されるときにcellForRowAtIndexPath
に設定します。
ただし、注意が必要です。セルを再配置するテーブルビューメソッドの中には、cellForRowAtIndexPath
を呼び出さないものがあります。この場合を考慮する必要があります。
ただし、常にreloadData()
のみを使用する場合は、安全で非常に簡単です。
もう1つの方法は、controllingの事柄に関するコードをcontrollerクラスに戻し、インデックスパスをキャプチャするコールバッククロージャを介して実行することです。
私のソリューションはUITableViewCellをサブクラス化することでしたので、IndexPathプロパティを追加できます。ストーリーボードのテーブルビューセルにカスタムクラスを割り当てます。 rowAtIndexPathが呼び出されたときにIndexPath値を割り当てます。
class MyTableViewCell: UITableViewCell {
var indexPath: IndexPath?
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "cellid1", for: indexPath)
(cell as? MyTableViewCell)?.indexPath = indexPath
return cell
}
スイフト5:
if
let collectionView = superview as? UICollectionView,
let index = collectionView.indexPath(for: self)
{
// stuff
}