programing

정적 셀로 설정된 UITableView입니다.프로그래밍 방식으로 일부 셀을 숨길 수 있습니까?

goodsources 2023. 5. 26. 20:53
반응형

정적 셀로 설정된 UITableView입니다.프로그래밍 방식으로 일부 셀을 숨길 수 있습니까?

UITableView정적 셀로 설정합니다.

프로그래밍 방식으로 일부 셀을 숨길 수 있습니까?

UI 테이블에서 정적 셀을 숨기는 방법

  1. 다음 방법을 추가합니다.

UITableView 컨트롤러 대리자 클래스에서 다음을 수행합니다.

목표-C:

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell* cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];

    if(cell == self.cellYouWantToHide)
        return 0; //set the hidden cell's height to 0

    return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}

스위프트:

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    var cell = super.tableView(tableView, cellForRowAtIndexPath: indexPath)

    if cell == self.cellYouWantToHide {
        return 0
    }

    return super.tableView(tableView, heightForRowAtIndexPath: indexPath)
}

이 메서드는 UI 테이블의 각 셀에 대해 호출됩니다.숨기려는 셀을 호출하면 높이를 0으로 설정합니다.대상 셀에 대한 배출구를 만들어 대상 셀을 식별합니다.

  1. 디자이너에서 숨기려는 셀의 배출구를 만듭니다.이러한 셀의 배출구를 위의 "숨기기를 원하는 셀"이라고 합니다.
  2. 숨길 셀에 대해 IB의 "Clip Subviews"를 선택합니다.숨기고 있는 셀은 ClipToBounds = YES여야 합니다.그렇지 않으면 텍스트가 UI 테이블 보기에 쌓입니다.

이 솔루션을 찾고 있습니다.

정적 데이터 테이블 뷰 컨트롤러 2.0

https://github.com/xelvenone/StaticDataTableViewController

애니메이션 유무에 관계없이 모든 정적 셀을 표시/숨김/숨김/숨김할 수 있습니다!

[self cell:self.outletToMyStaticCell1 setHidden:hide]; 
[self cell:self.outletToMyStaticCell2 setHidden:hide]; 
[self reloadDataAnimated:YES];

항상 사용해야 합니다(ReloadDataAnimated:YES/NO)([self.tableViewreloadData]를 직접 호출하지 않음)

이것은 높이를 0으로 설정한 해키 솔루션을 사용하지 않으며 변경 사항을 애니메이션화하고 전체 섹션을 숨길 수 있습니다.

가장 좋은 방법은 다음 블로그 http://ali-reynolds.com/2013/06/29/hide-cells-in-static-table-view/ 에 설명된 대로입니다.

인터페이스 빌더에서 정적 테이블 뷰를 정상적으로 설계하여 잠재적으로 숨겨진 모든 셀로 완성할 수 있습니다.그러나 숨기려는 모든 잠재적 셀에 대해 한 가지 작업을 수행해야 합니다. 셀의 "하위 보기 클립" 속성을 확인하십시오. 그렇지 않으면 셀의 높이를 축소하여 나중에 셀을 숨기려고 해도 셀의 내용이 사라지지 않습니다.

즉, 셀에 스위치가 있고 스위치는 일부 정적 셀을 숨기고 표시해야 합니다.IAction에 연결하고 다음 작업을 수행합니다.

[self.tableView beginUpdates];
[self.tableView endUpdates];

이것은 세포가 나타나고 사라지는 것에 대한 멋진 애니메이션을 제공합니다.이제 다음 테이블 뷰 대리자 방법을 구현합니다.

- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.section == 1 && indexPath.row == 1) { // This is the cell to hide - change as you need
    // Show or hide cell
        if (self.mySwitch.on) {
            return 44; // Show the cell - adjust the height as you need
        } else {
            return 0; // Hide the cell
        }
   }
   return 44;
}

그리고 그게 다야.스위치를 돌리면 셀이 숨었다가 부드럽고 멋진 애니메이션으로 다시 나타납니다.

제 해결책은 Gareth와 비슷한 방향으로 가고 있습니다. 제가 하는 일이 좀 다르긴 하지만요.

다음과 같습니다.

셀 숨기기

세포를 직접 숨길 방법은 없습니다. UITableViewController는 정적 셀을 제공하는 데이터 소스이며, 현재 "셀 x를 제공하지 않음"이라고 말할 수 없습니다.그래서 우리는 우리 자신의 데이터 소스를 제공해야 하며, 이 소스는 다음과 같이 위임됩니다.UITableViewController정적 세포를 얻기 위해.

가장 쉬운 것은 하위 분류입니다.UITableViewController을 숨길 때 다르게 동작해야 하는 모든 메서드를 재정의합니다.

가장 단순한 경우(단일 섹션 테이블, 모든 셀의 높이가 동일), 다음과 같습니다.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section    
{
    return [super tableView:tableView numberOfRowsInSection:section] - numberOfCellsHidden;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Recalculate indexPath based on hidden cells
    indexPath = [self offsetIndexPath:indexPath];

    return [super tableView:tableView cellForRowAtIndexPath:indexPath];
}

- (NSIndexPath*)offsetIndexPath:(NSIndexPath*)indexPath
{
    int offsetSection = indexPath.section; // Also offset section if you intend to hide whole sections
    int numberOfCellsHiddenAbove = ... // Calculate how many cells are hidden above the given indexPath.row
    int offsetRow = indexPath.row + numberOfCellsHiddenAbove;

    return [NSIndexPath indexPathForRow:offsetRow inSection:offsetSection];
}

표에 섹션이 여러 개 있거나 셀 높이가 다른 경우 더 많은 방법을 재정의해야 합니다.super에 위임하기 전에 indexPath, 단면 및 행을 오프셋해야 합니다.

indexPath와 같은 는 indexPath와 .didSelectRowAtIndexPath:상태(즉, 숨겨진 셀 수)에 따라 동일한 셀에 대해 다릅니다.따라서 indexPath 매개 변수를 항상 오프셋하고 이러한 값으로 작업하는 것이 좋습니다.

변경 사항에 대한 애니메이션 제작

Gareth가 이미 말했듯이, 만약 당신이 다음을 사용하여 변경을 애니메이션화한다면 당신은 큰 결함을 갖게 될 것입니다.reloadSections:withRowAnimation:방법.

이 당신전걸면에 전화하면 .reloadData:그 직후에는 애니메이션이 훨씬 개선됩니다(작은 결함만 남음).애니메이션 후 테이블이 올바르게 표시됩니다.

그래서 제가 하고 있는 일은:

- (void)changeState
{
     // Change state so cells are hidden/unhidden
     ...

    // Reload all sections
    NSIndexSet* reloadSet = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [self numberOfSectionsInTableView:tableView])];

    [tableView reloadSections:reloadSet withRowAnimation:UITableViewRowAnimationAutomatic];
    [tableView reloadData];
}
  1. 디자이너에서 숨기려는 셀의 배출구를 만듭니다.예를 들어, 'cellOne'을 숨기려고 하면 viewDidLoad()에서 이 작업을 수행합니다.

셀 원 아웃렛.숨겨진 = 참

이제 아래 방법을 재정의하고 숨겨진 셀 상태를 확인하고 해당 셀에 대해 높이 0을 반환합니다.이것은 정적 테이블에서 셀을 숨길 수 있는 여러 가지 방법 중 하나입니다.

override func tableView(tableView: UITableView, heightForRowAtIndexPathindexPath: NSIndexPath) -> CGFloat 
{

let tableViewCell = super.tableView(tableView,cellForRowAtIndexPath: indexPath)

        if tableViewCell.hidden == true
        {
            return 0
        }
        else{
             return super.tableView(tableView, heightForRowAtIndexPath: indexPath)
        }

}

저는 실제로 섹션을 숨기고 삭제하지 않는 대안을 생각해냈습니다.@henning77의 접근 방식을 시도했지만 정적 UITableView의 섹션 수를 변경할 때 계속 문제가 발생했습니다.이 방법은 저에게 매우 효과적이었지만 주로 행 대신 섹션을 숨기려고 합니다.몇 개의 행을 성공적으로 제거하고 있지만, 훨씬 더 지저분하기 때문에 표시하거나 숨길 부분으로 그룹화하려고 했습니다.다음은 섹션을 숨기는 방법의 예입니다.

먼저 NSMutableArray 속성을 선언합니다.

@property (nonatomic, strong) NSMutableArray *hiddenSections;

DidLoad 보기(또는 데이터를 쿼리한 후)에서 숨길 섹션을 배열에 추가할 수 있습니다.

- (void)viewDidLoad
{
    hiddenSections = [NSMutableArray new];

    if(some piece of data is empty){
        // Add index of section that should be hidden
        [self.hiddenSections addObject:[NSNumber numberWithInt:1]];
    }

    ... add as many sections to the array as needed

    [self.tableView reloadData];
}

그런 다음 다음 TableView 위임 방법을 구현합니다.

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    if([self.hiddenSections containsObject:[NSNumber numberWithInt:section]]){
        return nil;
    }

    return [super tableView:tableView titleForHeaderInSection:section];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if([self.hiddenSections containsObject:[NSNumber numberWithInt:indexPath.section]]){
        return 0;
    }

    return [super tableView:tableView heightForRowAtIndexPath:[self offsetIndexPath:indexPath]];
}

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if([self.hiddenSections containsObject:[NSNumber numberWithInt:indexPath.section]]){
        [cell setHidden:YES];
    }
}

그런 다음 높이를 0으로 설정할 수 없으므로 숨겨진 섹션의 머리글 및 바닥글 높이를 1로 설정합니다.이로 인해 2픽셀의 공간이 추가되지만, 다음에 보이는 헤더의 높이를 조정하여 이를 보완할 수 있습니다.

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 
{
    CGFloat height = [super tableView:tableView heightForHeaderInSection:section];

    if([self.hiddenSections containsObject:[NSNumber numberWithInt:section]]){
        height = 1; // Can't be zero
    }
    else if([self tableView:tableView titleForHeaderInSection:section] == nil){ // Only adjust if title is nil
        // Adjust height for previous hidden sections
        CGFloat adjust = 0;

        for(int i = (section - 1); i >= 0; i--){
            if([self.hiddenSections containsObject:[NSNumber numberWithInt:i]]){
                adjust = adjust + 2;
            }
            else {
                break;
            }
        }

        if(adjust > 0)
        {                
            if(height == -1){
                height = self.tableView.sectionHeaderHeight;
            }

            height = height - adjust;

            if(height < 1){
                height = 1;
            }
        }
    }

    return height;
}

-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section 
{   
    if([self.hiddenSections containsObject:[NSNumber numberWithInt:section]]){
        return 1;
    }
    return [super tableView:tableView heightForFooterInSection:section];
}

그런 다음 숨길 특정 행이 있는 경우 섹션 내 행 수와 셀ForRowAt에서 반환되는 행 수를 조정할 수 있습니다.인덱스 경로.이 예제에서는 세 개의 행이 있는 섹션이 있습니다. 세 개는 비워 둘 수 있고 제거해야 합니다.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSInteger rows = [super tableView:tableView numberOfRowsInSection:section];

    if(self.organization != nil){
        if(section == 5){ // Contact
            if([self.organization objectForKey:@"Phone"] == [NSNull null]){     
                rows--;
            }

            if([self.organization objectForKey:@"Email"] == [NSNull null]){     
                rows--;
            }

            if([self.organization objectForKey:@"City"] == [NSNull null]){     
                rows--;
            }
        }
    }

    return rows;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{    
    return [super tableView:tableView cellForRowAtIndexPath:[self offsetIndexPath:indexPath]];
}

이 간격띄우기 사용IndexPath 조건부로 행을 제거할 행에 대한 인덱스Path를 계산합니다.섹션만 숨기는 경우에는 필요하지 않습니다.

- (NSIndexPath *)offsetIndexPath:(NSIndexPath*)indexPath
{
    int row = indexPath.row;

    if(self.organization != nil){
        if(indexPath.section == 5){
            // Adjust row to return based on which rows before are hidden
            if(indexPath.row == 0 && [self.organization objectForKey:@"Phone"] == [NSNull null] && [self.organization objectForKey:@"Email"] != [NSNull null]){     
                row++;
            }
            else if(indexPath.row == 0 && [self.organization objectForKey:@"Phone"] == [NSNull null] && [self.organization objectForKey:@"Address"] != [NSNull null]){     
                row = row + 2;
            }
            else if(indexPath.row == 1 && [self.organization objectForKey:@"Phone"] != [NSNull null] && [self.organization objectForKey:@"Email"] == [NSNull null]){     
                row++;
            }
            else if(indexPath.row == 1 && [self.organization objectForKey:@"Phone"] == [NSNull null] && [self.organization objectForKey:@"Email"] != [NSNull null]){     
                row++;
            }
        }
    }

    NSIndexPath *offsetPath = [NSIndexPath indexPathForRow:row inSection:indexPath.section];

    return offsetPath;
}

무시할 수 있는 방법은 여러 가지가 있지만, 제가 이 접근 방식을 좋아하는 이유는 재사용이 가능하다는 것입니다.숨겨진 섹션 배열을 설정하고 추가하면 올바른 섹션이 숨겨집니다.행을 숨기는 것이 조금 더 까다롭지만, 가능합니다.그룹화된 UITableView를 사용하는 경우 테두리가 올바르게 그려지지 않으므로 숨길 행의 높이를 0으로 설정할 수 없습니다.

정적 UI 테이블 보기 및 애니메이션으로 셀을 숨기거나 표시할 수 있습니다.그리고 그것은 성취하기에 그리 어렵지 않습니다.

데모 프로젝트

데모 프로젝트 비디오

요점:

  1. Use tableView:heightForRowAtIndexPath:특정 상태를 기반으로 동적으로 셀 높이를 지정합니다.
  2. 상태가 호출을 통해 표시/숨김 애니메이션 셀을 변경하는 경우tableView.beginUpdates();tableView.endUpdates()
  3. 라고 부르지 마.tableView.cellForRowAtIndexPath:東京의 tableView:heightForRowAtIndexPath:캐시된 indexPath를 사용하여 셀을 구분합니다.
  4. 셀을 숨기지 마십시오.대신 Xcode에서 "Clip Subviews" 속성을 설정합니다.
  5. 사용자 지정 셀(일반 등이 아님)을 사용하여 멋진 숨김 애니메이션을 얻습니다.또한 셀 높이 == 0인 경우 자동 레이아웃을 올바르게 처리합니다.

내 블로그에 더 많은 정보(러시아어)

Justas의 답변에 따르면 Swift 4의 경우:

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    let cell = super.tableView(tableView, cellForRowAt: indexPath)

    if cell == self.cellYouWantToHide {
        return 0
    }

    return super.tableView(tableView, heightForRowAt: indexPath)
}

네, 저도 지금 같은 문제로 어려움을 겪고 있지만, 분명히 가능합니다.저는 세포들을 숨기는데 성공했고 모든 것이 잘 작동하지만, 현재 저는 그것을 깔끔하게 애니메이션으로 만들 수 없습니다.제가 찾은 것은 다음과 같습니다.

첫 번째 섹션의 첫 번째 행에 있는 ON/OFF 스위치 상태를 기준으로 행을 숨기고 있습니다.스위치가 ON이면 스위치 아래에 동일한 섹션에 1개의 행이 있고, 그렇지 않으면 2개의 다른 행이 있습니다.

스위치를 켜면 셀렉터가 호출되고 변수를 설정하여 상태를 표시합니다.그럼 전화할게요

[[self tableView] reloadData];

테이블View:willDisplayCell:forRowAtIndexPath:forRowAtIndexPath:function을 재정의하고 셀이 숨겨져야 하는 경우 다음 작업을 수행합니다.

[cell setHidden:YES];

셀과 셀 내용을 숨기지만 셀이 차지하는 공간은 제거되지 않습니다.

공백을 제거하려면 테이블View:heightForRowAtIndexPath: 함수를 재정의하고 숨겨야 하는 행에 대해 0을 반환합니다.

또한 tableView:numberOfRowsInSection:을(를) 재정의하고 해당 섹션의 행 수를 반환해야 합니다.테이블이 그룹화된 스타일이면 올바른 셀에서 둥근 모서리가 발생하도록 여기서 이상한 작업을 수행해야 합니다.정적 테이블에는 섹션에 대한 전체 셀 세트가 있으므로 옵션이 포함된 첫 번째 셀, ON 상태 옵션에 대한 셀 1개, OFF 상태 옵션에 대한 셀 2개, 총 4개의 셀이 있습니다.옵션이 ON이면 4를 반환해야 합니다. 여기에는 숨겨진 옵션이 포함되어 마지막으로 표시되는 옵션에 둥근 상자가 표시됩니다.옵션이 꺼져 있으면 마지막 두 옵션이 표시되지 않으므로 2를 반환합니다.이 모든 것이 투박하게 느껴집니다.설명하기가 까다롭고 명확하지 않다면 죄송합니다.설정을 설명하기 위해 IB의 표 섹션 구성을 다음과 같이 구성은 다음과 같습니다.

  • 0행: ON/OFF 스위치가 있는 옵션
  • 1행: 옵션이 ON일 때 표시됩니다.
  • 2행: 옵션이 OFF일 때 표시됩니다.
  • 3행: 옵션이 OFF일 때 표시됩니다.

따라서 옵션이 ON인 경우 테이블은 다음과 같은 두 행을 보고합니다.

  • 0행: ON/OFF 스위치가 있는 옵션
  • 1행: 옵션이 ON일 때 표시됩니다.

옵션이 OFF인 경우 테이블은 다음과 같은 4개 행을 보고합니다.

  • 0행: ON/OFF 스위치가 있는 옵션
  • 1행: 옵션이 ON일 때 표시됩니다.
  • 2행: 옵션이 OFF일 때 표시됩니다.
  • 3행: 옵션이 OFF일 때 표시됩니다.

이 접근법은 몇 가지 이유로 정확하게 느껴지지 않습니다. 제가 지금까지 실험한 것과 똑같으니 더 좋은 방법을 찾으시면 알려주시기 바랍니다.제가 지금까지 관찰한 문제는 다음과 같습니다.

  • 테이블에 행 수가 기본 데이터에 포함되어 있는 것과 다르다는 것을 알려주는 것은 잘못된 것 같습니다.

  • 저는 그 변화를 상상할 수 없는 것 같습니다.테이블뷰:reloadSections:withRowAnimation:reloadData 대신 사용해봤는데 결과가 의미가 없는 것 같습니다.현재는 테이블 보기가 올바른 행을 업데이트하지 않으므로 표시해야 할 행은 숨겨두고 첫 번째 행 아래에는 공백이 남아 있습니다.저는 이것이 기본 데이터에 대한 첫 번째 요점과 관련이 있을 수 있다고 생각합니다.

누군가가 다른 방법이나 애니메이션으로 확장하는 방법을 제안할 수 있기를 바라지만, 아마도 이것이 여러분을 시작하게 할 것입니다.기능에 대한 하이퍼링크가 부족해서 죄송합니다, 제가 기능을 넣었는데 제가 꽤 새로운 사용자이기 때문에 스팸 필터에 의해 거부되었습니다.

좋아요, 시도해 본 결과, 흔하지 않은 답이 있습니다."isHidden" 또는 "hidden" 변수를 사용하여 이 셀이 숨겨져야 하는지 확인하고 있습니다.

  1. 보기 컨트롤러에 대한 IO 게시판을 만듭니다. @IBOutlet weak var myCell: UITableViewCell!

  2. myCell사용자 정의 함수의 예에서는 viewDidLoad에 추가할 수 있습니다.

override func viewDidLoad() { super.viewDidLoad() self.myCell.isHidden = true }

  1. 대리인 방법으로:

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { let cell = super.tableView(tableView, cellForRowAt: indexPath) guard !cell.isHidden else { return 0 } return super.tableView(tableView, heightForRowAt: indexPath) }

이렇게 하면 위임 방법에 대한 논리가 줄어들고 비즈니스 요구 사항에만 집중하면 됩니다.

간단한 iOS 11 & IB/Storyboard 호환 방법

iOS 11의 경우, 모하메드 살레의 답변의 수정된 버전이 가장 효과적이며, 애플의 문서를 기반으로 일부 개선되었습니다.애니메이션을 잘 만들고, 추한 해킹이나 하드코드된 값을 피하고, 인터페이스 빌더에 이미 설정된 행 높이를 사용합니다.

기본 개념은 숨겨진 행에 대해 행 높이를 0으로 설정하는 것입니다.그런 다음 를 사용하여 일관되게 작동하는 애니메이션을 트리거합니다.

셀 높이 설정

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    if indexPath == indexPathOfHiddenCell {
        if cellIsHidden {
            return 0
        }
    }
    // Calling super will use the height set in your storyboard, avoiding hardcoded values
    return super.tableView(tableView, heightForRowAt: indexPath)
}

당신은 확인하고 싶을 것입니다.cellIsHidden그리고.indexPathOfHiddenCell사용 사례에 적합하게 설정되어 있습니다.내 코드의 경우 테이블 뷰 컨트롤러의 속성입니다.

셀 전환

어떤 방법으로든 가시성을 제어합니다(버튼 동작 또는didSelectRow state,, cellIsHidden을 .performBatchUpdates슬라이드:

tableView.performBatchUpdates({
                // Use self to capture for block
                self.cellIsHidden = !self.cellIsHidden 
            }, completion: nil)

Apple은 가능할 때마다 endUpdates권장합니다.

셀을 숨기거나 표시하거나 행 높이를 변경하거나 자동 레이아웃 제약 조건을 엉망으로 만드는 위의 답변은 자동 레이아웃 문제로 인해 저에게 적용되지 않았습니다.그 코드는 참을 수 없게 되었습니다.

단순한 정적 테이블의 경우, 저에게 가장 적합한 것은 다음과 같습니다.

  1. 정적 테이블의 모든 셀에 대한 배출구 만들기
  2. 표시할 셀의 출구로만 배열 만들기
  3. 셀ForRowAt 재지정배열에서 셀을 반환하는 IndexPath
  4. 배열 수를 반환하려면 섹션의 행 수를 재정의합니다.
  5. 해당 배열에 있어야 할 셀을 결정하는 메소드를 구현하고 필요할 때마다 메소드를 호출한 다음 데이터를 다시 로드합니다.

다음은 테이블 뷰 컨트롤러의 예입니다.

@IBOutlet weak var titleCell: UITableViewCell!
@IBOutlet weak var nagCell: UITableViewCell!
@IBOutlet weak var categoryCell: UITableViewCell!

var cellsToShow: [UITableViewCell] = []

override func viewDidLoad() {
    super.viewDidLoad()
    determinCellsToShow()
}

func determinCellsToShow() {
    if detail!.duration.type != nil {
        cellsToShow = [titleCell, nagCell, categoryCell]
    }
    else {
        cellsToShow = [titleCell,  categoryCell]
    }
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    return cellsToShow[indexPath.row]
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return cellsToShow.count
}

정적인 표에서 동물의 은닉 세포에 대한 해결책을 찾았습니다.

// Class for wrapping Objective-C block
typedef BOOL (^HidableCellVisibilityFunctor)();
@interface BlockExecutor : NSObject
@property (strong,nonatomic) HidableCellVisibilityFunctor block;
+ (BlockExecutor*)executorWithBlock:(HidableCellVisibilityFunctor)block;
@end
@implementation BlockExecutor
@synthesize block = _block;
+ (BlockExecutor*)executorWithBlock:(HidableCellVisibilityFunctor)block
{
    BlockExecutor * executor = [[BlockExecutor alloc] init];
    executor.block = block;
    return executor;
}
@end

사전 하나만 추가하면 됩니다.

@interface MyTableViewController ()
@property (nonatomic) NSMutableDictionary * hidableCellsDict;
@property (weak, nonatomic) IBOutlet UISwitch * birthdaySwitch;
@end

MyTableView 컨트롤러의 구현을 살펴보십시오.indexPath를 표시 가능한 인덱스와 보이지 않는 인덱스 간에 변환하려면 두 가지 방법이 필요합니다.

- (NSIndexPath*)recoverIndexPath:(NSIndexPath *)indexPath
{
    int rowDelta = 0;
    for (NSIndexPath * ip in [[self.hidableCellsDict allKeys] sortedArrayUsingSelector:@selector(compare:)])
    {
        BlockExecutor * executor = [self.hidableCellsDict objectForKey:ip];
        if (ip.section == indexPath.section
            && ip.row <= indexPath.row + rowDelta
            && !executor.block())
        {
            rowDelta++;
        }
    }
    return [NSIndexPath indexPathForRow:indexPath.row+rowDelta inSection:indexPath.section];
}

- (NSIndexPath*)mapToNewIndexPath:(NSIndexPath *)indexPath
{
    int rowDelta = 0;
    for (NSIndexPath * ip in [[self.hidableCellsDict allKeys] sortedArrayUsingSelector:@selector(compare:)])
    {
        BlockExecutor * executor = [self.hidableCellsDict objectForKey:ip];
        if (ip.section == indexPath.section
            && ip.row < indexPath.row - rowDelta
            && !executor.block())
        {
            rowDelta++;
        }
    }
    return [NSIndexPath indexPathForRow:indexPath.row-rowDelta inSection:indexPath.section];
}

UIS 스위치 값 변경 시 IBA 조치 1회:

- (IBAction)birthdaySwitchChanged:(id)sender
{
    NSIndexPath * indexPath = [self mapToNewIndexPath:[NSIndexPath indexPathForRow:1 inSection:1]];
    if (self.birthdaySwitch.on)
        [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
    else
        [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
}

일부 UITableViewDataSource 및 UITableViewDelegate 메서드는 다음과 같습니다.

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    int numberOfRows = [super tableView:tableView numberOfRowsInSection:section];
    for (NSIndexPath * indexPath in [self.hidableCellsDict allKeys])
        if (indexPath.section == section)
        {
            BlockExecutor * executor = [self.hidableCellsDict objectForKey:indexPath];
            numberOfRows -= (executor.block()?0:1);
        }
    return numberOfRows;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    indexPath = [self recoverIndexPath:indexPath];
    return [super tableView:tableView cellForRowAtIndexPath:indexPath];
}

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    indexPath = [self recoverIndexPath:indexPath];
    return [super tableView:tableView heightForRowAtIndexPath:indexPath];
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    // initializing dictionary
    self.hidableCellsDict = [NSMutableDictionary dictionary];
    [self.hidableCellsDict setObject:[BlockExecutor executorWithBlock:^(){return self.birthdaySwitch.on;}] forKey:[NSIndexPath indexPathForRow:1 inSection:1]];
}

- (void)viewDidUnload
{
    [self setBirthdaySwitch:nil];
    [super viewDidUnload];
}

@end

신속한 답변:

TableView 컨트롤러에 다음 방법을 추가합니다.

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return indexPathOfCellYouWantToHide == indexPath ? 0 : super.tableView(tableView, heightForRowAtIndexPath: indexPath)
}

테이블 뷰가 숨기려는 셀을 그리려고 하면 위의 방법으로 높이가 0pt로 설정되므로 테이블 뷰에 표시되지 않습니다. 다른 모든 항목은 변경되지 않습니다.

로 참로입니다.indexPathOfCellYouWantToHide할 수 있습니다 :)

> Swift 2.2에서, 저는 여기에 몇 가지 답변을 결합했습니다.

스토리보드에서 콘센트를 만들어 정적 셀에 연결합니다.

@IBOutlet weak var updateStaticCell: UITableViewCell!

override func viewDidLoad() {
    ...
    updateStaticCell.hidden = true
}

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    if indexPath.row == 0 {
        return 0
    } else {
        return super.tableView(tableView, heightForRowAtIndexPath: indexPath)
    }
}

첫 번째 셀을 숨기려고 위에서 설명한 대로 높이를 0으로 설정합니다.

@Saleh Masum 솔루션 외에도 다음이 있습니다.

자동 레이아웃 오류가 발생하는 경우 다음에서 제약 조건을 제거할 수 있습니다.tableViewCell.contentView

스위프트 3:

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    let tableViewCell = super.tableView(tableView, cellForRowAt: indexPath)

    if tableViewCell.isHidden == true
    {
        tableViewCell.contentView.removeConstraints(tableViewCell.contentView.constraints)
        return 0
    }
    else{
        return super.tableView(tableView, heightForRowAt: indexPath)
    }

}

이 솔루션은 앱의 흐름에 따라 달라집니다.동일한 뷰 컨트롤러 인스턴스에서 셀을 표시/숨기기를 원하는 경우 제약 조건이 제거되므로 이 방법이 최선의 선택이 아닐 수 있습니다.

스위프트 4:

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    var height = super.tableView(tableView, heightForRowAt: indexPath)
    if (indexPath.row == HIDDENROW) {
        height = 0.0
    }
    return height
}

표 보기의 맨 아래에 있는 셀을 숨길 때 가장 쉬운 시나리오를 위해 표 보기의 내용을 조정할 수 있습니다.셀을 숨긴 후 삽입:

- (void)adjustBottomInsetForHiddenSections:(NSInteger)numberOfHiddenSections
{
    CGFloat bottomInset = numberOfHiddenSections * 44.0; // or any other 'magic number
    self.tableView.contentInset = UIEdgeInsetsMake(self.tableView.contentInset.top, self.tableView.contentInset.left, -bottomInset, self.tableView.contentInset.right);
}

https://github.com/k06a/ABStaticTableViewController 을 사용하여 이 작업을 수행하는 새로운 방법입니다.

NSIndexPath *ip = [NSIndexPath indexPathForRow:1 section:1];
[self deleteRowsAtIndexPaths:@[ip] withRowAnimation:UITableViewRowAnimationFade]

k06a의 솔루션(https://github.com/k06a/ABStaticTableViewController) 은 셀 머리글과 바닥글을 포함한 전체 섹션을 숨기기 때문에 더 좋습니다. 여기서 이 솔루션(https://github.com/peterpaulis/StaticDataTableViewController) 은 바닥글을 제외한 모든 항목을 숨기기 때문입니다.

편집

바닥글을 숨기려면 방금 해결책을 찾았습니다.StaticDataTableViewControllerStaticTableViewController.m 파일에서 복사해야 하는 내용은 다음과 같습니다.

- (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInteger)section {
    if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] == 0) {
        return nil;
    } else {
        return [super tableView:tableView titleForFooterInSection:section];
    }
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {

    CGFloat height = [super tableView:tableView heightForFooterInSection:section];

    if (self.originalTable == nil) {
        return height;
    }

    if (!self.hideSectionsWithHiddenRows) {
        return height;
    }

    OriginalSection * os = self.originalTable.sections[section];
    if ([os numberOfVissibleRows] == 0) {
       //return 0;
        return CGFLOAT_MIN;
    } else {
        return height;
    }

    //return 0;
    return CGFLOAT_MIN;
}

물론 할 수 있습니다.먼저 테이블로 돌아가기표시할 셀 수를 보고 호출합니다.super스토리보드에서 특정 셀을 가져와 테이블 보기로 되돌리기:

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return self.mode.numberOfCells()
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = super.tableView(tableView, cellForRowAtIndexPath: self.mode.indexPathForIndexPath(indexPath))

    return cell
}

셀 높이가 다른 경우에도 반환합니다.

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return super.tableView(tableView, heightForRowAtIndexPath: self.mode.indexPathForIndexPath(indexPath))
}

정적 셀과 섹션을 해킹 없이 동적으로 숨길 수 있는 더 나은 방법이 있습니다.

행 높이를 0으로 설정하면 행을 숨길 수 있지만 모든 행을 숨기더라도 일부 공간을 포함하는 전체 섹션을 숨기려는 경우에는 해당되지 않습니다.

제 접근 방식은 정적 셀의 섹션 배열을 만드는 것입니다.그런 다음 테이블 뷰 내용은 섹션 배열에 의해 구동됩니다.

다음은 몇 가지 샘플 코드입니다.

var tableSections = [[UITableViewCell]]()

private func configTableSections() {
    // seciton A
    tableSections.append([self.cell1InSectionA, self.cell2InSectionA])

    // section B
    if shouldShowSectionB {
        tableSections.append([self.cell1InSectionB, self.cell2InSectionB])
    }

    // section C
    if shouldShowCell1InSectionC {
        tableSections.append([self.cell1InSectionC, self.cell2InSectionC, self.cell3InSectionC])
    } else {
        tableSections.append([self.cell2InSectionC, self.cell3InSectionC])
    }
}

func numberOfSections(in tableView: UITableView) -> Int {
    return tableSections.count
}

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return tableSections[section].count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    return tableSections[indexPath.section][indexPath.row]
}

이렇게 하면 행과 섹션 수를 계산하기 위해 악성 코드를 작성할 필요 없이 모든 구성 코드를 하나로 묶을 수 있습니다.그리고 물론, 아닙니다.0더 이상의 높이.

이 코드는 또한 유지보수가 매우 쉽습니다.예를 들어, 더 많은 셀 또는 섹션을 추가/제거하려는 경우.

마찬가지로 횡단 머리글 제목 배열과 횡단 바닥글 제목 배열을 작성하여 횡단 제목을 동적으로 구성할 수 있습니다.

언급URL : https://stackoverflow.com/questions/8260267/uitableview-set-to-static-cells-is-it-possible-to-hide-some-of-the-cells-progra

반응형