質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

解決済

1回答

336閲覧

Section毎に折りたたみ可能としたtableView上で、LongPress先がsectionかCellか判別したい。

退会済みユーザー

退会済みユーザー

総合スコア0

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2018/07/29 04:07

編集2018/07/30 04:37

セクションごとに折りたたみ機能をもたせたUITableViewUILongPressGestureRecognizerを追加して
ロングプレスされたpointがcellかSectionによって処理を分けたいのですが、どのようにしたら判別できるでしょうか?

tableViewがロングプレスされた際に、gestureのlocationからindexPathが取得できるのですが、Sectionをタップしても、ロングプレスしたSection直下のCellのindexpathしか取得できず(先頭のSectionだけは、ロングプレスすると、indexpathはnilと変換される。)、indexPathからロングプレスされたのがSectionかCellか判別することができません。senderに送られてくるlocation、view、subviewsあたりから取得できるcellとsectionを判別する基準があれば教えてください。

イメージ説明

TableViewロングタップ時の処理

swift

1 // LongPressGestureRecognizerはstoryBoardで設置、Action接続済 2 // longPressed leftTableView 3 @IBAction func savedListCellLongPressed(_ sender: UILongPressGestureRecognizer) { 4 if(sender.state == UIGestureRecognizerState.began) { 5 6 } else if (sender.state == UIGestureRecognizerState.ended) { 7 8 let point = sender.location(in: leftTableView) 9 let indexPath = leftTableView.indexPathForRow(at: point) 10 11 // ここでSectionとCellで処理を分けたい 12 13 // gifでの表示用アラート 14 let alert = UIAlertController(title: nil, message: nil, preferredStyle: .alert) 15 alert.title = "point/indexPath" 16 alert.message = "(point)\n(indexPath)" 17 18 alert.addAction( 19 UIAlertAction(title: "OK", style: .default, handler: nil )) 20 self.present(alert, animated: true, completion: nil) 21 22 } 23 }

上記の方法ではtableViewに設置したUILongPressGestureRecognizerでcellとSectionの判別ができないため、コード上でSectionに別途UILongPressGestureRecognizerを追加したところ、
Sectionをロングプレスすると、10%くらいの頻度でSectionではなくCellのロングプレスが反応してしまい正常に機能させることができません。これは実装の仕方に問題があるのでしょうか?

セクションとその折りたたみの実装

swift

1 2// titleOfSection 3 func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 4 let headerView = UIView(frame: CGRect(x: 0, y: 0, width: tableView.bounds.width, height: 30)) 5 headerView.backgroundColor = #colorLiteral(red: 0.1764705926, green: 0.4980392158, blue: 0.7568627596, alpha: 1) 6 7 let headerLabel = UILabel(frame: CGRect(x: 5, y: 0, width: tableView.bounds.width - 5, height: 30)) 8 headerLabel.text = sectionNameStrArray[section][0] 9 headerLabel.font = UIFont.boldSystemFont(ofSize: 15) 10 headerLabel.textAlignment = .left 11 headerLabel.textColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1) 12 13 // セクションに対応するtagを設定する 14 headerView.tag = section 15 16 // タップジェスチャを設定する 17 headerView.addGestureRecognizer( 18 UITapGestureRecognizer(target: self, action: #selector(self.tapHeader(gestureRecognizer:))) 19 ) 20 21 // ここのaddGestureRecognizerを有効にすると一見キチンと動くように見えるが、cellとSectionどちらのRecognizerが反応するかが明白でない動きをする。 22 /* 23 // ロングタップジェスチャを設定する 24 headerView.addGestureRecognizer( 25 UILongPressGestureRecognizer(target: self, action: #selector(self.longTapHeader(gestureRecognizer:))) 26 ) 27 */ 28 29 headerView.addSubview(headerLabel) 30 return headerView 31 } 32 33 // heightOfSection 34 func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 35 return 30 36 } 37 38// sectionHeaderTap 39 @objc func tapHeader(gestureRecognizer: UITapGestureRecognizer) { 40 guard let section = gestureRecognizer.view?.tag as Int! else { return } 41 42 // sectionの表示状態を取得する 43 let indicateStateOfSection = sectionNameStrArray[section][1] 44 45 // sectionの表示状態を設定する 46 if indicateStateOfSection == "T" { 47 sectionNameStrArray[section][1] = "F" 48 } else { 49 sectionNameStrArray[section][1] = "T" 50 } 51 52 leftTableView.reloadSections(NSIndexSet(index: section) as IndexSet, with: .none) 53 } 54 55 56// sectionHeaderLongTap 57 @objc func longTapHeader(gestureRecognizer: UITapGestureRecognizer) { 58 if(gestureRecognizer.state == UIGestureRecognizerState.began) { 59 60 } else if (gestureRecognizer.state == UIGestureRecognizerState.ended) { 61 performSegue(withIdentifier: "goEditSection", sender: nil) 62 } 63 } 64 } 65

対処したことを追記

双方のLongPressGedtureRecognizerに.cancelsTouchesInView = falseを設定。(SB上ではチェックを外す)したところ、
誤動作(SectionLongPressしてもCellLongPressが動く)することが稀になる。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

対症療法的でイマイチですが。

swift

1if let indexPath = tableView.indexPathForRow(at: point) { 2 let rectCell = tableView.rectForRow(at: indexPath) 3 if rectCell.contains(point) { 4 print("cell", indexPath) 5 } else { 6 print("section", indexPath.section) 7 } 8} else { 9 print("section 0") 10}

投稿2018/07/30 04:41

編集2018/07/30 05:05
fuzzball

総合スコア16731

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/07/30 05:34 編集

恐れ入ります。自分の用途には十分です。 ここまで動くと、たたんであるときにsectionが判別できないのがもったいない気がしてきます。 せっかく教えていただいたので、rectForHeaderあたりをつかってやってみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問