ตรวจจับ UIButton ที่ถูกกดใน UITableView


212

ฉันมีUITableView5 UITableViewCellsข้อ แต่ละเซลล์มีเซลล์UIButtonที่ตั้งค่าไว้ดังนี้:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
     NSString *identifier = @"identifier";
     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
     if (cell == nil) {
         cell = [[UITableView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
         [cell autorelelase];

         UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 5, 40, 20)];
         [button addTarget:self action:@selector(buttonPressedAction:) forControlEvents:UIControlEventTouchUpInside];
         [button setTag:1];
         [cell.contentView addSubview:button];

         [button release];
     }

     UIButton *button = (UIButton *)[cell viewWithTag:1];
     [button setTitle:@"Edit" forState:UIControlStateNormal];

     return cell;
}

คำถามของฉันคือ: ในbuttonPressedAction:วิธีฉันจะทราบได้อย่างไรว่ากดปุ่มใด ฉันได้พิจารณาการใช้แท็ก แต่ฉันไม่แน่ใจว่านี่เป็นเส้นทางที่ดีที่สุด ฉันต้องการติดแท็กindexPathลงบนตัวควบคุมอย่างใด

- (void)buttonPressedAction:(id)sender
{
    UIButton *button = (UIButton *)sender;
    // how do I know which button sent this message?
    // processing button press for this row requires an indexPath. 
}

มาตรฐานวิธีการทำเช่นนี้คืออะไร

แก้ไข:

ฉันได้แก้ไขมันโดยทำสิ่งต่อไปนี้ ฉันยังต้องการที่จะแสดงความคิดเห็นว่านี่เป็นวิธีมาตรฐานในการทำหรือมีวิธีที่ดีกว่าหรือไม่?

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
     NSString *identifier = @"identifier";
     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
     if (cell == nil) {
         cell = [[UITableView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
         [cell autorelelase];

         UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 5, 40, 20)];
         [button addTarget:self action:@selector(buttonPressedAction:) forControlEvents:UIControlEventTouchUpInside];
         [cell.contentView addSubview:button];

         [button release];
     }

     UIButton *button = (UIButton *)[cell.contentView.subviews objectAtIndex:0];
     [button setTag:indexPath.row];
     [button setTitle:@"Edit" forState:UIControlStateNormal];

     return cell;
}

- (void)buttonPressedAction:(id)sender
{
    UIButton *button = (UIButton *)sender;
    int row = button.tag;
}

สิ่งสำคัญที่ควรทราบคือฉันไม่สามารถตั้งค่าแท็กในการสร้างเซลล์ได้เนื่องจากเซลล์อาจถูกลบออกแทน รู้สึกสกปรกมาก จะต้องมีวิธีที่ดีกว่า


ฉันไม่เห็นปัญหาใด ๆ กับการใช้โซลูชันแท็กของคุณ เซลล์ถูกนำกลับมาใช้ใหม่ดังนั้นจึงเหมาะสมที่จะตั้งแท็กให้กับดัชนีแถวในแบบที่คุณกำลังทำอยู่ที่นี่ ฉันพบว่านี่เป็นคำตอบที่สวยงามกว่าการแปลงตำแหน่งสัมผัสเป็นดัชนีแถวตามที่แนะนำด้านล่าง
Erik van der Neut

คำตอบ:


400

ในตัวอย่างอุปกรณ์เสริมของ Apple มีการใช้วิธีการดังต่อไปนี้:

[button addTarget:self action:@selector(checkButtonTapped:) forControlEvents:UIControlEventTouchUpInside];

จากนั้นในตัวจัดการแบบสัมผัสตัวจัดการแบบสัมผัสที่ดึงและเส้นทางดัชนีถูกคำนวณจากพิกัดนั้น:

- (void)checkButtonTapped:(id)sender
{
    CGPoint buttonPosition = [sender convertPoint:CGPointZero toView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
    if (indexPath != nil)
    {
     ...
    }
}

ใช่นี่คือสิ่งที่ฉันตัดสิน (ดูการแก้ไขของฉัน) ฉันเห็นด้วยกับคุณว่ามันไม่เหมาะสม
rein

2
แต่คุณเพิ่ม UIButton ลงใน UITableViewCell ด้วยตัวคุณเองดังนั้นคุณต้องสอดคล้องกับสิ่งที่คุณทำเมื่อสร้างเซลล์ แม้ว่าวิธีการนี้จะดูไม่สง่างามจริงๆฉันต้องยอมรับ
Vladimir

1
สำหรับวิธีแรกคุณจะต้องคว้า [[ปุ่มผู้ดูแล] superview] เนื่องจากการโทร superview ครั้งแรกจะให้ contentView และในที่สุดข้อที่สองจะให้ UITableViewCell โซลูชันที่สองทำงานได้ไม่ดีหากคุณกำลังเพิ่ม / ลบเซลล์เนื่องจากจะทำให้ดัชนีแถวไม่ถูกต้อง ดังนั้นฉันจึงไปกับวิธีแก้ปัญหาแรกตามที่อธิบายไว้และทำงานได้สมบูรณ์แบบ
raidfive

3
นี่จะเลือกเซลล์ที่เป็นเจ้าของได้อย่างน่าเชื่อถือ: ปุ่ม UIView * view =; ในขณะที่ (! [ดู isKindOfClass: [คลาส UITableViewCell]]) {view = [ดู superview]}
Jacob Lyles

1
มีกับดักเมื่อใช้: [ปุ่ม addTarget: การกระทำด้วยตนเอง: @selector (checkButtonTapped :) สำหรับControlEvents: UIControlEventTouchUpInside]; เพราะ addTarget: action: forControlEvents: จะเพิ่มเป้าหมายและการกระทำซ้ำหลายรายการเมื่อคุณเลื่อนตารางมันจะไม่ลบเป้าหมายและการกระทำก่อนหน้าดังนั้นวิธีการ checkButtonTapped: จะถูกเรียกหลายครั้งเมื่อคุณคลิกปุ่ม คุณควรลบเป้าหมายและการกระทำก่อนที่จะเพิ่มพวกเขา
bandw

48

ฉันพบวิธีการใช้ superview ของ superview เพื่อรับการอ้างอิงไปยัง indexPath ของเซลล์ทำงานได้อย่างสมบูรณ์ ขอบคุณ iphonedevbook.com (macnsmith) สำหรับข้อความลิงค์เคล็ดลับ

-(void)buttonPressed:(id)sender {
 UITableViewCell *clickedCell = (UITableViewCell *)[[sender superview] superview];
 NSIndexPath *clickedButtonPath = [self.tableView indexPathForCell:clickedCell];
...

}

โคโคนัทส่วนรหัสของคุณชี้ให้ฉันในทิศทางที่ถูกต้องสำหรับการเปลี่ยนแปลงของฉันเองในปัญหานี้ ขอบคุณ! ในกรณีที่คนอื่นต้องการมันกรณีพิเศษของฉันคือปุ่มอยู่ในเซลล์ที่กำหนดเองที่ถูกแสดงเป็นส่วนหนึ่งของส่วนท้าย ฉันจะเพิ่มรหัสด้านล่าง
ซอฟต์แวร์พัฒนา

หากคุณ (ตัวอ่านสแต็คโอเวอร์โฟลว์) ลองทำสิ่งนี้และมันไม่ได้ผลสำหรับคุณตรวจสอบว่าในการติดตั้ง UIButton ของคุณนั้นเป็นหลานของ UITableViewCell หรือไม่ ในการดำเนินการของฉัน UIButton ของฉันเป็นลูกโดยตรงของ UITableViewCell ของฉันดังนั้นฉันต้องถอด "กำกับ" หนึ่งในรหัสของ Cocoanut ออกมา
Jon Schneider

29
นี่เป็นสิ่งที่ผิดมากและเสียในระบบปฏิบัติการเวอร์ชันใหม่กว่า อย่าเดินตามต้นไม้ที่คุณไม่ได้เป็นเจ้าของ
Kenrik มีนาคม

2
นี่ใช้งานได้สำหรับฉันใน iOS 6 แต่ใช้งานไม่ได้ใน iOS 7 ดูเหมือนว่า @KenrikMarch มีจุดที่ถูกต้อง!
Jon Schneider

3
ใน iOS 7 เป็นอีกหนึ่งขั้นตอนในการควบคุม เช่น [[[ผู้ควบคุมผู้ส่ง] superview] superView];
CW0007007

43

นี่คือวิธีที่ฉันทำ ง่ายและรัดกุม:

- (IBAction)buttonTappedAction:(id)sender
{
    CGPoint buttonPosition = [sender convertPoint:CGPointZero
                                           toView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:buttonPosition];
    ...
}

2
ง่ายยิ่งขึ้น: ใช้CGPointZeroแทนCGPointMake(0, 0);-)
Jakob W

ง่ายต่อการทำงานกับมัน นอกจากเรื่องง่ายที่จะแปลเป็นสวิฟท์ 3. คุณจะดีที่สุด :)
ฟรานซิสโรเมโร

แปลสิ่งนี้เป็น Swift ด้านล่าง ทางออกที่ง่ายที่สุดที่ฉันหาได้ ขอบคุณคริส!
Rutger Huijsmans

6

พบทางออกที่ดีสำหรับปัญหานี้ที่อื่นไม่ยุ่งกับแท็กที่ปุ่ม:

- (void)buttonPressedAction:(id)sender {

    NSSet *touches = [event allTouches];
    UITouch *touch = [touches anyObject];
    CGPoint currentTouchPosition = [touch locationInView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint: currentTouchPosition];

    // do stuff with the indexPath...
}

5
มันไม่ชัดเจนในตัวอย่างนี้ที่คุณได้รับวัตถุ 'เหตุการณ์'
Nick Ludlam

นี่คือทางออกที่ฉันไปด้วย การใช้แท็กไม่สามารถคาดเดาได้เมื่อเพิ่ม / ลบแถวเนื่องจากดัชนีมีการเปลี่ยนแปลง นอกจากนี้
raidfive

@NickLudlam: อาจจะเป็นวิธีที่ชื่อไม่ได้แต่buttonPressedAction: buttonPressedAction:forEvent:
KPM

5

วิธีการเกี่ยวกับการส่งข้อมูลเช่นNSIndexPathในการUIButtonใช้การฉีดรันไทม์

1) คุณต้องใช้งานจริงในการนำเข้า

2) เพิ่มค่าคงที่แบบคงที่

3) เพิ่มNSIndexPathปุ่มของคุณใน runtime โดยใช้:

(เป็นโมฆะ) setMetaData: (id) เป้าหมาย withObject: (id) newObj

4) กดปุ่มรับเมตาดาต้าโดยใช้:

(ID) เมตา (ID) เป้าหมาย

สนุก

    #import <objc/runtime.h>
    static char const * const kMetaDic = "kMetaDic";


    #pragma mark - Getters / Setters

- (id)metaData:(id)target {
    return objc_getAssociatedObject(target, kMetaDic);
}

- (void)setMetaData:(id)target withObject:(id)newObj {
    objc_setAssociatedObject(target, kMetaDic, newObj, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}



    #On the cell constructor
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
    ....
    cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    ....
    [btnSocial addTarget:self
                                   action:@selector(openComments:)
                         forControlEvents:UIControlEventTouchUpInside];

    #add the indexpath here or another object
    [self setMetaData:btnSocial withObject:indexPath];

    ....
    }



    #The action after button been press:

    - (IBAction)openComments:(UIButton*)sender{

        NSIndexPath *indexPath = [self metaData:sender];
        NSLog(@"indexPath: %d", indexPath.row);

        //Reuse your indexpath Now
    }

1
หากตารางถูกจัดเรียงใหม่หรือลบแถวแล้วจะไม่ทำงาน
Neil

5

สิ่งที่ต้องทำ (@Vladimir) คำตอบคือ Swift:

var buttonPosition = sender.convertPoint(CGPointZero, toView: self.tableView)
var indexPath = self.tableView.indexPathForRowAtPoint(buttonPosition)!

แม้ว่าการตรวจสอบindexPath != nilจะให้นิ้วแก่ฉัน ... "NSIndexPath ไม่ใช่ประเภทย่อยของ NSString"


5

ด้วย Swift 4.2 และ iOS 12 คุณสามารถเลือกตัวอย่างที่สมบูรณ์ 5 ข้อต่อไปนี้เพื่อแก้ปัญหาของคุณ


# 1 ใช้UIView's convert(_:to:)และUITableView' sindexPathForRow(at:)

import UIKit

private class CustomCell: UITableViewCell {

    let button = UIButton(type: .system)

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        button.setTitle("Tap", for: .normal)
        contentView.addSubview(button)

        button.translatesAutoresizingMaskIntoConstraints = false
        button.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
        button.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
        button.topAnchor.constraint(equalToSystemSpacingBelow: contentView.topAnchor, multiplier: 1).isActive = true
        button.leadingAnchor.constraint(greaterThanOrEqualToSystemSpacingAfter: contentView.leadingAnchor, multiplier: 1).isActive = true
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}
import UIKit

class TableViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.register(CustomCell.self, forCellReuseIdentifier: "CustomCell")
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 3
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell
        cell.button.addTarget(self, action: #selector(customCellButtonTapped), for: .touchUpInside)
        return cell
    }

    @objc func customCellButtonTapped(_ sender: UIButton) {
        let point = sender.convert(CGPoint.zero, to: tableView)
        guard let indexPath = tableView.indexPathForRow(at: point) else { return }
        print(indexPath)
    }

}

# 2 ใช้UIView's convert(_:to:)และUITableView' sindexPathForRow(at:) (ทางเลือก)

นี้เป็นทางเลือกให้กับตัวอย่างก่อนหน้านี้ที่เราผ่านnilไปพารามิเตอร์ในtarget addTarget(_:action:for:)วิธีนี้หากผู้ตอบกลับคนแรกไม่ได้ลงมือปฏิบัติก็จะถูกส่งไปยังผู้เผชิญเหตุต่อไปในห่วงโซ่การตอบกลับจนกว่าจะพบการปฏิบัติที่เหมาะสม

import UIKit

private class CustomCell: UITableViewCell {

    let button = UIButton(type: .system)

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        button.setTitle("Tap", for: .normal)
        button.addTarget(nil, action: #selector(TableViewController.customCellButtonTapped), for: .touchUpInside)
        contentView.addSubview(button)

        button.translatesAutoresizingMaskIntoConstraints = false
        button.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
        button.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
        button.topAnchor.constraint(equalToSystemSpacingBelow: contentView.topAnchor, multiplier: 1).isActive = true
        button.leadingAnchor.constraint(greaterThanOrEqualToSystemSpacingAfter: contentView.leadingAnchor, multiplier: 1).isActive = true
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}
import UIKit

class TableViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.register(CustomCell.self, forCellReuseIdentifier: "CustomCell")
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 3
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell
        return cell
    }

    @objc func customCellButtonTapped(_ sender: UIButton) {
        let point = sender.convert(CGPoint.zero, to: tableView)
        guard let indexPath = tableView.indexPathForRow(at: point) else { return }
        print(indexPath)
    }

}

# 3 ใช้UITableViewของindexPath(for:)รูปแบบและผู้รับมอบสิทธิ์

ในตัวอย่างนี้เราตั้งค่าตัวควบคุมมุมมองเป็นตัวแทนของเซลล์ เมื่อปุ่มของเซลล์ถูกทาบทามมันจะทริกเกอร์การเรียกไปยังวิธีการที่เหมาะสมของผู้รับมอบสิทธิ์

import UIKit

protocol CustomCellDelegate: AnyObject {
    func customCellButtonTapped(_ customCell: CustomCell)
}

class CustomCell: UITableViewCell {

    let button = UIButton(type: .system)
    weak var delegate: CustomCellDelegate?

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        button.setTitle("Tap", for: .normal)
        button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
        contentView.addSubview(button)

        button.translatesAutoresizingMaskIntoConstraints = false
        button.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
        button.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
        button.topAnchor.constraint(equalToSystemSpacingBelow: contentView.topAnchor, multiplier: 1).isActive = true
        button.leadingAnchor.constraint(greaterThanOrEqualToSystemSpacingAfter: contentView.leadingAnchor, multiplier: 1).isActive = true
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    @objc func buttonTapped(sender: UIButton) {
        delegate?.customCellButtonTapped(self)
    }

}
import UIKit

class TableViewController: UITableViewController, CustomCellDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.register(CustomCell.self, forCellReuseIdentifier: "CustomCell")
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 3
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell
        cell.delegate = self
        return cell
    }

    // MARK: - CustomCellDelegate

    func customCellButtonTapped(_ customCell: CustomCell) {
        guard let indexPath = tableView.indexPath(for: customCell) else { return }
        print(indexPath)
    }

}

# 4 ใช้UITableView's indexPath(for:)และการปิดสำหรับคณะผู้แทน

นี่เป็นอีกทางเลือกหนึ่งของตัวอย่างก่อนหน้านี้ที่เราใช้การปิดแทนการประกาศผู้มอบหมายโปรโตคอลเพื่อจัดการกับการแตะปุ่ม

import UIKit

class CustomCell: UITableViewCell {

    let button = UIButton(type: .system)
    var buttontappedClosure: ((CustomCell) -> Void)?

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        button.setTitle("Tap", for: .normal)
        button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
        contentView.addSubview(button)

        button.translatesAutoresizingMaskIntoConstraints = false
        button.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
        button.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true
        button.topAnchor.constraint(equalToSystemSpacingBelow: contentView.topAnchor, multiplier: 1).isActive = true
        button.leadingAnchor.constraint(greaterThanOrEqualToSystemSpacingAfter: contentView.leadingAnchor, multiplier: 1).isActive = true
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    @objc func buttonTapped(sender: UIButton) {
        buttontappedClosure?(self)
    }

}
import UIKit

class TableViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.register(CustomCell.self, forCellReuseIdentifier: "CustomCell")
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 3
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell
        cell.buttontappedClosure = { [weak tableView] cell in
            guard let indexPath = tableView?.indexPath(for: cell) else { return }
            print(indexPath)
        }
        return cell
    }

}

# 5 ใช้UITableViewCell's accessoryTypeและUITableViewDelegate' stableView(_:accessoryButtonTappedForRowWith:)

ถ้าปุ่มของคุณเป็นUITableViewCell'การควบคุมอุปกรณ์มาตรฐานแตะใดที่มันจะทำให้การเรียกไปยังUITableViewDelegate' s tableView(_:accessoryButtonTappedForRowWith:)ช่วยให้คุณได้รับเส้นทางดัชนีที่เกี่ยวข้อง

import UIKit

private class CustomCell: UITableViewCell {

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        accessoryType = .detailButton
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}
import UIKit

class TableViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.register(CustomCell.self, forCellReuseIdentifier: "CustomCell")
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 3
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "CustomCell", for: indexPath) as! CustomCell
        return cell
    }

    override func tableView(_ tableView: UITableView, accessoryButtonTappedForRowWith indexPath: IndexPath) {
        print(indexPath)
    }

}

5
func buttonAction(sender:UIButton!)
    {
        var position: CGPoint = sender.convertPoint(CGPointZero, toView: self.tablevw)
        let indexPath = self.tablevw.indexPathForRowAtPoint(position)
        let cell: TableViewCell = tablevw.cellForRowAtIndexPath(indexPath!) as TableViewCell
        println(indexPath?.row)
        println("Button tapped")
    }

3

ฉันจะใช้คุณสมบัติแท็กเหมือนที่คุณพูดการตั้งค่าแท็กดังนี้:

[button setTag:indexPath.row];

จากนั้นรับแท็กภายในของปุ่มกดการดำเนินการเช่น:

((UIButton *)sender).tag

หรือ

UIButton *button = (UIButton *)sender; 
button.tag;

5
วิธีนี้ไม่สมบูรณ์สำหรับตารางที่มีส่วนต่างๆ
ohhorob

ไม่คุณสามารถใช้ฟังก์ชั่นง่าย ๆ เพื่อใส่หัวข้อลงในแท็กได้เช่นกัน
ACBurk

2
tagเป็นจำนวนเต็ม ดูเหมือนจะค่อนข้างงุ่มง่ามที่จะเข้ารหัส / ถอดรหัสพา ธ ดัชนีลงในแท็กมุมมอง
ohhorob

ถูกต้อง แต่มันเป็นวิธีแก้ปัญหาแม้ว่าจะไม่ใช่วิธีที่ฉันใช้ถ้ามีส่วน ทั้งหมดที่ฉันพยายามจะบอกคือมันสามารถทำได้โดยใช้วิธีนี้ว่ามันไม่ได้หัก รุ่นที่ดีกว่าและซับซ้อนกว่านี้จะเป็นตัวกำหนดดัชนีพา ธ จากตำแหน่งของปุ่มภายใน UITableView อย่างไรก็ตามเนื่องจากบังเหียนได้กล่าวว่าเขามีเซลล์เพียงห้าเซลล์เท่านั้น (ไม่มีส่วน) จึงอาจทำให้วิธีการนี้ซับซ้อนกว่าและความคิดเห็นเริ่มต้นของคุณและหัวข้อความคิดเห็นทั้งหมดนี้ไม่มีจุดหมาย
ACBurk

3

แม้ว่าฉันจะชอบวิธีการติดแท็ก ... หากคุณไม่ต้องการใช้แท็กด้วยเหตุผลใดก็ตามคุณสามารถสร้างสมาชิกNSArrayของปุ่มที่สร้างไว้ล่วงหน้าได้:

NSArray* buttons ;

จากนั้นสร้างปุ่มเหล่านั้นก่อนที่จะเรนเดอร์ tableView และผลักพวกมันเข้าไปในอาเรย์

จากนั้นภายในtableView:cellForRowAtIndexPath:ฟังก์ชั่นที่คุณสามารถทำได้:

UIButton* button = [buttons objectAtIndex:[indexPath row] ] ;
[cell.contentView addSubview:button];

จากนั้นในbuttonPressedAction:ฟังก์ชั่นคุณสามารถทำได้

- (void)buttonPressedAction:(id)sender {
   UIButton* button = (UIButton*)sender ;
   int row = [buttons indexOfObject:button] ;
   // Do magic
}

2

เป็นส่วนที่จัดการ - ฉันเก็บ NSIndexPath ไว้ใน UITableViewCell ที่กำหนดเอง

ใน CLKIndexPricesHEADERTableViewCell.xib

ใน IB เพิ่ม UIButton ลงใน XIB - อย่าเพิ่มการกระทำ!

เพิ่มร้านค้า @ คุณสมบัติ (เก็บ, ไม่ใช่เชิงอะตอม) IBOutlet UIButton * buttonIndexSectionClose;

อย่า CTRL + ลากการกระทำใน IB (ทำในรหัสด้านล่าง)

@interface CLKIndexPricesHEADERTableViewCell : UITableViewCell
...
@property (retain, nonatomic) IBOutlet UIButton *buttonIndexSectionClose;
@property (nonatomic, retain) NSIndexPath * indexPathForCell;
@end

ใน viewForHeaderInSection (ควรทำงานกับ cellForRow ... ฯลฯ หากตารางมีเพียง 1 ส่วน)

- viewForHeaderInSection is called for each section 1...2...3
- get the cell CLKIndexPricesHEADERTableViewCell 
- getTableRowHEADER just does the normal dequeueReusableCellWithIdentifier
- STORE the indexPath IN the UITableView cell
- indexPath.section = (NSInteger)section
- indexPath.row = 0 always (we are only interested in sections)

- (UIView *) tableView:(UITableView *)tableView1 viewForHeaderInSection:(NSInteger)section {


    //Standard method for getting a UITableViewCell
    CLKIndexPricesHEADERTableViewCell * cellHEADER = [self getTableRowHEADER];

... ใช้ส่วนนี้เพื่อรับข้อมูลสำหรับเซลล์ของคุณ

... กรอกข้อมูล

   indexName        = ffaIndex.routeCode;
   indexPrice       = ffaIndex.indexValue;

   //

   [cellHEADER.buttonIndexSectionClose addTarget:self
                                          action:@selector(buttonDELETEINDEXPressedAction:forEvent:)
                                forControlEvents:UIControlEventTouchUpInside];


   cellHEADER.indexPathForCell = [NSIndexPath indexPathForRow:0 inSection:section];


    return cellHEADER;
}

USER กดปุ่ม DELETE ที่ส่วนหัวของส่วนและการโทรนี้

- (void)buttonDELETEINDEXPressedAction:(id)sender forEvent:(UIEvent *)event
{
    NSLog(@"%s", __PRETTY_FUNCTION__);


    UIView *  parent1 = [sender superview];   // UiTableViewCellContentView
    //UIView *myContentView = (UIView *)parent1;

    UIView *  parent2 = [parent1 superview];  // custom cell containing the content view
    //UIView *  parent3 = [parent2 superview];  // UITableView containing the cell
    //UIView *  parent4 = [parent3 superview];  // UIView containing the table


    if([parent2 isMemberOfClass:[CLKIndexPricesHEADERTableViewCell class]]){
        CLKIndexPricesHEADERTableViewCell *myTableCell = (CLKIndexPricesHEADERTableViewCell *)parent2;

        //UITableView *myTable = (UITableView *)parent3;
        //UIView *mainView = (UIView *)parent4;

        NSLog(@"%s indexPath.section,row[%d,%d]", __PRETTY_FUNCTION__, myTableCell.indexPathForCell.section,myTableCell.indexPathForCell.row);

        NSString *key = [self.sortedKeysArray objectAtIndex:myTableCell.indexPathForCell.section];
        if(key){
            NSLog(@"%s DELETE object at key:%@", __PRETTY_FUNCTION__,key);
            self.keyForSectionIndexToDelete = key;
            self.sectionIndexToDelete = myTableCell.indexPathForCell.section;

            UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Remove Index"
                                                                message:@"Are you sure"
                                                               delegate:self
                                                      cancelButtonTitle:@"No"
                                                      otherButtonTitles:@"Yes", nil];
            alertView.tag = kALERTVIEW_REMOVE_ONE_INDEX;
            [alertView show];
            [alertView release];
            //------
        }else{
            NSLog(@"ERROR: [%s] key is nil for section:%d", __PRETTY_FUNCTION__,myTableCell.indexPathForCell.section);
        }

    }else{
        NSLog(@"ERROR: [%s] CLKIndexPricesHEADERTableViewCell not found", __PRETTY_FUNCTION__);
    }
}

ในตัวอย่างนี้ฉันเพิ่มปุ่มลบดังนั้นควรแสดง UIAlertView เพื่อยืนยัน

ฉันจัดเก็บส่วนและคีย์ลงในพจนานุกรมการจัดเก็บข้อมูลเกี่ยวกับส่วนใน ivar ใน VC

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
   if(alertView.tag == kALERTVIEW_REMOVE_ONE_INDEX){
        if(buttonIndex==0){
            //NO
            NSLog(@"[%s] BUTTON:%d", __PRETTY_FUNCTION__,buttonIndex);
            //do nothing
        }
        else if(buttonIndex==1){
            //YES
            NSLog(@"[%s] BUTTON:%d", __PRETTY_FUNCTION__,buttonIndex);
            if(self.keyForSectionIndexToDelete != nil){

                //Remove the section by key
                [self.indexPricesDictionary removeObjectForKey:self.keyForSectionIndexToDelete];

                //sort the keys so sections appear alphabetically/numbericsearch (minus the one we just removed)
                [self updateTheSortedKeysArray];                

                //Delete the section from the table using animation
                [self.tableView beginUpdates];

                [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:self.sectionIndexToDelete]
                              withRowAnimation:UITableViewRowAnimationAutomatic];
                [self.tableView endUpdates];

                //required to trigger refresh of myTableCell.indexPathForCell else old values in UITableViewCells
                [self.tableView reloadData];
            }else{
                NSLog(@"ERROR: [%s] OBJECT is nil", __PRETTY_FUNCTION__);
            }
        }
        else {
            NSLog(@"ERROR: [%s] UNHANDLED BUTTON:%d", __PRETTY_FUNCTION__,buttonIndex);
        }
    }else {
        NSLog(@"ERROR: [%s] unhandled ALERTVIEW TAG:%d", __PRETTY_FUNCTION__,alertView.tag);
    }
}

2
A better way would be to subclass your button and add a indexPath property to it.

//Implement a subclass for UIButton.

@interface NewButton:UIButton
@property(nonatomic, strong) NSIndexPath *indexPath;


Make your button of type NewButton in the XIB or in the code whereever you are initializing them.

Then in the cellForRowAtIndexPath put the following line of code.

button.indexPath = indexPath;

return cell; //As usual



Now in your IBAction

-(IBAction)buttonClicked:(id)sender{
   NewButton *button = (NewButton *)sender;

//Now access the indexPath by buttons property..

   NSIndexPath *indexPath = button.indexPath; //:)
}

สิ่งนี้เป็นข้อผิดพลาดเล็กน้อยเนื่องจาก indexPath ของเซลล์สามารถเปลี่ยนแปลงได้หากคุณเรียก deleteRowsAtIndexPaths
John Gibb

deleteRowsAtIndexPaths จะทำให้ cellForRowAtIndexPath เรียกใช้อีกครั้ง จากนั้นปุ่มจะมี indexPaths ใหม่ที่ถูกต้อง
mmmanishs

1

มันใช้งานได้สำหรับฉันเช่นกันขอบคุณ @Cocoanut

ฉันพบวิธีการใช้ superview ของ superview เพื่อรับการอ้างอิงไปยัง indexPath ของเซลล์ทำงานได้อย่างสมบูรณ์ ขอบคุณ iphonedevbook.com (macnsmith) สำหรับข้อความลิงค์เคล็ดลับ

-(void)buttonPressed:(id)sender {
 UITableViewCell *clickedCell = (UITableViewCell *)[[sender superview] superview];
 NSIndexPath *clickedButtonPath = [self.tableView indexPathForCell:clickedCell];
...

}

0

คุณสามารถใช้รูปแบบแท็ก:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
     NSString *identifier = @"identifier";
     UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
     if (cell == nil) {
         cell = [[UITableView alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
         [cell autorelelase];

         UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(10, 5, 40, 20)];
         [button addTarget:self action:@selector(buttonPressedAction:) forControlEvents:UIControlEventTouchUpInside];
         [button setTag:[indexPath row]]; //use the row as the current tag
         [cell.contentView addSubview:button];

         [button release];
     }

     UIButton *button = (UIButton *)[cell viewWithTag:[indexPath row]]; //use [indexPath row]
     [button setTitle:@"Edit" forState:UIControlStateNormal];

     return cell;
}

- (void)buttonPressedAction:(id)sender
{
    UIButton *button = (UIButton *)sender;
    //button.tag has the row number (you can convert it to indexPath)
}

ฉันจะติดแท็กตัวควบคุมได้อย่างไรถ้าฉันมีตัวควบคุมหลายตัวในเซลล์เดียว
rein

ฉันไม่แน่ใจว่าสิ่งนี้จะได้ผล - หากเซลล์ถูกสร้างขึ้นสำหรับแถว # 1 มันจะได้รับแท็ก 1 หากถูกตัดออกจากแถว # 3 แล้วมันจะยังคงมีแท็ก 1 ไม่ใช่ 3
rein

เดาว่าคุณพูดถูกเกี่ยวกับความคิดเห็นที่สอง ความผิดฉันเอง. ผมคิดว่าทางออกที่ดีที่สุดของคุณคือการ subclass UIButton เพิ่มทรัพย์สินของผู้อื่นหรือสองของคุณเองและจากนั้นตั้งค่า / รับพวกเขาในกรณีที่เหมาะสม (ติดกับแท็ก: 1 ที่คุณมีในรหัสของคุณ)
Nir ประกาศ

0

ฉันพลาดอะไรไปรึเปล่า? คุณไม่สามารถใช้ผู้ส่งเพื่อระบุปุ่มได้ ผู้ส่งจะให้ข้อมูลเช่นนี้กับคุณ:

<UIButton: 0x4b95c10; frame = (246 26; 30 30); opaque = NO; tag = 104; layer = <CALayer: 0x4b95be0>>

จากนั้นถ้าคุณต้องการเปลี่ยนคุณสมบัติของปุ่มให้พูดภาพพื้นหลังที่คุณบอกผู้ส่ง:

[sender setBackgroundImage:[UIImage imageNamed:@"new-image.png"] forState:UIControlStateNormal];

หากคุณต้องการแท็กวิธีการของ ACBurk ก็ใช้ได้


1
พวกเขากำลังมองหา "วัตถุ" ที่ปุ่มนั้นเกี่ยวข้องกับ
ohhorob

0
// how do I know which button sent this message?
// processing button press for this row requires an indexPath.

ตรงไปตรงมาสวยจริง ๆ :

- (void)buttonPressedAction:(id)sender
{
    UIButton *button = (UIButton *)sender;
    CGPoint rowButtonCenterInTableView = [[rowButton superview] convertPoint:rowButton.center toView:self.tableView];
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:rowButtonCenterInTableView];
    MyTableViewItem *rowItem = [self.itemsArray objectAtIndex:indexPath.row];
    // Now you're good to go.. do what the intention of the button is, but with
    // the context of the "row item" that the button belongs to
    [self performFooWithItem:rowItem];
}

ทำงานได้ดีสำหรับฉัน: P

หากคุณต้องการปรับการตั้งค่าการกระทำที่เป็นเป้าหมายคุณสามารถรวมพารามิเตอร์เหตุการณ์ในวิธีการแล้วใช้สัมผัสของเหตุการณ์นั้นเพื่อแก้ไขพิกัดของการสัมผัส พิกัดยังต้องได้รับการแก้ไขในขอบเขตมุมมองแบบสัมผัส แต่บางคนอาจดูง่ายขึ้น


0

สร้างอาร์เรย์ที่ไม่น่าเชื่อถือและวางปุ่มทั้งหมดในอาร์เรย์นั้นโดยใช้ [อาร์เรย์ addObject: yourButton];

ในวิธีการกดปุ่ม

-

 (void)buttonPressedAction:(id)sender
{
    UIButton *button = (UIButton *)sender;

for(int i=0;i<[yourArray count];i++){

if([buton isEqual:[yourArray objectAtIndex:i]]){

//here write wat u need to do

}
}

0

ความแตกต่างเล็กน้อยในคำตอบของ Cocoanuts (ที่ช่วยฉันแก้ปัญหานี้) เมื่อปุ่มอยู่ในส่วนท้ายของตาราง (ซึ่งป้องกันไม่ให้คุณค้นหา 'เซลล์ที่ถูกคลิก':

-(IBAction) buttonAction:(id)sender;
{
    id parent1 = [sender superview];   // UiTableViewCellContentView
    id parent2 = [parent1 superview];  // custom cell containing the content view
    id parent3 = [parent2 superview];  // UITableView containing the cell
    id parent4 = [parent3 superview];  // UIView containing the table

    UIView *myContentView = (UIView *)parent1;
    UITableViewCell *myTableCell = (UITableViewCell *)parent2;
    UITableView *myTable = (UITableView *)parent3;
    UIView *mainView = (UIView *)parent4;

    CGRect footerViewRect = myTableCell.frame;
    CGRect rect3 = [myTable convertRect:footerViewRect toView:mainView];    

    [cc doSomethingOnScreenAtY:rect3.origin.y];
}

0

ฉันมักจะใช้แท็ก

คุณต้อง subclass UITableviewCellและจัดการกดปุ่มจากที่นั่น


ฉันไม่เข้าใจวิธีการ คุณสมบัติแท็กถูกตั้งค่าระหว่างการสร้างเซลล์ - เซลล์นี้สามารถใช้ซ้ำได้สำหรับแต่ละแถวด้วยตัวระบุเดียวกัน แท็กนี้เฉพาะกับตัวควบคุมในเซลล์ที่ใช้ซ้ำได้ทั่วไป ฉันจะใช้แท็กนี้เพื่อแยกความแตกต่างปุ่มในเซลล์ที่สร้างขึ้นในลักษณะทั่วไปได้อย่างไร คุณช่วยโพสต์โค้ดได้ไหม
rein

0

มันง่ายมาก สร้างเซลล์ที่กำหนดเองและเอาปุ่มออก

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
         NSString *identifier = @"identifier";
        customCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];

    cell.yourButton.tag = indexPath.Row;

- (void)buttonPressedAction:(id)sender

เปลี่ยน id ในวิธีการด้านบนเป็น (UIButton *)

คุณสามารถรับค่าที่ปุ่มใดถูกแตะโดย sender.tag


0

ซับคลาสปุ่มเพื่อจัดเก็บค่าที่ต้องการอาจสร้างโปรโตคอล (ControlWithData หรือบางอย่าง) ตั้งค่าเมื่อคุณเพิ่มปุ่มลงในเซลล์มุมมองตาราง ในกิจกรรมการแตะของคุณดูว่าผู้ส่งปฏิบัติตามโปรโตคอลและแยกข้อมูลหรือไม่ โดยปกติฉันจะเก็บการอ้างอิงไปยังวัตถุจริงที่แสดงผลในเซลล์มุมมองตาราง


0

SWIFT 2 UPDATE

ต่อไปนี้เป็นวิธีการค้นหาว่าปุ่มใดถูกกด + ส่งข้อมูลไปยัง ViewController อื่นจากปุ่มนั้นindexPath.rowในขณะที่ฉันสมมติว่าเป็นจุดสำคัญที่สุด!

@IBAction func yourButton(sender: AnyObject) {


     var position: CGPoint = sender.convertPoint(CGPointZero, toView: self.tableView)
        let indexPath = self.tableView.indexPathForRowAtPoint(position)
        let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath!)! as
        UITableViewCell
        print(indexPath?.row)
        print("Tap tap tap tap")

    }

สำหรับผู้ที่ใช้คลาส ViewController และเพิ่ม tableView ฉันใช้ ViewController แทน TableViewController ดังนั้นฉันจึงเพิ่ม tableView ด้วยตนเองเพื่อเข้าถึง

นี่คือรหัสสำหรับการส่งข้อมูลไปยัง VC อื่นเมื่อแตะปุ่มนั้นและส่งผ่านของเซลล์ indexPath.row

@IBAction func moreInfo(sender: AnyObject) {

    let yourOtherVC = self.storyboard!.instantiateViewControllerWithIdentifier("yourOtherVC") as! YourOtherVCVIewController



    var position: CGPoint = sender.convertPoint(CGPointZero, toView: self.tableView)
    let indexPath = self.tableView.indexPathForRowAtPoint(position)
    let cell: UITableViewCell = tableView.cellForRowAtIndexPath(indexPath!)! as
    UITableViewCell
    print(indexPath?.row)
    print("Button tapped")


    yourOtherVC.yourVarName = [self.otherVCVariable[indexPath!.row]]

    self.presentViewController(yourNewVC, animated: true, completion: nil)

}

0

หมายเหตุที่นี่ฉันใช้เซลล์ที่กำหนดเองรหัสนี้ทำงานอย่างสมบูรณ์สำหรับฉัน

 @IBAction func call(sender: UIButton)
    {
        var contentView = sender.superview;
        var cell = contentView?.superview as EmployeeListCustomCell
        if (!(cell.isKindOfClass(EmployeeListCustomCell)))
        {
            cell = (contentView?.superview)?.superview as EmployeeListCustomCell
        }

        let phone = cell.lblDescriptionText.text!
        //let phone = detailObject!.mobile!
        let url:NSURL = NSURL(string:"tel://"+phone)!;
        UIApplication.sharedApplication().openURL(url);
    }

0

วิธีแก้ปัญหาของ Chris Schwerdt แต่ใน Swift ได้ผลสำหรับฉัน:

@IBAction func rateButtonTapped(sender: UIButton) {
    let buttonPosition : CGPoint = sender.convertPoint(CGPointZero, toView: self.ratingTableView)
    let indexPath : NSIndexPath = self.ratingTableView.indexPathForRowAtPoint(buttonPosition)!

    print(sender.tag)
    print(indexPath.row)
}

0

ปัญหานี้มีสองส่วน:

1) การหาพา ธ ดัชนีUITableViewCellซึ่งมีการกดUIButton

มีข้อเสนอแนะบางอย่างเช่น:

  • อัปเดตUIButton's tagในcellForRowAtIndexPath:วิธีการโดยใช้เส้นทางดัชนีrowค่า นี่ไม่ใช่วิธีแก้ปัญหาที่ดีเนื่องจากต้องมีการอัปเดตtagอย่างต่อเนื่องและไม่ทำงานกับมุมมองตารางที่มีมากกว่าหนึ่งส่วน

  • การเพิ่มNSIndexPathสถานที่ให้บริการไปยังเซลล์ที่กำหนดเองและปรับปรุงมันแทนUIButton's tagในcellForRowAtIndexPath:วิธีการ วิธีนี้ช่วยแก้ปัญหาหลายส่วนได้ แต่ยังไม่ดีเท่าที่จำเป็นต้องทำการอัพเดทอยู่เสมอ

  • การรักษาความอ่อนแออย่างอ่อนช้อยให้กับผู้ปกครองUITableViewในเซลล์ที่กำหนดเองในขณะที่สร้างมันและใช้indexPathForCell:วิธีการรับเส้นทางดัชนี ดูเหมือนดีขึ้นเล็กน้อยไม่จำเป็นต้องอัปเดตสิ่งใดในcellForRowAtIndexPath:วิธีการ แต่ยังคงต้องการการตั้งค่าการอ้างอิงที่อ่อนแอเมื่อสร้างเซลล์ที่กำหนดเอง

  • การใช้มือถือของสถานที่ให้บริการที่จะได้รับการอ้างอิงไปยังผู้ปกครองsuperView UITableViewไม่จำเป็นต้องเพิ่มคุณสมบัติใด ๆ ไปยังเซลล์ที่กำหนดเองและไม่จำเป็นต้องตั้งค่า / ปรับปรุงอะไรในการสร้าง / ภายหลัง แต่เซลล์superViewขึ้นอยู่กับรายละเอียดการใช้ iOS ดังนั้นจึงไม่สามารถใช้งานได้โดยตรง

แต่สามารถทำได้โดยใช้ลูปแบบง่ายเนื่องจากเรามั่นใจว่าเซลล์ที่เป็นปัญหาจะต้องอยู่ใน UITableView:

UIView* view = self;
while (view && ![view isKindOfClass:UITableView.class])
    view = view.superview;
UITableView* parentTableView = (UITableView*)view;

ดังนั้นคำแนะนำเหล่านี้สามารถรวมกันเป็นวิธีกำหนดเซลล์ที่ง่ายและปลอดภัยสำหรับการรับเส้นทางดัชนี:

- (NSIndexPath *)indexPath
{
    UIView* view = self;

    while (view && ![view isKindOfClass:UITableView.class])
        view = view.superview;

    return [(UITableView*)view indexPathForCell:self];
}

จากนี้ไปวิธีการนี้สามารถใช้ในการตรวจสอบที่ UIButtonกด

2) แจ้งฝ่ายอื่น ๆ เกี่ยวกับเหตุการณ์การกดปุ่ม

หลังจากทราบว่าUIButtonมีการกดปุ่มใดในเซลล์ที่กำหนดเองที่มีพา ธ ดัชนีที่แน่นอนข้อมูลนี้จะต้องถูกส่งไปยังฝ่ายอื่น ๆ (ส่วนใหญ่อาจเป็นตัวควบคุมมุมมองที่จัดการUITableView) ดังนั้นเหตุการณ์คลิกปุ่มนี้สามารถจัดการได้ในระดับนามธรรมและระดับตรรกะที่คล้ายกันdidSelectRowAtIndexPath:วิธีการของ UITableView

สามารถใช้สองวิธีนี้:

a) การมอบหมาย:เซลล์ที่กำหนดเองสามารถมีdelegateคุณสมบัติและสามารถกำหนดโปรโตคอล เมื่อกดปุ่มเพียงดำเนินการมันเป็นวิธีการมอบหมายในdelegateคุณสมบัติของมัน แต่delegateจะต้องตั้งค่าคุณสมบัตินี้สำหรับแต่ละเซลล์ที่กำหนดเองเมื่อสร้างขึ้น อีกทางเลือกหนึ่งเซลล์ที่กำหนดเองสามารถเลือกที่จะดำเนินการวิธีการมอบหมายในมุมมองของตารางหลักdelegateเกินไป

b) ศูนย์การแจ้งเตือน:เซลล์ที่กำหนดเองสามารถกำหนดชื่อการแจ้งเตือนที่กำหนดเองและโพสต์การแจ้งเตือนนี้กับเส้นทางดัชนีและข้อมูลมุมมองตารางหลักที่ให้ไว้ในuserInfoวัตถุ ไม่จำเป็นต้องตั้งค่าอะไรสำหรับแต่ละเซลล์เพียงเพิ่มผู้สังเกตการณ์สำหรับการแจ้งเตือนของเซลล์ที่กำหนดเองก็เพียงพอแล้ว


0

ฉันใช้โซลูชันที่ subclass UIButtonและฉันคิดว่าฉันควรแบ่งปันที่นี่รหัสใน Swift:

class ButtonWithIndexPath : UIButton {
    var indexPath:IndexPath?
}

จากนั้นอย่าลืมอัปเดตมันคือ indexPath ค่ะ cellForRow(at:)

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let returnCell = tableView.dequeueReusableCell(withIdentifier: "cellWithButton", for: indexPath) as! cellWithButton
    ...
    returnCell.button.indexPath = IndexPath
    returnCell.button.addTarget(self, action:#selector(cellButtonPressed(_:)), for: .touchUpInside)

    return returnCell
}

ดังนั้นเมื่อตอบสนองต่อเหตุการณ์ของปุ่มคุณสามารถใช้มันได้

func cellButtonPressed(_ sender:UIButton) {
    if sender is ButtonWithIndexPath {
        let button = sender as! ButtonWithIndexPath
        print(button.indexPath)
    }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.