カスタムテーブルビューセルのレイアウトにNIBファイルを使用しています。このセルには、lblNameと呼ばれるアウトレットを持つラベルがあります。このラベルにUITapGestureRecognizerを追加しても、関連付けられたイベントは発生しません。 userInteractionEnabled = YESがあります。
問題は、UILabelがTableViewにあり、テーブル/セルビューがタップをインターセプトしていることだと思います。これについて何かできますか?
UILabelが押されたときにカスタムアクションを実行するだけです!これを実行するためのソリューションはすべて私が見たものではばかげています。標準のツールセットを使用すると簡単です。しかし、明らかにそうではありません。
これが私が使っているコードです:
- (void)tapAction {
NSLog(@"Tap action");
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction)];
[recognizer setNumberOfTapsRequired:1];
//lblName.userInteractionEnabled = true; (setting this in Interface Builder)
[lblName addGestureRecognizer:recognizer];
}
簡単な方法:
そのラベルの上部にある非表示のボタンを使用することもできます。そのため、そのラベルにtapGestureを追加する作業が減ります。
代替方法:
そのUILabel
にはIBOutletを作成しないでください。これを行うと、カスタムクラス実装ファイルにアウトレットが追加されます。他のファイルではアクセスできません。したがって、そのラベルのタグをカスタムクラスIB
に設定し、cellForRowAtIndexPath:
方法。
更新:
cellForRowAtIndexPath:
方法、
for(UIView *view in cell.contentViews.subviews) {
if(view.tag == 1) {
UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction)];
[tap setNumberOfTapsRequired:1];
[view addGestureRecognizer:tap];
}
}
UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction)];
[recognizer setNumberOfTapsRequired:1];
lblName.userInteractionEnabled = YES;
[lblName addGestureRecognizer:recognizer];
これを行うことは問題なく動作します:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
...
// create you cell
UILabel *lbl = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 50)];
[lbl setText:@"example"];
[lbl setUserInteractionEnabled:YES];
[cell.contentView addSubview:lbl];
UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction:)];
tap.tag = [NSIndexPath row];
[tap setNumberOfTapsRequired:1];
[lbl addGestureRecognizer:tap];
...
}
- (void)tapAction:(id)sender {
switch(((UITapGestureRecognizer *)sender).view.tag) {
case 0:
// code
break;
case 1:
// code
break;
....
}
}
がIBでUILabelを作成する場合でも
ITableViewcellのUILabelにタップジェスチャーを追加するには、以下のコードを使用できます
UITapGestureRecognizer *tapGeature = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(lblClick:)];
tapGeature.delegate =self;
tapGeature.numberOfTapsRequired = 1;
cell.lbl.userInteractionEnabled = YES;
[cell.lbl addGestureRecognizer:tapGeature];
そしてセレクターメソッドにアクセスするため
- (void)lblClick:(UITapGestureRecognizer *)tapGesture {
UILabel *label = (UILabel *)tapGesture.view;
NSLog(@"Lable tag is ::%ld",(long)label.tag);
}
Swiftの場合
let tapGesture : UITapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: #selector(lblClick(tapGesture:)))
tapGesture.delegate = self
tapGesture.numberOfTapsRequired = 1
cell.lbl.userInteractionEnabled = true
cell.lbl.tag = indexPath.row
cell.lbl.addGestureRecognizer(tapGesture)
func lblClick(tapGesture:UITapGestureRecognizer){
print("Lable tag is:\(tapGesture.view!.tag)")
}
2019年の更新はSwift 5で、Hardik Thakkarのソリューションに基づいています。セルのUIlabelのタップを検出するには、以下のビューコントローラーでcellForRowAtメソッドを見つけます。
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {}
セルを返す前に、次のコードを上記のメソッドに配置します。
let tapGesture : UITapGestureRecognizer = UITapGestureRecognizer.init(target: self, action: #selector(labelTap(tapGesture:)))
tapGesture.delegate = self
tapGesture.numberOfTapsRequired = 1
cell.yourLabel.isUserInteractionEnabled = true
cell.yourLabel.tag = indexPath.row
cell.yourLabel.addGestureRecognizer(tapGesture)
return cell
タップを処理するメソッドをビューコントローラーに追加します。
@objc func labelTap(tapGesture:UITapGestureRecognizer){
print("Label tag is:\(tapGesture.view!.tag)")
}
セルの-awakeFromNibメソッドに次を追加できます
UITapGestureRecognizer* gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureRecognizerAction:)];
[self.yourLabel setUserInteractionEnabled:YES];
[self.yourLabel addGestureRecognizer:gesture];
UILabelにタップジェスチャーを割り当て、ユーザー操作を有効に設定すると、コールバック関数でセルビューからインデックスパスを見つけることができますが、スーパービューのネストを検索できます。
- (UITableViewCell *) findCellInSuperview:(UIView *)view
{
UITableViewCell *cell = nil;
NSString *className = NSStringFromClass([[view superview] class]);
if ([className isEqualToString:@"UITableViewCell"]) {
cell = (UITableViewCell *)[view superview];
} else {
if ([view superview] != nil) {
cell = [self findCellInSuperview:[view superview]];
}
}
return cell;
}
Swift 3の場合
let tapGesture : UITapGestureRecognizer = UITapGestureRecognizer.init(target: self, action:
#selector(lblClick(tapGesture:)))
tapGesture.delegate = self
tapGesture.numberOfTapsRequired = 1
cell.lbl.isUserInteractionEnabled = true
cell.lbl.tag = indexPath.row
cell.lbl.addGestureRecognizer(tapGesture)
その後
func lblClick(tapGesture:UITapGestureRecognizer){
print("Lable tag is:\(tapGesture.view!.tag)")
}
Dineshが提案した方法は、プロパティ変数を使用するforループなしで機能します。
UITapGestureRecognizer *tap=[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction)];
[tap setNumberOfTapsRequired:1];
[self.myUILabel addGestureRecognizer:tap];
Swiftの場合、これをcellForRowAtIndexPathメソッド内に追加できます。
var tap = UITapGestureRecognizer(target: self, action: "labelTapped")
tap.numberOfTapsRequired = 1
cell.label.addGestureRecognizer(tap)
cell.label.tag = indexPath.row
次にアクションのために
func labelTapped(gesture: UITapGestureRecognizer) {
let indexPath = NSIndexPath(forRow: gesture.view!.tag, inSection: 0)
let cell = tableView.cellForRowAtIndexPath(indexPath) as UITableViewCell
// Do whatever you want.
}