Làm cách nào để bỏ chọn một ô UITableView đã chọn?


212

Tôi đang làm việc trên một dự án mà tôi phải chọn trước một ô cụ thể.

Tôi có thể chọn trước một ô bằng cách sử dụng -willDisplayCell, nhưng tôi không thể bỏ chọn nó khi người dùng nhấp vào bất kỳ ô nào khác.

- (void)tableView:(UITableView*)tableView 
        willDisplayCell:(UITableViewCell*)cell
        forRowAtIndexPath:(NSIndexPath*)indexPath
{ 
    AppDelegate_iPad *appDelegte = 
      (AppDelegate_iPad *)[[UIApplication sharedApplication] delegate];

    if ([appDelegte.indexPathDelegate row] == [indexPath row])
    {
        [cell setSelected:YES];    
    } 
}

- (void)tableView:(UITableView *)tableView 
        didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    AppDelegate_iPad *appDelegte = 
      (AppDelegate_iPad *)[[UIApplication sharedApplication] delegate];

    NSIndexPath *indexpath1 = appDelegte.indexPathDelegate;
    appDelegte.indexPathDelegate = indexPath;
    [materialTable deselectRowAtIndexPath:indexpath1 animated:NO];
}

Bạn có thể giúp?


11
Câu hỏi này cần phải có câu trả lời được chấp nhận
Titouan de Bailleul

Câu trả lời:


407

sử dụng mã này

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath 
 {
    //Change the selected background view of the cell.
     [tableView deselectRowAtIndexPath:indexPath animated:YES];
 }

Swift 3.0:

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    //Change the selected background view of the cell.
    tableView.deselectRow(at: indexPath, animated: true)
}

1
Có một didDeselectRowAtIndexPath để sử dụng để bỏ chọn cái trước đó.
huggie

3
Tôi muốn nghĩ rằng tôi không thể nâng cấp bài đăng này vì nó sẽ gây ra tràn số nguyên :)
Milo

xin chào @ram, bạn cần chọn một câu trả lời cho câu hỏi này
Fattie 20/03/2016

4
Tôi không hiểu ... mã này sẽ không bao giờ để bất cứ thứ gì được chọn.
C. Tewalt

@matrixugly nói đúng. Nó thích hợp hơn để làm điều này bên trong willSelectRowAt:. Xem câu trả lời đầy đủ hơn tại đây: stackoverflow.com/questions/12693402/ từ
HuaTham

117

Sử dụng phương pháp sau trong bảng đại biểu của khung nhìn didSelectRowAtIndexpath(Hoặc từ bất cứ đâu)

[myTable deselectRowAtIndexPath:[myTable indexPathForSelectedRow] animated:YES];

2
Điều đáng chú ý đó indexPathForSelectedRowlà một phương pháp và không phải là một tài sản.
FreeAsInBeer

Ngọt! Không biết về [myTable indexPathForSelectedRow]. Tôi đã lặp qua các tế bào trước đây. Cảm ơn!
guptron

@FreeAsInBeer Sự khác biệt này có quan trọng không? Người truy cập tài sản là phương pháp.
devios1

@chaiguy Điều đó tốt nếu bạn không phiền các đồng nghiệp coi bạn là ác quỷ .
FreeAsInBeer

1
@Supertecnoboff Không có sự khác biệt về hiệu suất giữa hai biến thể.
FreeAsInBeer

38

Thử cái này:

for (NSIndexPath *indexPath in tableView.indexPathsForSelectedRows) {
    [tableView deselectRowAtIndexPath:indexPath animated:NO];
}

1
Làm tốt lắm ... Tôi nghĩ 'chỉ số' trên dòng thứ 2 nên là indexPath
El Tomato

điều này không được hỗ trợ trên iOS 11 Swift 4
Boris Nikolic

30

Có thể hữu ích để tạo một tiện ích mở rộng trong Swift cho việc này.

Swift 4 và Swift 5:

Tiện ích mở rộng Swift (ví dụ: trong tệp UITableViewExtension.swift):

import UIKit

extension UITableView {

    func deselectSelectedRow(animated: Bool)
    {
        if let indexPathForSelectedRow = self.indexPathForSelectedRow {
            self.deselectRow(at: indexPathForSelectedRow, animated: animated)
        }
    }

}

Sử dụng ví dụ:

override func viewWillAppear(_ animated: Bool)
{
    super.viewWillAppear(animated)

    self.tableView.deselectSelectedRow(animated: true)
}

1
Theo tôi, câu trả lời này tốt hơn bởi vì đặt sự hoang vắng trong viewWillAppear()phương pháp giúp người dùng hiểu được nơi anh ta trở về.
MonsieurDart

người hoàn hảo như tôi cần
Patel Jigar

28

Vui lòng kiểm tra với phương thức đại biểu xem nó có đúng hay không. Ví dụ;

-(void) tableView:(UITableView *)tableView didDeselectRowAtIndexPath:(NSIndexPath *)indexPath

cho

-(void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

Đã gọi sai phương pháp toàn bộ thời gian này, arghh !! Cảm ơn bạn!
Damir Kotoric

1
trời ơi .... tự động đẫm máu !!! Tôi phải mất vài giờ để tìm ra nó !!! OMG ... tôi muốn hôn bạn!
George Asda

22

Swift 4:

tableView.deselectRow(at: indexPath, animated: true)

Không cần phải khai báo là không tùy chọn nhưng điều này là chính xác.
Michael

16

Đây là một giải pháp cho Swift 4

 in tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)

chỉ cần thêm

tableView.deselectRow(at: indexPath, animated: true)

Nó hoạt động như một say mê

thí dụ:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
//some code
}

cho đến khi bạn thêm lựa chọn vào chỉnh sửa trong chế độ xem bảng của mình, sẽ không thể chọn bất kỳ ô nào vì nó sẽ bỏ chọn khi bạn chọn xong :)
Mehdi Chennoufi

Đây chắc chắn là cách tiếp cận chính xác, khi bạn không chỉnh sửa, khi bạn "chạm vào một hàng để làm gì đó"
Fattie

11

Ngoài việc đặt ô như đã chọn, bạn cũng cần thông báo cho bảngView rằng ô được chọn. Thêm một cuộc gọi vào phương thức -tableView:selectRowAtIndexPath:animated:scrollPosition:của bạn willDisplayCell:: và bạn sẽ có thể bỏ chọn nó như bình thường.

- (void)tableView:(UITableView*)tableView 
  willDisplayCell:(UITableViewCell*)cell
forRowAtIndexPath:(NSIndexPath*)indexPath
{ 
    AppDelegate_iPad *appDelegte = (AppDelegate_iPad *)[[UIApplication sharedApplication] delegate];

    if ([appDelegte.indexPathDelegate row] == [indexPath row])
    {
        // SELECT CELL
        [cell setSelected:YES]; 
        // TELL TABLEVIEW THAT ROW IS SELECTED
        [tableView selectRowAtIndexPath:indexPath animated:NO scrollPosition:UITableViewScrollPositionNone];   
    } 
}

Hãy chắc chắn sử dụng UITableViewScrollPocationNone để tránh hành vi cuộn lẻ.


1
Chuẩn xác. Tôi nghĩ rằng [cell setSelected:YES]có thể bỏ qua: selectRowAtIndexPathsẽ chăm sóc selectedtrạng thái của tế bào
spassas

Câu trả lời này hoạt động cho UITableView's với nhiều lựa chọn. Đồng ý.
Daniel Bravo

6

Điều này sẽ làm việc:

[tableView deselectRowAtIndexPath:indexpath1 animated:NO];

Chỉ cần chắc chắn rằng MaterialTable và tableView đang trỏ đến cùng một đối tượng.

Các vật liệu có được kết nối với bảngView trong Interface Builder không?


tôi đã thử nghiệm với NO nhưng điều đó cũng không giải quyết được vấn đề của tôi. nhưng tôi đã khắc phục vấn đề này bằng một cách khác là Dữ liệu được tải lại khi bao giờ đại biểu didselect bị sa thải.
Ram

6

Dựa trên giải pháp saikirans, tôi đã viết điều này, giúp tôi. Trên tệp .m:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    if(selectedRowIndex && indexPath.row == selectedRowIndex.row) {

        [tableView deselectRowAtIndexPath:indexPath animated:YES];
        selectedRowIndex = nil;

    }

    else {  self.selectedRowIndex = [indexPath retain];   }

    [tableView beginUpdates];
    [tableView endUpdates];

}

Và trên tệp tiêu đề:

@property (retain, nonatomic) NSIndexPath* selectedRowIndex;

Tôi cũng không có nhiều kinh nghiệm, vì vậy hãy kiểm tra kỹ các rò rỉ bộ nhớ, v.v.


6

Nếu bạn muốn chọn bất kỳ ô bảng nào với lần nhấp đầu tiên và bỏ chọn với ô thứ hai, bạn nên sử dụng mã này:

- (void)tableView:(UITableView *)tableView 
        didSelectRowAtIndexPath:(NSIndexPath *)indexPath {   

    if (self.selectedIndexPath && 
        [indexPath compare:self.selectedIndexPath] == NSOrderedSame) {

        [tableView deselectRowAtIndexPath:indexPath animated:YES];
         self.selectedIndexPath = nil;
    } 
    else {
        self.selectedIndexPath = indexPath;
    }
}

5

Swift 4:

func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? {
    let cell = tableView.cellForRow(at: indexPath)
    if cell?.isSelected == true { // check if cell has been previously selected
        tableView.deselectRow(at: indexPath, animated: true)
        return nil
    } else {
        return indexPath
    }
}

2
Điều này làm việc cho tôi trong Swift 3. Chỉ cần thêm self.tableView(tableView, didDeselectRowAt: indexPath)sau tableView.deselectRow...vì nó không được gọi tự động
elysch

4

Swift 2.0:

tableView.deselectRowAtIndexPath(indexPath, animated: true)

3

thử cái này

[self.tableView deselectRowAtIndexPath:[self.tableView indexPathForSelectedRow] animated:YES];

Hãy thử giải thích câu trả lời của bạn, nếu không nó sẽ là một nhận xét.
Hugo Dozois

3
NSIndexPath * index = [self.menuTableView indexPathForSelectedRow];
[self.menuTableView deselectRowAtIndexPath:index animated:NO];

đặt mã này theo mã của bạn và bạn sẽ bỏ chọn ô của mình.


3

Bạn có thể thử cái này không?

- (void)tableView:(UITableView *)tableView 
  didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    AppDelegate_iPad *appDelegte = 
    (AppDelegate_iPad *)[[UIApplication sharedApplication] delegate];
    NSIndexPath *indexpath1 = appDelegte.indexPathDelegate;
    appDelegte.indexPathDelegate = indexPath;

    UITableViewCell *prevSelectedCell = [tableView cellForRowAtIndexPath: indexpath1];
    if([prevSelectedCell isSelected]){
       [prevSelectedCell setSelected:NO];
    }
}

Nó làm việc cho tôi.


2

Swift 3.0:

Theo phần tuân thủ giao thức của hướng dẫn kiểu swift ray wenderlich , để giữ các phương thức liên quan được nhóm lại với nhau, hãy đặt phần mở rộng này bên dưới lớp trình điều khiển xem của bạn như thế:

// your view controller
class MyViewcontroller: UIViewController {
  // class stuff here
}

// MARK: - UITableViewDelegate
extension MyViewcontroller: UITableViewDelegate {
      // use the UITableViewDelegate method tableView(_:didSelectRowAt:)
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {

        // your code when user select row at indexPath

        // at the end use deselectRow
        tableView.deselectRow(at: indexPath, animated: true)
    }
}

1

Nhanh

func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {

    // your code

    // your code

    // and use deselect row to end line of this function

    self.tableView.deselectRowAtIndexPath(indexPath, animated: true)

}

1
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)
}

1

Swift 3

Tôi cũng đã gặp phải điều này - khi bạn điều hướng hoặc thư giãn trở lại chế độ xem bảng, nó thường không bỏ chọn hàng đã chọn trước đó cho bạn. Tôi đặt mã này trong trình điều khiển xem bảng và nó hoạt động tốt:

override func viewDidAppear(_ animated: Bool) {
    if let lastSelectedRow = tableView.indexPathForSelectedRow {
        tableView.deselectRow(at: lastSelectedRow, animated: true)
    }
}

1

Swift 3/4

Trong ViewContoder:

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
    tableView.deselectRow(at: indexPath, animated: true)
}

Trong ô tùy chỉnh:

override func awakeFromNib() {
    super.awakeFromNib()
    selectionStyle = .none
}


0

Để hủy bỏ chọn (DidDeselectRowAt) khi nhấp vào lần đầu tiên vì dữ liệu được tải sẵn; bạn cần thông báo cho bảng Xem rằng hàng đã được chọn để bắt đầu, để lần nhấp đầu tiên sau đó bỏ chọn hàng:

// Swift 3:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    if tableView[indexPath.row] == "data value"

        tableView.selectRow(at: indexPath, animated: false, scrollPosition: UITableViewScrollPosition.none)

    }
}

0

Những gì tôi đã tìm thấy là ở đầu cài đặt ô như đã chọn , bạn phải cho chế độ xem bảng biết để chọn hàng ở đường dẫn chỉ mục đã cho.

// Swift 3+  

override func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if appDelegate.indexPathDelegate.row == indexPath.row {
        self.tableView.selectRow(at: indexPath, animated: true, scrollPosition: .none)
        cell.setSelected(true, animated: true)
    }
}
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.