-didSelectRowAtIndexPath: không được gọi


295

Tôi đang viết một ứng dụng iOS với chế độ xem bảng bên trong chế độ xem tab. Theo tôi UITableViewController, tôi đã triển khai -tableView:didSelectRowAtIndexPath:, nhưng khi tôi chọn một hàng trong thời gian chạy, phương thức không được gọi. Chế độ xem bảng đang được phổ biến, vì vậy tôi biết rằng các phương thức xem bảng khác trong bộ điều khiển của tôi đang được gọi.

Có ai có bất cứ ý tưởng nào về những gì tôi có thể làm hỏng để thực hiện điều này không?


79
ngoài ra, bạn có thể có một cử chỉ nhận dạng trên đầu UITableView để hấp thụ lựa chọn .. (một trong những khả năng)
M.Othman

Hãy cẩn thận nếu chế độ xem bảng đang được điền, điều đó có nghĩa là DataSource được thiết lập tốt. Việc lựa chọn là một phần của các phương thức Delegate. Vì vậy, có thể DataSource được thiết lập tốt nhưng không phải là Đại biểu!
Thomas Besnehard

1
Xin chào M.Othman, nhận xét của bạn chính xác là những gì sai với vấn đề của riêng tôi. Bạn có biết làm thế nào để cử chỉ nhận dạng hoạt động 'với' UITableViewkhông?
yhl

15
Tôi nhận thấy rằng nếu tôi chạm và giữ, vòi cuối cùng sẽ gọi -didSelectRowAtIndexPath. Tôi đã tìm ra chiếc mũ bởi vì tôi có một bộ nhận dạng cử chỉ gõ trên bàn xem và cử chỉ phải thất bại trước khi nhận được liên lạc. Mặc dù thật kỳ lạ, hoạt hình lựa chọn bảng không bị ảnh hưởng bởi trình nhận dạng cử chỉ.
Hlung

6
Tôi đã có cùng một vấn đề ở đây và đã có cơ hội may mắn khi biết rằng bạn không thể có một cử chỉ nhận dạng trên đầu trang của UITableView. Cảm ơn M. Othman!
vnchopra

Câu trả lời:


97

Có vẻ như lớp học không phải là UITableViewDelegatecho chế độ xem bảng đó, mặc dù UITableViewControllerđược cho là tự động đặt nó.

Bất kỳ cơ hội nào bạn đặt lại đại biểu cho một số lớp khác?


7
Tôi phát hiện ra rằng trong khi bộ điều khiển của tôi là UITableViewContaptor, tôi đã sử dụng một tiện ích UIViewControll cũ đơn giản trong UI Builder. Điều đó không hiệu quả. Khi tôi xóa tiện ích UIViewControll và bỏ UITableViewControll vào vị trí của nó, mọi thứ đều hoạt động.
Matt Pfefferle

1
Một trường hợp ranh giới khác cho tất cả mọi người - Tôi đã kết nối mã đại biểu và quên rằng trước đó tôi đã kết nối đại biểu thông qua bảng phân cảnh .... lần cuối cùng để thiết lập chiến thắng.
Oliver Dungey

1
bạn có thể chỉ cho bạn cách "thiết lập lại một đại biểu cho một số lớp khác" không? Tôi có vấn đề tương tự và không thể giải quyết nó
Alfro 14/07/2016

1
myTableViewControll.tableView.delegate = xxx
Hunter

534

Chỉ trong trường hợp ai đó phạm sai lầm ngu ngốc như tôi đã làm:

Kiểm tra xem tên phương thức của những gì bạn mong đợi didSelectcó thể vô tình được nhận didDeselecttheo một cách nào đó. Mất khoảng hai giờ để tôi tìm hiểu ...


47
Vấn đề tương tự ở đây. Đó là vì XCode tự động hoàn thành việc bỏ chọn trước khi chọn.
dùng1021430

Tương tự, tôi đã đặt allowSelection = false, cũng như loại bỏ bất kỳ tô sáng lựa chọn nào, cũng ngăn ô không được nhấn!
djinne95

503

Một điều khác có thể dẫn đến vấn đề không phải là loại lựa chọn:

Loại lựa chọn UITableView

Nên Single Selectioncho lựa chọn bình thường, không nên No Selection.

Để làm điều này theo chương trình, hãy làm:

tableView.allowsSelection = YES

4
Tôi tiếp tục chạy vào đây vì tôi có các cảnh luôn ở chế độ chỉnh sửa và tôi quên không thay đổi mặc định từ "Không có lựa chọn nào trong khi chỉnh sửa".
xứng

3
Bạn có thể thêm dòng này trong phương thức -viewDidLoad của viewControlller NSParameterAssert (self.tableView.allowsSelection);
Nikolay Shubenkov

đối với những người đã quan sát bảngView.rx.itemSelected.subscribe đã không gọi lại, đây là sự cố và cách khắc phục ở trên
Dhilip

Rất hữu ích khi bạn tiếp quản một số cơ sở mã và nó có mã bằng các nút có thẻ và không didSelectRow, với lựa chọn này bị vô hiệu hóa trong bảng phân cảnh
Nitin Alabur

đây là hành vi mặc định của bảng xem?
Frostmourne

296

Một khả năng khác là UITapGestureRecognizer có thể đang ăn các sự kiện, như trường hợp ở đây: https://stackoverflow.com/a/9248827/214070

Tôi không nghi ngờ nguyên nhân này, bởi vì các ô của bảng vẫn sẽ làm nổi bật màu xanh như thể các vòi đang đi qua.


Đây là vấn đề của tôi! Cảm ơn bạn rất nhiều!! Ý tôi là nó rõ ràng đã hoạt động trước đó, nhưng nó đã ngừng hoạt động sau khi tôi triển khai UITapGestureRecognizer * tap = [[UITapGestureRecognizer alloc] initWithTarget: self action: @selector (notifyPal)]; [self.view addGestureRecognizer: tap];
coolcool1994

26
Tôi gặp vấn đề tương tự như bạn @ coolcool1994 vừa thực hiện [tap setCancelsTouchesInView: NO]; và giải quyết vấn đề.
nizx

Cảm ơn, nó giúp tôi. Trong trường hợp của tôi didSelectRowAtIndexPathkhông hoạt động chỉ sau khi xóa ô trong commitEditingStyle. Sau đó, tôi thực hiện UITapGestureRecognizertapAction:nhận được indexPathtừ sender.view( [self.tableView indexPathForCell:sender.view]) và gọi[self.tableView.delegate didSelectRowAtIndexPath:myIndexPath]
Alexmelyon

1
Đây cũng là vấn đề của tôi .. thêm mã để loại bỏ tapesture trong chế độ xem bảng và nó hoạt động giống như sự quyến rũ - (bảng UITableViewCell *) Xem: (UITableView *) bảngView cellForRowAtIndexPath: (NS IndexPath *) indexPath {UITapGesture ] trong đó]; cử chỉ.cancelsTouchesInView = NO; [self.tableView addGestureRecognizer: cử chỉ]; }
Udaya Sri

6
Cảm ơn @nizx, trong swift 4 tap.cancelsTouchesInView = false
Ariven Nadar

150

Tất cả các câu trả lời hay, nhưng còn một điều nữa cần chú ý ...

(Đặc biệt khi tạo UITableView theo chương trình)

Đảm bảo bảngView có thể đáp ứng lựa chọn bằng cách đặt [tableView setAllowsSelection:YES];hoặc xóa bất kỳ dòng nào đặt nó NO.


9
Tôi sẽ thêm setAllowsSelectionDuringEditing:vào danh sách (khi chế độ xem bảng ở chế độ chỉnh sửa)
alex-i

Cảm ơn bạn! Trong IB tôi đã phải thay đổi giá trị phần "Lựa chọn" thành Single Selection.
Sasho

90

Nếu vấn đề phát sinh với UITapGestureRecognizerbạn có thể khắc phục điều này:

  • trong Storyboard:

nhập mô tả hình ảnh ở đây

trong mã với Objective-C:

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(dismissKeyboard)]; 
[self.view addGestureRecognizer:tap];

[tap setCancelsTouchesInView:NO];

trong mã với Swift:

let tap = UITapGestureRecognizer(target: self, action:Selector("dismissKeyboard"))
view.addGestureRecognizer(tap)

tap.cancelsTouchesInView = false

67

Tôi đã gặp hai điều trong tình huống này.

  1. Bạn có thể đã quên thực hiện giao thức UITableViewDelegate hoặc không có lối ra ủy nhiệm giữa lớp và chế độ xem bảng của bạn.

  2. Bạn có thể có một UIView bên trong hàng của bạn là phản hồi đầu tiên và lấy đi các nhấp chuột của bạn. Nói một UIButton hoặc một cái gì đó tương tự.


5
Nó bắt đầu xảy ra trên iOS 7, vô hiệu hóa "Chế độ tương tác người dùng được bật" trong nội dung Xem đã sửa lỗi này.
Kof

1
@Kof đóng đinh nó. Tạo một UITableViewCell trong trình tạo giao diện của Xcode 5 sẽ tạo ra nó với tính năng tương tác người dùng được kích hoạt = CÓ. Xcode 5 tệ!
jsd

44

Tôi đã có cùng một vấn đề. Và thật khó để tìm thấy. Nhưng đâu đó trong mã của tôi là thế này:

- (NSIndexPath *)tableView:(UITableView *)tableView willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
    return nil;
}

Nó phải được return indexPath, người khác -tableView:didSelectRowAtIndexPath:không được gọi.


2
cho làm SelectRow Tại indexPath chữ ký đúng là: - (void) tableView: (UITableView *) tableView didSelectRowAtIndexPath: (NSIndexPath *) indexPath {
coolcool1994

Đối với tôi, nó sẽ không bắt đầu gọi bảngView: didSelectRowAtIndexPath cho đến khi tôi xóa hoàn toàn
willSelectRowAtIndexPath

38

Nếu bạn đã thêm một cử chỉ nhận dạng trên đầu UITableView, didSelectRowAtIndexPathsẽ không được gọi.

Vì vậy, bạn cần sử dụng phương thức ủy nhiệm cử chỉ cử chỉ để tránh chạm trong chế độ xem cụ thể.

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    if ([touch.view isDescendantOfView:YourTable]) {
        return NO;
    }
    return YES;
}

3
if ([touch.view isDescendantOfView:YourTable])
Sudheesh

29

Tôi đã gặp phải một vấn đề trong đó sau nhiều tháng không xem mã của mình, tôi quên rằng tôi đã thực hiện phương pháp sau do một số yêu cầu không cần thiết

- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath  *)indexPath{
    return NO;
}

Nó sẽ được trả về CÓ cho một hàng để làm cho nó được chọn.


24

BẠN PHẢI chọn các tùy chọn này

nhập mô tả hình ảnh ở đây

nhưng nếu bạn muốn làm UITableViewnổi bật khi nhấp vào thì bạn nên thay đổi UITableViewCellthuộc tính.

Chọn tùy chọn Không có cho Lựa chọn giống như bên dưới

nhập mô tả hình ảnh ở đây


20

Tôi đã đặt một cái nhìn UITapGestureRecognizertrên bàn để loại bỏ bàn phím ngăn không cho didSelectRowAtIndexPath:gọi. Hy vọng nó sẽ giúp được ai đó.



19

Tôi đã từng gặp vấn đề tương tự,

Lý do đã được sử dụng UITapGestureRecognizer. Tôi muốn bàn phím bị loại bỏ khi tôi gõ bất cứ nơi nào khác. Tôi nhận ra rằng điều này ghi đè tất cả các hành động nhấn, đó là lý do tại sao,didSelectRowAtIndexPath chức năng không được gọi.

Khi tôi nhận xét các hàng liên quan đến UITapGestureRecognizer, nó hoạt động. Ngoài ra, bạn có thể kiểm tra chức năng của UITapGestureRecognizer selectorviệc khai thác UITableViewCellhay không.


14

Trong trường hợp của tôi, didSelctRowAtIndexPath không gọi là do tôi đã chọn không có trong thuộc tính Lựa chọn của bảngView, được đặt thành một lựa chọn đã giải quyết vấn đề của tôi

nhập mô tả hình ảnh ở đây


11

Đối với Xcode 6.4, Swift 1.2. "Thẻ" lựa chọn đã được thay đổi trong IB. Tôi không biết làm thế nào và tại sao. Đặt nó thành "Lựa chọn đơn" làm cho các ô xem bảng của tôi có thể được chọn lại. nhập mô tả hình ảnh ở đây


10

Mặc dù câu trả lời khác đã được chấp nhận, tôi sẽ thêm một vấn đề và giải pháp khả thi hơn cho những người quan sát vấn đề này:

Nếu bạn đã bật tính năng tham chiếu tự động (ARC), bạn có thể thấy rằng ngay cả sau khi gán bộ điều khiển của mình làm đại biểu cho chế độ xem, thông báo của chế độ xem cho bộ điều khiển sẽ không được nhận vì ARC đang xóa bộ điều khiển. Rõ ràng con trỏ ủy nhiệm của UITableView không được tính là tham chiếu cho ARC, vì vậy nếu đó là tham chiếu duy nhất cho nó, bộ điều khiển sẽ được xử lý. Bạn có thể xác minh xem điều này có xảy ra hay không bằng cách triển khai phương thức dealloc trên bộ điều khiển và đặt điểm dừng hoặc lệnh NSLog ở đó.

Giải pháp là theo dõi bộ điều khiển với một tham chiếu mạnh mẽ ở một nơi khác, cho đến khi bạn chắc chắn rằng bạn sẽ không cần nó nữa.


Bộ điều khiển được thu gom rác trong khi chế độ xem của nó vẫn được hiển thị? Điều này thực sự có thể xảy ra?
Drux

@Drux Yep! Khi điều này xảy ra với tôi, nó gần như là phiên bản đầu tiên của Obj-C với bộ sưu tập rác được sử dụng trên iOS và thật lòng họ không làm tốt lắm. Rất nhiều tài liệu tham khảo rõ ràng hoặc ngầm "yếu" rằng, IMO, lẽ ra phải mạnh mẽ. Điều này dẫn đến sự kỳ quặc như bộ sưu tập rác của các đối tượng được sử dụng bởi lớp hiển thị. Tôi đã không hoàn thành công việc iOS trong một thời gian vì vậy tôi không biết điều này có xảy ra trên phiên bản mới nhất không.
Andrew Gorcester

Mã của tôi có vấn đề về kích thước bộ nhớ ngày càng tăng và tôi đã sửa một phần của nó và một nơi nào khác trong mã ngay sau khi didSelect này không được gọi lần đầu tiên. Tôi không biết điều này có biện minh cho vấn đề hay không.
Amber K

10

Hãy nhớ đặt nguồn dữ liệu và ủy quyền trong phương thức viewDidLoad như sau:

[self.tableView setDelegate:self];

[self.tableView setDataSource:self];

Tôi đã gọi nguồn dữ liệu nhưng không đại biểu ... cảm ơn!
Gmeister4

9

Vấn đề của tôi là không có ở trên. Và thật khập khiễng. Nhưng tôi nghĩ rằng tôi sẽ liệt kê nó ở đây trong trường hợp nó giúp được ai đó.

Tôi có một tableViewControllerbộ điều khiển "cơ sở" và sau đó tôi tạo các lớp con của bộ điều khiển này. Tôi đã viết tất cả mã của tôi trongtableView:didSelectRowAtIndexPath thói quen trong lớp "cơ sở". Hoàn toàn quên rằng theo mặc định, thói quen này cũng đã được tạo ra (mặc dù không có mã nào làm gì cả) trong tất cả các lớp con của tôi. Vì vậy, khi tôi chạy ứng dụng của mình, nó chạy phiên bản lớp con của mã, không làm gì cả và làm tôi buồn. Vì vậy, tất nhiên, một khi tôi loại bỏ thói quen khỏi các lớp con, nó đã sử dụng thói quen lớp mt "cơ sở" và tôi đang kinh doanh.

Tôi biết. Đừng cười. Nhưng có lẽ điều này sẽ cứu ai đó vào giờ tôi mất ...


8

Cho tôi 2 xu vào việc này.

Tôi đã có một UITableViewCell tùy chỉnh và có một nút bao trùm toàn bộ ô, vì vậy khi chạm vào, nút được chọn chứ không phải ô.

Hoặc loại bỏ nút hoặc trong trường hợp của tôi, tôi đặt Bật Tương tác người dùng thành sai trên nút, theo cách đó, ô được chọn.


8

Nếu bạn đọc nó, vì vậy vẫn không giải quyết được vấn đề.

Tôi có ô tùy chỉnh , trong đó hộp kiểm " Đã bật tương tác người dùng ". Vì vậy, tôi chỉ cần bật nó lên. Chúc may mắn.


7

Tôi chỉ có điều này và như đã xảy ra với tôi trong quá khứ nó không hoạt động vì tôi đã không chú ý đến tự động hoàn thành khi cố gắng thêm phương thức và tôi thực sự kết thúc việc thực hiện tableView:didDeselectRowAtIndexPath: thay vì tableView:didSelectRowAtIndexPath:.


7

Hãy chắc chắn rằng bạn đã thực hiện tableView:didSelectRowAtIndexPathvà khôngtableView:didDeSelectRowAtIndexPath

Điều này đã nhận được tôi nhiều hơn một vài lần !!


5

Tôi biết là đã cũ và vấn đề đã được giải quyết, nhưng có một vấn đề tương tự, tôi nghĩ rằng vấn đề là do UITableViewCell tùy chỉnh của tôi, nhưng giải pháp hoàn toàn khác - Tôi khởi động lại XCode :) và sau đó hoạt động tốt! gần giống như Windows :)


5

Nếu chế độ xem bảng của bạn ở chế độ chỉnh sửa (ví dụ [tableView setEditing:YES animated:NO];:), bạn cần đặttableView.allowsSelectionDuringEditing = YES;


4

Một lỗi khác bạn có thể đã làm (như tôi đã làm): nếu bạn đặt một dấu tách ở ô, didSelectRowAtIndexPathsẽ không được gọi. Thay vào đó, bạn nên đặt phân biệt của mình tại bộ điều khiển xem.


4

Không có câu trả lời nào trong số này làm việc cho tôi. Sau khoảng một giờ, tôi đã tìm ra một điều rất ngấm ngầm:

Tôi có chế độ xem bảng bên trong một ô của chế độ xem bảng khác. Tôi quyết định tạo một khung nhìn kèm theo có chứa khung nhìn bảng bên trong, trong số những thứ khác. Tôi đã gọi nội dung này xem và xem nó trong xib.

Hóa ra UITableViewCell đã có contentView và thực hiện những điều kỳ lạ với nó. Vấn đề tự giải quyết khi tôi đổi tên thuộc tính thành mainContentView và kết nối lại khung nhìn với thuộc tính được đổi tên này.


4

Trong trường hợp của tôi, tôi tự động tính toán chiều cao của TableView's SuperViewtại thời gian tải. Do tính toán sai, TableViewvị trí bên ngoài SuperView. Điều TableViewnày đã được rút ra, tuy nhiên tất cả các tương tác đã bị vô hiệu hóa (và didSelectRowAtIndexPathkhông bao giờ được gọi). Rất khó phát hiện, vì không có dấu hiệu trực quan nào cho thấy TableViewkhông thể truy cập được.


4

Trong trường hợp của tôi, vấn đề là tôi đã có một UITableViewCelllớp con và tôi đã thực hiện hai phương pháp sau: touchesBegan:withEvent:& touchesEnded:withEventđể xử lý một hình ảnh động ưa thích khi chạm vào. Nhưng tôi đã quên thêm [super touchesBegan:touches withEvent:event];quảng cáo phương thức [super touchesEnded:touches withEvent:event];để thông báo cho cha mẹ của tế bào cảm ứng.

Vì vậy, thay đổi mã để giải quyết vấn đề của tôi:

-(void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event{
    [super touchesBegan:touches withEvent:event];
    //blah blah blah
}

-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
    [super touchesEnded:touches withEvent:event];
    //rest of the code
}

1
Có thể xác nhận rằng điều này gây ra vấn đề của OP nói riêng đối với tôi
Josh Wolff

4

Trong trường hợp của tôi, giải pháp là thay đổi KHÔNG thành CÓ trong chức năng dưới đây.

iOS 9+

- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
    return YES;
}

Đây cũng là vấn đề của tôi. Tôi có một triển khai nhiều bảng xem và quên tách hai bảng xem trong phương thức này.
turingtested
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.