2012-11-07 34 views
16

Tôi đang gặp sự cố với các ô xem bảng không giữ trạng thái "đã chọn" khi cuộn bảng. Đây là mã có liên quan:UITableView ô đã chọn không được chọn khi cuộn

@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; 
} 

Và đối với các tế bào:

- (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; 
    } 
} 

Làm thế nào tôi có thể nhận được các ô đã chọn để duy trì nhấn mạnh? Nếu tôi di chuyển nó ra khỏi màn hình, khi nó cuộn trở lại trên màn hình nó xuất hiện trong trạng thái không được chọn của nó (với lựa chọn của nóBg ẩn).

CHỈNH SỬA: Xóa tập hợp Phương pháp được đánh dấu sáng khỏi ô sẽ khắc phục sự cố. Tuy nhiên điều đó có nghĩa là tôi không nhận được trạng thái được đánh dấu khi nhấn vào ô bảng. Tôi muốn biết giải pháp này.

Trả lời

13

Có cùng vấn đề, phụ kiện của ô đã chọnXem biến mất khi cuộn. Đồng nghiệp của tôi tìm thấy khá hack cho vấn đề này. Lý do là trong iOS 7 trên touchesBan động sự kiện UITableView bỏ chọn ô đã chọn và chọn ô được chạm xuống. Trong iOS 6 nó không xảy ra và trên di chuyển chọn ô vẫn được chọn. Để có được hành vi tương tự trong iOS 7, hãy thử:

1) Bật nhiều lựa chọn trong tableView của bạn.

2) Tới tableView phương pháp đại biểu didSelectRowAtIndexPath, và bỏ chọn tế bào hạ cánh với mã:

NSArray *selectedRows = [tableView indexPathsForSelectedRows]; 
for(NSIndexPath *i in selectedRows) 
{ 
    if(![i isEqual:indexPath]) 
    { 
     [tableView deselectRowAtIndexPath:i animated:NO]; 
    } 
} 

Cố định vấn đề của tôi! Hy vọng nó sẽ hữu ích, xin lỗi vì btw tiếng Anh nghèo của tôi.

+1

Tuyệt vời! Giải pháp này làm việc tốt cho tôi. Nhưng tôi đã tìm thấy sự cố khi hàng được chọn được chọn lại. Sau đó, nó được bỏ chọn. Tôi đã thêm phương pháp này UITableView đại biểu để giải quyết vấn đề này: - (NSIndexPath *) tableView: (UITableView *) tableView willDeselectRowAtIndexPath: (NSIndexPath *) indexPath { UITableViewCell * cell = [tableView cellForRowAtIndexPath: indexPath]; nếu ([ô được chọn]] { trả về số không; } return indexPath; } – mlabraca

0

Bạn đã thử so sánh các hàng của các đường dẫn chỉ mục thay vì toàn bộ đối tượng đường dẫn chỉ mục chưa?

if ((indexPath.row == self.selectedIndexPath.row) && (indexPath.section == self.selectedIndexPath.section)) { 
    [cell setSelected:YES animated:NO]; 
} 
+0

Điều này sẽ không hoạt động, vì có nhiều phần. – soleil

+0

Tôi đã cập nhật mã để bao gồm kiểm tra cho phần cũng như hàng. – danielM

0

Đây là giải pháp tôi đã đưa ra - và thậm chí nó không cảm thấy bị hack.

1) Triển khai -scrollViewWillBeginDragging:-scrollViewWillEndDragging:withVelocity:targetContentOffset: và đánh dấu thủ công ô cho hàng đã chọn (nếu có) trong khi cuộn.

Mine trông như thế này:

- (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]; 
    } 
} 

Thuộc tính scrollViewIsDragging là có để trong -tableView:cellForRowAtIndexPath: chúng ta có thể chắc chắn rằng bất kỳ tế bào mới dequeued có nổi bật thích hợp (ví dụ nếu ô cho hàng đã chọn được cuộn lên màn hình sau khi tắt màn hình). Phần liên hệ của phương pháp mà trông như thế này:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

    // ... cell creation/configuration ... 

    if(self.scrollViewIsDragging && [[tableView indexPathForSelectedRow] isEqual:indexPath]) { 
     [cell setHighlighted:YES animated:NO]; 
    } 

}

... và có bạn có nó. Ô cho SelectedRow sẽ được tô sáng trong khi cuộn.

+0

Thông báo trước, mà tôi nghĩ là hành vi chính xác (ít nhất là trong trường hợp của tôi), là một liên lạc do dự trên một ô khác có thể làm nổi bật ô đó trong giây lát trước khi người dùng bắt đầu cuộn. Nếu bất cứ ai có một cách thông minh để đối phó với điều này tôi muốn được nghe nó. –

6

Tôi biết phương pháp của tôi không phải là rất chính thống nhưng dường như hoạt động.Đây là giải pháp của tôi:

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { 
    if cell.selected { 
     cell.selected = true 
    } else { 
     cell.selected = false 
    } 
} 

Bạn phải thực hiện tất cả các phương pháp mà bạn đề cập về bài đăng của bạn cũng như (@soleil)

+0

Đây là một giải pháp rất đơn giản, và làm việc cho tôi – Joqus

+0

đây là giải pháp duy nhất ở đây đã giúp tôi. Tôi đã thực hiện nó trong Obj-C trong lớp con 'UITableViewController' của mình và thậm chí không cần thiết để lưu trữ' selectedIndexPath' trong một biến là @soleil nếu bạn sử dụng '[self setClearsSelectionOnViewWillAppear: NO];' – skornos

+0

bạn chỉ có thể làm ' cell.selected = cell.selected', mặc dù không thể đọc được – sbru

2

iOS 7/8 cả hai bỏ các tế bào khi di chuyển bắt đầu (như Alexander Larionov chỉ ra).

Một giải pháp đơn giản hơn đối với tôi là để thực hiện phương pháp này trong UIScrollViewDelegate ViewController tôi:

- (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]; 
} 

này hoạt động vì viewController tôi là đại biểu của UITableView, và UITableView thừa hưởng từ UIScrollView.

+1

Đây là giải pháp thay thế cho bạn NSIndexPath * indexPath = [_tableView indexPathForSelectedRow]; [_tableView selectRowAtIndexPath: indexPath hoạt ảnh: NO scrollPosition: UITableViewScrollPositionNone]; – alexiscrack3

0

UITableViewCell có thuộc tính BOOL "được chọn". Bất cứ khi nào bạn nạp các tế bào, kiểm tra tình trạng lựa chọn và đưa ra lựa chọn hoặc deselection phù hợp như sau trong định nghĩa cellForRowAtIndexPath:

if (cell.selected) { 
    // Maintain selected state 
} 
else{ 
    // Maintain deselected state 
} 
1

Nếu bạn muốn đạt được điều tương tự trong Swift thì đây là đoạn code. Nhân tiện tôi đang sử dụng Xcode 7.2 với 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 
    } 
} 

Do chỉnh khác gì đã bao giờ bạn muốn ..

Cảm ơn ..

Hy vọng điều này giúp đỡ.

0

giải pháp Swift 3, 2017.

Tôi cố định vấn đề với dòng đơn giản mã này:

cell.isSelected = tableView.indexPathsForSelectedRows?.contains(indexPath) ?? false 

Bên trong tableView (tableView: cellForRowAt indexPath :) phương pháp:

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() 
} 
1

Tôi đang sử dụng Xcode 9.0.1 và Swift 4.0. Tôi đã tìm thấy các mã sau giải quyết dấu chọn của mình khi các ô tắt màn hình và quay lại:

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) { 
    if cell.isSelected { 
     cell.accessoryType = .checkmark 
    } else { 
     cell.accessoryType = .none 
    } 
} 
Các vấn đề liên quan