セクションごとに折りたたみ機能をもたせたUITableView
にUILongPressGestureRecognizer
を追加して
ロングプレスされた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が動く)することが稀になる。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2018/07/30 05:34 編集