[英]Why is -didDeselectRowAtIndexPath not being called?
我創建了一個新項目(Xcode 4,Master-Detail 應用程序)只是為了看看我是否做錯了什么,但我仍然遇到同樣的問題。 當用戶取消選擇一個單元格時,我想調用-reloadData
,所以這是我的代碼:
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
NSLog(@"%s", __PRETTY_FUNCTION__);
}
-(void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"%s", __PRETTY_FUNCTION__);
[tableView reloadData];
}
-(NSIndexPath *)tableView:(UITableView *)tableView willDeselectRowAtIndexPath:(NSIndexPath *)indexPath {
NSLog(@"%s", __PRETTY_FUNCTION__);
return indexPath;
}
問題是didDeselectRowAtIndexPath
和willDeselectRowAtIndexPath
似乎沒有被調用。 這是預期的行為嗎? tableView:didDeselectRowAtIndexPath:
state 的文檔
告訴委托指定的行現在已取消選擇。
所以我想它應該像我想的那樣工作。
如果您調用deselectRowAtIndexPath:animated:
,則不會發送委托方法tableView:willDeselectRowAtIndexPath:
和tableView:didDeselectRowAtIndexPath:
消息。
tableView:willDeselectRowAtIndexPath:
的文檔也說
僅當用戶嘗試選擇不同的行時存在現有選擇時才會調用此方法。 為先前選定的行發送此方法的委托。 您可以使用UITableViewCellSelectionStyleNone禁用觸摸屏時單元格突出顯示的外觀。
當我使用UITableViewCellSelectionStyleNone
時,它對我們不起作用。
我發現的另一個怪癖——至少在 IOS 5.1 中——是如果你在表上調用reloadData
,你將不會得到任何選定行的didDeselectRowAtIndexPath
。 就我而言,我根據是否選中它稍微調整單元格布局,因此我需要在重新加載表格數據之前手動執行該工作。
我知道這是一個老問題,但我遇到了同樣的問題。
如果你使用
[tableView reloadData]
然后重新加載表數據並且在幕后沒有選擇任何行 - 意思是
只要
didSelectRowAtIndexPath
曾經被稱為。 我希望這可以幫助遇到這個問題的人。
解決此問題的一種簡潔方法是執行以下操作:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("myCell", forIndexPath: indexPath)
// Do your cell setup work here...
//If your cell should be selected...
if cellShouldBeSelected {
tableView.selectRowAtIndexPath(indexPath, animated: false, scrollPosition: UITableViewScrollPosition.None)
}
return cell
}
這解決了在tableView.reloadData()
調用發生后單元格沒有響應被取消選擇的整個問題。
第一次選擇任何單元格時,不會調用-[UITableViewDelegate tableView:didDeselectRowAtIndexPath:]
方法,而是調用-[UITableViewDelegate tableView:didSelectRowAtIndexPath:]
。 再選擇一個單元格后, didDeselectRowAtIndexPath
會在didSelectRowAtIndexPath
之后被調用。
還行吧。
但是,如果您必須在開始時顯示選定的單元格(例如使用UITableViewCellAccessoryCheckmark
),那么在選擇另一個單元格后,您可能希望第一次調用didDeselectRowAtIndexPath
方法,以取消選擇前一個單元格。
解決方案!
您必須調用-[UITableViewDataSource tableView:cellForRowAtIndexPath:]
的-[UITableView selectRowAtIndexPath:animated:scrollPosition:]
-[UITableViewDataSource tableView:cellForRowAtIndexPath:]
來通知已經選擇了想要的單元格。
目標-C
#pragma mark - UITableViewDelegate
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryCheckmark;
// saving the current selected row
SelectedRow = indexPath.row;
}
- (void)tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
cell.accessoryType = UITableViewCellAccessoryNone;
}
#pragma mark - UITableViewDataSource
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
if (!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
}
// preventing selection style
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.textLabel.text = "Some text";
if (indexPath.row == SelectedRow) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
// just wanted to make it selected, but it also can scroll to the selected position
[tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];
}
return cell;
}
斯威夫特 3.1
// MARK: - UITableViewDelegate
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)!
cell.accessoryType = UITableViewCellAccessoryType.checkmark
selectedRow = indexPath.row
}
override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) {
let cell = tableView.cellForRow(at: indexPath)!
cell.accessoryType = UITableViewCellAccessoryType.none
}
// MARK: - UITableViewDataSource
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: UITableViewCellStyle.default, reuseIdentifier: "cell")
// preventing selection style
cell.selectionStyle = UITableViewCellSelectionStyle.none
cell.textLabel?.text = "some text"
if (indexPath.row == selectedRow) {
cell.accessoryType = UITableViewCellAccessoryType.checkmark
// just wanted to make it selected, but it also can scroll to the selected position
tableView.selectRow(at: indexPath, animated: false, scrollPosition: UITableViewScrollPosition.none)
}
return cell
}
將該 tableview 的allowsMultipleSelection
設置為TRUE
self.tableView.allowsMultipleSelection = YES;
您只需將選擇設置為“多選”,因為 Xcode 僅允許您在此模式下取消選擇單元格。
我認為這只是一個簡單的錯誤! 為什么不使用以下內容:
[self.tableView deselectRowAtIndexPath:indexPath animated:YES];
而不是在該行中僅使用“tableView”?
我想,並且很確定上面的行會給你解決方案!
希望這對你有幫助,如果你回顧你的舊問題!!!
榮譽! :)
對我來說,它是通過添加開始工作的 -> super.setSelected(selected, animated: animated)
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)//This was missing
}
首先,您必須將allowsMultipleSelection
設置為true
並通過以下代碼設置delegate
self.tableView.allowsMultipleSelection = true
self.tableView.delegate = self
如果在didSelectRowAt
委托方法中使用tableView.reloadData()
,請刪除它。
在您的自定義單元格中,使用選定的方法。
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
//write your code here for selection method
}
通過這種方法,您的細胞狀態被選中。 如果您再次單擊選定的單元格,則 didDeSelect 委托方法將自動調用。
此問題的一個來源是直接在表格視圖單元格上設置isSelected
,而不是通過selectRow(at:animated:scrollPosition:)
或通過deselectRow(at:animated:)
將表格視圖告訴 select 單元格。
單元格的isSelected
屬性不是表格視圖用來確定是否調用委托的didDeselect
方法的事實來源(盡管設置了isSelected
的單元格似乎確實阻止表格視圖調用委托的didSelect
方法——這意味着單元格可以進入 state ,其中不可能 select 或通過 UI 取消選擇)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.