2009-06-22 27 views
19

Tôi hiện có UITableView được điền bằng UITableViewCell tùy chỉnh nằm trong một ngòi bút riêng biệt. Trong ô, có hai nút được kết nối với các hành động trong lớp ô tùy chỉnh. Khi tôi nhấp vào một trong các nút, tôi có thể gọi phương thức thích hợp, nhưng tôi cần phải biết hàng nào đã được nhấn. Thuộc tính thẻ cho mỗi nút sẽ đến bằng 0. Tôi không cần biết khi nào toàn bộ ô được chọn, chỉ khi một nút cụ thể được nhấn, vì vậy tôi cần biết hàng nào là vì vậy tôi có thể cập nhật đối tượng thích hợp.iPhone - Cách xác định một ô được nhấn trong một UITableViewCell tùy chỉnh

Trả lời

10

Bạn có thể sử dụng thuộc tính tag trên nút để chỉ định hàng nào được tạo trong đó, nếu bạn không sử dụng thẻ cho bất kỳ thứ gì khác.

+1

Tôi có cần đặt thẻ trong phương thức cellForRowAtIndexPath không, sau đó truy cập thẻ khi nhấn nút? –

+1

Vâng, đó là phương pháp tốt nhất. – Jason

+0

Đã tìm kiếm điều này trong một thời gian dài, như tôi là một newbie là tốt. Cảm ơn @ pix0r vì đã tư vấn tốt. – Jonauz

1

Bạn có thể truy cập các nút superview để nhận được UITableViewCell có chứa nút của bạn, nhưng nếu bạn chỉ cần số hàng, bạn có thể sử dụng thuộc tính tag như đăng bài trước.

+0

Sử dụng [người giám sát người gửi]; trong lớp tế bào tùy chỉnh (có chứa các phương pháp hành động cho các nút) cho tôi một UIView, không phải là ô. Nếu tôi đặt thẻ trong phương thức cellForRowAtIndexPath, nó vẫn chỉ là 0 cho mỗi nút trong ô khi được nhấn. –

+0

Đúng vậy, bạn cần sử dụng [[superviewiew] superview] như được mô tả bởi một bài viết khác… đây là ô, chứa UIView, chứa nút của bạn. – h4xxr

+0

Đây là một giải pháp tốt: http: //www.71squared.com/2008/12/custom-button-in-uitableviewcell-indexpath/ – DixieFlatline

4

Tôi có cùng một trường hợp. Để đạt được điều này, tôi bắt nguồn từ một ô tùy chỉnh. Tôi đã thêm hai thuộc tính, phần và hàng. Tôi cũng đã thêm một chủ sở hữu, đó sẽ là lớp TableViewController có nguồn gốc của tôi. Khi các ô được yêu cầu, tôi đặt phần/hàng dựa trên indexPath, cùng với chủ sở hữu.

cell.section = indexPath.section cell.row = indexPath.row cell.owner = tự

Điều tiếp theo mà tôi đã làm được khi tôi tạo ra các nút, tôi kết hợp các sự kiện nút với các tế bào thay vì với tableViewController. Trình xử lý sự kiện có thể đọc mục nhập và phần và gửi thông điệp (hoặc sự kiện) thích hợp tới TableViewController. Điều này giúp đơn giản hoá việc giữ gìn và bảo trì nhà bằng cách tận dụng các phương pháp và vệ sinh hiện có và giữ cho ô luôn tự chủ càng tốt. Kể từ khi hệ thống theo dõi các tế bào đã có, tại sao làm điều đó hai lần!

19

Giải pháp dễ dàng hơn nhiều là xác định lời gọi lại nút của bạn với người gửi (id) và sử dụng để tìm ra chỉ mục hàng trong bảng. Dưới đây là một số mã mẫu:

- (IBAction)buttonWasPressed:(id)sender 
{ 
    NSIndexPath *indexPath = 
     [self.myTableView 
     indexPathForCell:(UITableViewCell *)[[sender superview] superview]]; 
    NSUInteger row = indexPath.row; 

    // Do something with row index 
} 

Rất có thể bạn đã sử dụng cùng một chỉ mục hàng để tạo/lấp đầy ô, vì vậy sẽ không quan trọng để xác định nút của bạn sẽ làm gì bây giờ. Không cần phải chơi với các thẻ và cố gắng giữ chúng theo thứ tự!

Làm rõ: nếu bạn hiện đang sử dụng - (Nút IBAction)WasPressed; chỉ cần xác định lại nó là - (nút IBAction)WasPressed: (id) người gửi; Các đối số gọi lại bổ sung là có, không cần phải làm bất cứ điều gì thêm để có được nó. Ngoài ra, hãy nhớ kết nối lại nút của bạn với cuộc gọi lại mới trong Trình tạo giao diện!

+0

Tất nhiên bạn sử dụng lại các ô, nếu trường hợp sử dụng cho phép điều đó! Nếu không, mọi thứ có thể trở nên thực sự phức tạp. Dù sao, hàng đầu tiên được thêm vào tableView S be là "hàng đầu tiên". Xin lỗi, tôi thấy không có vấn đề gì với điều đó? – JOM

+0

Làm rõ cho nhận xét "tế bào tái sử dụng" cô đơn của tôi. Đó là câu trả lời cho một nhận xét khác, hiện đã bị ai đó xóa. Tôi cũng đã bỏ phiếu cho điều đó! Đừng lo, tôi sẽ sống sót :) – JOM

+0

Tôi chỉ nắm lấy nội dung của hành động này để xử lý tìm ra nút nào trong đó ô UITableView được gọi cho một Segue. Kỹ thuật này thật tuyệt vời! – jerwood

3

Thậm chí dễ dàng hơn:

-(IBAction) buttonPressed { 
    NSIndexPath *myIndexPath = [(UITableView *)self.superview indexPathForCell: self]; 
    // do whatever you need to do with the information 
} 
1

Có nhiều phương pháp để khắc phục vấn đề.

  1. Bạn có thể sử dụng thuộc tính "thẻ" Cung cấp giá trị indexPath.row làm giá trị thẻ cho nút.
    btn.tag = indexPath.hàng;

Sau đó, trong chức năng nút, bạn có thể dễ dàng truy cập vào giá trị thẻ và nó sẽ là chỉ mục cho nút được nhấp.

-(void)btnClicked:(id)sender 
{ 
    int index = [sender tag]; 
} 
  1. Bạn có thể sử dụng thuộc tính lớp Thêm indexPath như giá trị trong từ điển lớp.

    [[btn layer] setValue: indexPath forKey: @ "indexPath"];

Chỉ mục này có thể truy cập được từ chức năng thao tác nút.

-(void)btnClicked:(id)sender 
{ 
    NSIndexPath *indexPath = [[sender layer] valueForKey:@"indexPath"]; 
    int index = indexPath.row; 
} 

Với phương pháp này, bạn có thể chuyển nhiều giá trị vào chức năng nút bằng cách thêm các đối tượng mới vào từ điển với các phím khác nhau.

+0

Thật là một hack khủng khiếp. Lớp không có ở đó để lưu trữ dữ liệu tùy ý. – jrturton

+1

Xem http://stackoverflow.com/questions/9274494/how-to-know-the-uitableview-row-number/9274863#9274863 để có giải pháp tốt hơn nhiều. – jrturton

+0

@tinku George - câu trả lời đầu tiên của bạn đã hoạt động trong trường hợp của tôi !. Cảm ơn! –

4

Đối với việc thực hiện đó không phải là phụ thuộc vào thẻ hoặc hệ thống phân cấp xem làm như sau

- (void)btnPressed:(id)sender event:(id)event 
{ 
    UITouch *touch = [[event allTouches] anyObject]; 
    CGPoint touchPoint = [touch locationInView:self.tableView]; 
    NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:touchPoint]; 
} 
0
[btnFavroite setAccessibilityValue:[NSString stringWithFormat:@"%d",indexPath.row]]; 
    [btnFavroite setAccessibilityLabel:btnFavroite.titleLabel.text]; 
    [btnFavroite addTarget:self action:@selector(btnFavClick:) forControlEvents:UIControlEventTouchUpInside]; 

-(void)btnFavClick:(id)sender{ 
    UIButton *btn=(UIButton *)sender; 
    int index=[btn.accessibilityValue integerValue]] 
} 
0

giải pháp này cũng làm việc trong IBAction kết nối sử dụng nguyên mẫu tế bào storyboard

- (IBAction)viewMapPostsMarker:(UIButton*)sender{ 
    // button > cellContentView > cellScrollView > cell 
    UITableViewCell *cell = (UITableViewCell *) sender.superview.superview.superview; 
    NSIndexPath *index = [self.mapPostsView indexPathForCell:cell]; 
    NSLog(@" cell at index %d",index.row); 
} 
3

Dưới đây là một Ví dụ về Swift ...

Lớp UIControl là lớp cha của nhiều widge iOS khác nhau ts, bao gồm UIButton, vì UIControl cung cấp cơ chế đích/hành động gửi thông báo sự kiện. Do đó, cách chung để xử lý vấn đề này như sau:

func actionHandler(control: UIControl) 
    var indexPath = tableView.indexPathForCell(control.superview!.superview! as UITableViewCell)! 
    var row = indexPath.row 
} 

Đây là ví dụ về thiết lập điều khiển nút để thực hiện tác vụ. Ngoài ra, hãy tạo một @IBAction và tạo hành động trực quan bằng Trình tạo giao diện.

button.addTarget(self, action: "actionHandler:", forControlEvents: .TouchUpInside) 

Bạn có thể truyền tham số UIControl xuống UIButton, UIStepper, v.v ... nếu cần. Ví dụ:

var button = control as UIButton 

Các SuperView tầm kiểm soát là của UITableViewCell contentView, mà subviews là UIViews hiển thị trong ô (UIControl là một lớp con của UIView). Giám sát của ô nội dung là chính UITableViewCell. Đó là lý do tại sao đây là một cơ chế đáng tin cậy và những người giám sát có thể bị vượt qua sự bất công.

+0

Cảm ơn câu trả lời tuyệt vời! Nó hoạt động với nút nhiều trong 'UITableView' trong cùng một hàng! –

Các vấn đề liên quan