滚动表时,我遇到表视图单元格不能保持“选中”状态的问题。以下是相关代码:
@property (nonatomic, strong) NSIndexPath *selectedIndexPath;
-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
self.selectedIndexPath = indexPath;
//do other stuff
}
-(UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyCustomCell_iPhone* cell = [tableView dequeueReusableCellWithIdentifier:@"MyCustomCell_iPhone"];
if (cell == nil)
cell = [[[NSBundle mainBundle] loadNibNamed:@"MyCustomCell_iPhone" owner:self options:nil] objectAtIndex:0];
if ([indexPath compare: self.selectedIndexPath] == NSOrderedSame) {
[cell setSelected:YES animated:NO];
}
return cell;
}
对于细胞:
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
if (selected) {
self.selectedBg.hidden = NO;
}else{
self.selectedBg.hidden = YES;
}
}
- (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
{
[super setHighlighted:highlighted animated:animated];
if (highlighted) {
self.selectedBg.hidden = NO;
}else{
self.selectedBg.hidden = YES;
}
}
如何让所选单元格保持突出显示?如果我将它从屏幕上滚动,当它在屏幕上滚动时,它会以未选择的状态显示(隐藏了selectedBg)。
编辑: 从单元格中删除setHighlighted方法可以解决问题。但是,这意味着在按下表格单元格时没有突出显示状态。我想知道解决方法。
答案 0 :(得分:13)
出现同样的问题,选中的单元格的附件在滚动时消失了。我的同事发现了这个问题。原因是在iOS 7中 touchesBegan 事件UITableView取消选择所选单元格并选择触及的单元格。在iOS 6中它不会发生,并且滚动选择的单元格保持选中状态。要在iOS 7中获得相同的行为,请尝试:
1)在tableView中启用多项选择。
2)转到tableView委托方法 didSelectRowAtIndexPath ,并取消选择已触及的单元格代码:
NSArray *selectedRows = [tableView indexPathsForSelectedRows];
for(NSIndexPath *i in selectedRows)
{
if(![i isEqual:indexPath])
{
[tableView deselectRowAtIndexPath:i animated:NO];
}
}
解决了我的问题!希望它会有所帮助,抱歉我的英语很差。
答案 1 :(得分:7)
我知道我的方法不是很正统,但似乎有效。这是我的解决方案:
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if cell.selected {
cell.selected = true
} else {
cell.selected = false
}
}
您必须实现您在帖子中提到的所有方法(@soleil)
答案 2 :(得分:2)
iOS 7/8都会在滚动开始时取消选择单元格(正如Alexander Larionov指出的那样)。
对我来说更简单的解决方案是在我的ViewController中实现这个UIScrollViewDelegate方法:
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
NSInteger theRow = [self currentRowIndex]; // my own method
NSIndexPath *theIndexPath = [NSIndexPath indexPathForRow:theRow inSection:0];
[self.myTableView selectRowAtIndexPath:theIndexPath
animated:NO
scrollPosition:UITableViewScrollPositionNone];
}
这是有效的,因为我的viewController是UITableView的委托,UITableView继承自UIScrollView。
答案 3 :(得分:2)
我正在使用Xcode 9.0.1和Swift 4.0。我发现当屏幕和背面的单元格时,以下代码解析了我的选择标记:
override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
if cell.isSelected {
cell.accessoryType = .checkmark
} else {
cell.accessoryType = .none
}
}
答案 4 :(得分:1)
如果你想在Swift中实现同样的功能,那么这里是代码。顺便说一下,我使用Xcode 7.2和Swift 2.1。
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if cell.selected == true{
cell.selected = true
cell.backgroundColor = UIColor.blackColor()
}else{
cell.backgroundColor = tableViewCellColor //Don't panic its my own custom color created for the table cells.
cell.selected = false
}
}
根据您的需要进行其他定制..
谢谢..
希望这会有所帮助。
答案 5 :(得分:0)
您是否尝试过比较索引路径的行而不是整个索引路径对象?
if ((indexPath.row == self.selectedIndexPath.row) && (indexPath.section == self.selectedIndexPath.section)) {
[cell setSelected:YES animated:NO];
}
答案 6 :(得分:0)
这是我提出的解决方案 - 它甚至没有感觉到hacky。
1)实施-scrollViewWillBeginDragging:
和-scrollViewWillEndDragging:withVelocity:targetContentOffset:
并在滚动期间手动突出显示所选行的单元格(如果有)。
- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollview {
self.scrollViewIsDragging = YES;
if( [self.tableView indexPathForSelectedRow] ) {
[[self.tableView cellForRowAtIndexPath:[self.tableView indexPathForSelectedRow]] setHighlighted:YES];
}
}
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset {
self.scrollViewIsDragging = NO;
if( [self.tableView indexPathForSelectedRow] ) {
[[self.tableView cellForRowAtIndexPath:[self.tableView indexPathForSelectedRow]] setHighlighted:NO];
}
}
scrollViewIsDragging
属性是这样的,因此在-tableView:cellForRowAtIndexPath:
中我们可以确保任何新出列的单元格具有正确的突出显示(例如,如果所选行的单元格在屏幕外滚动到屏幕上)。该方法的相关部分如下所示:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// ... cell creation/configuration ...
if( self.scrollViewIsDragging && [[tableView indexPathForSelectedRow] isEqual:indexPath]) {
[cell setHighlighted:YES animated:NO];
}
}
......你有它。在滚动期间,selectedRow的单元格将保持突出显示。
答案 7 :(得分:0)
UITableViewCell具有BOOL属性“ selected ”。无论何时加载单元格,检查选定的状态,并在cellForRowAtIndexPath定义中进行相应的选择或取消选择:
if (cell.selected) {
// Maintain selected state
}
else{
// Maintain deselected state
}
答案 8 :(得分:0)
在这里发布了一个快速回答: https://stackoverflow.com/a/35605984/3754003
在其中,我也解释了为什么会发生这种情况。
答案 9 :(得分:0)
2017年Swift 3解决方案。
我用这个简单的代码行解决了这个问题:
cell.isSelected = tableView.indexPathsForSelectedRows?.contains(indexPath) ?? false
在 tableView(tableView:cellForRowAt indexPath:) 方法内:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// Dequeue a reusable cell
if let cell = tableView.dequeueReusableCell(withIdentifier: "YourCellID") {
cell.isSelected = tableView.indexPathsForSelectedRows?.contains(indexPath) ?? false
// Now you can safely use cell.isSelected to configure the cell
// ...your configurations here
return cell
}
return UITableViewCell()
}
答案 10 :(得分:0)
在自定义UITableViewCell
子类中放置以下代码:
override func setHighlighted(_ highlighted: Bool, animated: Bool) {
guard !isSelected else { return }
super.setHighlighted(highlighted, animated: animated)
if highlighted {
// Style cell for highlighted
} else {
// Style cell for unhighlighted
}
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
if selected {
// Style cell for selected
} else {
// Style cell for unselected
}
}
说明:尝试同时在setHighlighted
和setSelected
上设置断点。您会发现dequeueReusableCell
方法先依次依次setSelected
和setHighlighted
来重置新单元格。因此,您的突出显示代码正在吹走您在选择代码中所做的样式。非骇客修复程序是避免在调用setHighlighted(false, animated: false)
时破坏所选样式。