大学のコースの読書課題を追跡するためのアプリを作成しています。各ReadingAssignmentには、リーダーが課題の読み取りを完了したかどうかを示すブール値が含まれています。 ReadingAssignmentは、WeeklyAssignment配列に収集されます。ユーザーがラベルに触れてチェックマークを表示し、割り当てが完了したことを表示できるようにしたい。このタッチで.checkedプロパティもtrueに更新して、データを永続化できるようにします。それで、私はジェスチャーレコグナイザーにlabelTicked()メソッドを呼び出させようとしています。これは機能し、コンソールに出力されます。ただし、割り当てパラメーターを渡そうとすると、コンパイルは行われますが、「認識できないセレクター」エラーが発生してクラッシュします。私はここで見つけることができるすべてのトピックを読みましたが、解決策を見つけていません。 「:」はパラメータ付きのセレクタであることを意味しますが、実行できません。私が間違っていることを理解できますか?
func configureCheckmark(cell: UITableViewCell, withWeeklyAssignment assignment: WeeklyAssignment) {
let checkLabel = cell.viewWithTag(1002) as! UILabel
checkLabel.userInteractionEnabled = true
let gestureRecognizer = UITapGestureRecognizer(target: self, action: Selector("labelTicked:assignment"))
checkLabel.addGestureRecognizer(gestureRecognizer)
}
@objc func labelTicked(assignment: WeeklyAssignment) {
assignment.toggleCheckmark()
if assignment.checked {
label.text = "✔︎"
} else {
label.text = ""
}
}
LabelTicked()メソッドで更新できるように、UILabel checkLabelも渡したいと思います。ご協力いただきありがとうございます。
ここには2つの明確な問題があります。
セレクタの構文が間違っています。 _:
_は、パラメーター部分の始まりを示しません。単に、この関数がパラメーターを取ることを示すだけです。したがって、タップ認識機能はUITapGestureRecognizer(target: self, action: "labelTicked:")
として初期化する必要があります。簡単な修正。それは朗報です。
悪いニュース:完全な構文を使用しても、ここで設定した方法では機能しません。タップ認識機能は、WeeklyAssignment
オブジェクトをパラメーターとして渡すことができません。実際、カスタムパラメータを渡すことはできません。少なくとも、そうではありません。
ただし、渡すことができるのはそのsender
(通常、ジェスチャレコグナイザがアタッチされているビュー)です。メソッドを次のように変更して取得できます
_func labelTicked(sender: AnyObject) {
_
(何を期待するかが正確にわかっている場合は、AnyObject
をより具体的な型として宣言できることに注意してください。)
送信者を通過すると、理論的には、どのラベルがタップされたのか、どのデータエンティティがラベルに対応しているのか、そのエンティティのchecked
プロパティがどの状態にあるのかを理論的に推測できます。非常にすばやく複雑になりました。
一見単純なものが複雑になることは、通常、一歩下がってより良い解決策を探すべきであるという良い兆候です。
この時点でGestureRecognizer
アプローチ全体を削除することをお勧めします。代わりに、テーブルビューの各セルに、独自の「タップ再認識」機能がすでに備わっているという事実を利用します:_didSelectRowAtIndexPath:
_テーブルビューのデリゲートのメソッド。そこでは、提供されているNSIndexPath
を使用して、対応するモデルエンティティをデータソースから簡単に取得し、必要に応じてパラメーターを読み取って変更できます。 _cellForRowAtIndexPath:
_を使用して、正しいセルへの参照を取得し、それに応じてその内容を変更できます。
Swift言語が進化し、文字列ベースのセレクターの使用(たとえば、_"labelTicked:"
_)が非推奨としてフラグが立てられたので、答えに小さな更新を提供することが適切だと思います。
より最新の構文を使用すると、次のように関数を宣言できます。
_@objc func labelTicked(withSender sender: AnyObject) {
_
_#selector
_を使用して、次のようにジェスチャーレコグナイザーを初期化します。
_UITapGestureRecognizer(target: self, action: #selector(labelTicked(withSender:)))
_
その関数の正しいセレクタは_labelTicked:
_です。さらに、文字列をセレクタとして直接使用できます。したがって:
_let gestureRecognizer = UITapGestureRecognizer(target: self, action: "labelTicked:")
_
ただし、認識エンジンが起動したときに、メソッドに任意のオブジェクトを渡すように調整することはできません。これを行うためのより良い方法は、UITableViewCell
のサブクラスを作成することです。 AssignmentCell
としましょう。サブクラスにassignment
プロパティを指定し、_labelTicked:
_メソッドをAssignmentCell
に移動します。
ストーリーボードでセルを設計した場合は、タップ認識機能をストーリーボードの右側のラベルに追加し、認識機能をストーリーボードのセルの_labelTicked:
_メソッドに配線できます。
テーブルビューデータソースのtableView(_:cellForRowAtIndexPath:)
で、セルをデキューした後、そのassignment
プロパティをその行の割り当てに設定します。