선택한 UITableView 셀을 선택 해제하는 방법은 무엇입니까?


212

특정 셀을 미리 선택 해야하는 프로젝트를 진행 중입니다.

을 사용하여 셀을 미리 선택할 수 -willDisplayCell있지만 사용자가 다른 셀을 클릭하면 선택을 취소 할 수 없습니다.

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

도울 수 있니?


11
이 질문에 대한 답변이 필요합니다
Titouan de Bailleul

답변:


407

이 코드를 사용하십시오

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

스위프트 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
이전 경로를 선택 취소하는 데 사용할 didDeselectRowAtIndexPath가 있습니다.
huggie

3
정수 오버플로가 발생하기 때문에이 게시물을 찬성 할 수 없다고 생각합니다.)
Milo

안녕하세요 @ram,이 질문에 대한 답변을 선택해야합니다
Fattie

4
이해가 안됩니다 ...이 코드는 아무것도 선택하지 않을 것입니다.
C. Tewalt

@matrixugly가 맞습니다. 이것을 안에하는 것이 더 적절합니다 willSelectRowAt:. 보다 자세한 답변은 여기를 참조하십시오 : stackoverflow.com/questions/12693402/…
HuaTham

117

에서 다음과 같은 방법을 사용하여 테이블 뷰 대리인의 didSelectRowAtIndexpath(또는 어디서나)

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

2
그것이 indexPathForSelectedRow속성이 아니라 방법 이라는 점 은 주목할 가치가 있습니다.
FreeAsInBeer

단! 에 대해 몰랐습니다 [myTable indexPathForSelectedRow]. 나는 전에 세포를 반복하고있었습니다. 감사!
guptron

@FreeAsInBeer이 구별은 어떻게 든 중요합니까? 속성 접근자는 메서드입니다.
devios1

@chaiguy 동료를 사악하게 생각하지 않는다면 괜찮습니다 .
FreeAsInBeer

1
@Supertecnoboff 두 변형간에 성능 차이는 없습니다.
FreeAsInBeer

38

이 시도:

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

1
잘 했어 .. 두 번째 줄의 'index'는 indexPath 여야합니다.
El Tomato

iOS 11 Swift 4
Boris Nikolic

30

이를 위해 Swift에서 확장하는 것이 유용 할 수 있습니다.

스위프트 4와 스위프트 5 :

빠른 확장 (예 : UITableViewExtension.swift 파일) :

import UIKit

extension UITableView {

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

}

사용 예 :

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

    self.tableView.deselectSelectedRow(animated: true)
}

1
내 생각에,이 답변은 viewWillAppear()방법에 황폐를 넣으면 사용자가 자신이 어디에서 왔는지 이해하는 데 도움이 되므로 더 좋습니다 .
MonsieurDart

내가 필요로 한 완벽한 것
Patel Jigar

28

위임 방법이 올바른지 여부를 확인하십시오. 예를 들어;

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

...에 대한

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

이 시간 내내 잘못된 방법을 부르고 있었다, arghh !! 감사합니다!
Damir Kotoric

1
오 남자 .. 피 묻은 자동 완성 !!! 알아내는 데 몇 시간이 걸렸습니다 !!! 세상에 ... 키스하고 싶어요!
George Asda

22

스위프트 4 :

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

선택 사항이 아닌 것으로 선언 할 필요는 없지만 이것이 맞습니다.
Michael

16

이것은 스위프트 4에 대한 솔루션입니다

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

그냥 추가

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

그것은 매력처럼 작동합니다

예:

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

당신이 당신의 tableview에서 편집시 선택을 추가 할 때까지, 당신이 그것을 선택했을 때 그것을 선택 해제하기 때문에 어떤 셀을 선택하는 것은 불가능합니다 :)
Mehdi Chennoufi

이것은 편집하지 않을 때, "행을 두드려서 무언가를하기"때 올바른 접근법입니다
Fattie

11

셀을 선택된 것으로 설정하는 것 외에도, 셀이 선택되었음을 tableView에 알려야합니다. 에 호출을 추가 -tableView:selectRowAtIndexPath:animated:scrollPosition:하여에 willDisplayCell:방법 당신은 정상으로 선택을 취소 할 수 있습니다.

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

이상한 스크롤 동작을 피하려면 UITableViewScrollPositionNone을 사용해야합니다.


1
절대적으로 맞습니다. 나는 그것이 [cell setSelected:YES]생략 될 수 있다고 생각 한다 : selectRowAtIndexPath세포의 selected상태를 돌볼 것이다
spassas

이 답변은 여러 선택 항목이있는 UITableView에 적용됩니다. 엄지 손가락.
Danny Bravo

6

이것은 작동해야합니다 :

[tableView deselectRowAtIndexPath:indexpath1 animated:NO];

materialTable과 tableView가 동일한 객체를 가리키는 지 확인하십시오.

인터페이스 빌더에서 재질이 tableView에 연결되어 있습니까?


나는 NO로 테스트했지만 내 문제도 해결하지 못했습니다. 하지만 didselect 대리자가 해고 될 때 데이터를 다시로드하는 다른 방법 으로이 문제를 해결했습니다.
Ram

6

saikirans 솔루션을 기반으로, 나는 이것을 작성하여 나를 도왔다. .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];

}

그리고 헤더 파일에서 :

@property (retain, nonatomic) NSIndexPath* selectedRowIndex;

나는 경험이 많지 않으므로 메모리 누수 등을 다시 확인하십시오.


6

첫 번째 클릭으로 테이블 셀을 선택하고 두 번째 클릭으로 선택 취소하려면이 코드를 사용해야합니다.

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

스위프트 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
스위프트 3. 그냥 나를 위해 일한이 추가 한 self.tableView(tableView, didDeselectRowAt: indexPath)tableView.deselectRow...이 자동으로 호출되지 않았기 때문에
elysch


3

이 시도

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

답변을 설명하십시오. 그렇지 않으면 의견이 있어야합니다.
Hugo Dozois 2013

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

이 코드를 코드에 따라 배치하면 셀 선택이 해제됩니다.


3

당신이 이것을 시도 할 수 있습니까?

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

그것은 나를 위해 일했다.


2

스위프트 3.0 :

ray wenderlich swift style guide프로토콜 적합성 섹션에 따라 관련 메소드를 그룹화하려면이 확장을 뷰 컨트롤러 클래스 아래에 다음과 같이 배치하십시오.

// 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

빠른

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

스위프트 3

나는 또한 이것에 부딪쳤다-당신이 탐색하거나 테이블 뷰로 되 감을 때 일반적으로 이전에 선택된 행을 선택 해제하지 않는다. 이 코드를 테이블 뷰 컨트롤러에 넣고 잘 작동합니다.

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

1

스위프트 3/4

ViewController에서 :

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

맞춤 셀에서 :

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


0

사전로드 된 데이터로 인해 처음 클릭 할 때 (DidDeselectRowAt) 실행을 해제하려면; 행이 이미 선택되어 있음을 tableView에 알려 주어야하므로 처음 클릭하면 행이 선택 해제됩니다.

// 스위프트 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

내가 찾은 것은 셀을 selected 로 설정하는 것 외에도 주어진 인덱스 경로에서 행 을 선택 하도록 테이블 뷰에 알려 주어야한다는 것입니다.

// 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)
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.