プログラムでUITableViewを作成し、そのセルアクセサリビューにUISwitchを追加しました。
これは、cellForRowAtIndexPath
メソッドのセルアクセサリビューのUISwitchのコードです。
UISwitch *accessorySwitch = [[UISwitch alloc]initWithFrame:CGRectZero];
[accessorySwitch setOn:NO animated:YES];
[accessorySwitch addTarget:self action:@selector(changeSwitch:) forControlEvents:UIControlEventValueChanged];
cell.accessoryView = accessorySwitch;
これは、ボタンがクリックされた後に呼び出されるメソッドです。
- (void)changeSwitch:(UISwitch *)sender{
UITableViewCell *cell = (UITableViewCell *)[sender superview];
NSIndexPath *indexPath = [self.filterTableView indexPathForCell:cell];
NSLog(@"%ld",(long)indexPath);
……………. My other code…….
}
IOS 6でインデックスパスの値を印刷できますが、iOS 7ではnilが印刷されますが、
IOS 7で何かが欠けていますか、iOS 7でindexPathを取得する他のアプローチがありますか
ありがとう、アルン。
NSLog(@"%ld",(long)indexPath);
が間違っていると、indexPathのポインターアドレスが出力されます
次のコードを使用してみてください
CGPoint center= sender.center;
CGPoint rootViewPoint = [sender.superview convertPoint:center toView:self.filterTableView];
NSIndexPath *indexPath = [self.filterTableView indexPathForRowAtPoint:rootViewPoint];
NSLog(@"%@",indexPath);
Swift解決策:このようなUITableView拡張機能はこれに役立ちます。
extension UITableView {
func indexPathForView(view: AnyObject) -> NSIndexPath? {
let originInTableView = self.convertPoint(CGPointZero, fromView: (view as! UIView))
return self.indexPathForRowAtPoint(originInTableView)
}
}
どこでも使用が簡単になります。
let indexPath = tableView.indexPathForView(button)
セルにボタンがある場合。スーパービューを呼び出すことでセルを取得できます。そして、この方法でIndexpathを取得できます。
(void)obButtonTap:(UIButton *)sender {
UITableViewCell *cell = (UITableViewCell *)sender.superview;
NSIndexPath *indexPath = [tableView indexPathForCell:cell];
}
CellForRowAtIndexPathメソッドで各スイッチにタグを割り当てることができます
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UISwitch *accessorySwitch = [[UISwitch alloc]initWithFrame:CGRectZero];
[accessorySwitch setOn:NO animated:YES];
[accessorySwitch addTarget:self action:@selector(changeSwitch:) forControlEvents:UIControlEventValueChanged];
cell.accessoryView = accessorySwitch;
accessorySwitch.tag = indexPath.row;
}
- (void)changeSwitch:(UISwitch *)sender{
NSIndexPath *indexPath = [NSIndexPath indexPathWithIndex:[sender tag]];
NSLog(@"%ld",(long)indexPath);
}
スイフト4:
extension UITableView {
func indexPathForView(view: AnyObject) -> NSIndexPath? {
let originInTableView = self.convert(CGPoint.zero, from: (view as! UIView))
return self.indexPathForRow(at: originInTableView)! as NSIndexPath
}
}
Swift 4変換、グローバル拡張を作成します。
extension UITableView {
func indexPathForView(view: UIView) -> IndexPath? {
let originInTableView = self.convert(CGPoint.zero, from: (view))
return self.indexPathForRow(at: originInTableView)
}
}
使用例:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = ...
cell.myButton.addTarget(self, action: #selector(myButtonAction(_:)), for: .primaryActionTriggered)
return cell
}
@objc func myButtonAction(_ button:UIButton) {
guard let ip = self.tableView.indexPathForView(view: button) else {
return
}
}
スイッチのsuperview
がtableViewCell
になると仮定して、おそらく火傷しているでしょう。たぶんiOS 7では、何らかの視覚効果を達成するために階層を変更しました。そこに新しいビューが挿入されている可能性があります。
UISwitch
をサブクラス化し、indexPath
プロパティを指定することもできます。次に、cellForRowAtIndexPath
で、そこに割り当てて参照できるようにします。
どのボタンがクリックされたかを知るためにボタンの位置に依存するのは危険だと思います。
キーとしてボタン/スイッチ自体を取り、値としてindexpathを取る辞書を作成することをお勧めします。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
...
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
NSValue * accessorySwitchKey = [NSValue valueWithNonretainedObject:[cell settingSwitch]];
[[self switchIndexDictionary]setObject:indexPath accessorySwitchKey];
...
}
次に、スイッチ/ボタンがトリガーされると、辞書から簡単にインデックスパスを取得します:
- (void)toggleSetting:(id)sender
{
UISwitch *selectedSwitch = (UISwitch *) sender;
NSValue * accessorySwitchKey = [NSValue valueWithNonretainedObject:selectedSwitch];
NSIndexPath *indexPath = [[self switchIndexDictionary]objectForKey: accessorySwitchKey];
}