[ios] UITableView가 정적 셀로 설정되었습니다. 프로그래밍 방식으로 일부 셀을 숨길 수 있습니까?

UITableView 정적 셀로 설정합니다.

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



답변

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

StaticDataTableViewController 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.tableView reloadData]를 직접 호출하지 마십시오)

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


답변

UITable에서 정적 셀을 숨기려면

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

이 메소드는 UITable의 각 셀에 대해 호출됩니다. 숨기려는 셀을 호출하면 높이를 0으로 설정합니다. 콘센트를 만들어 대상 셀을 식별합니다.

  1. 디자이너에서 숨기려는 셀의 콘센트를 만듭니다. 이러한 셀 중 하나의 콘센트를 위의 “cellYouWantToHide”라고합니다.
  2. 숨길 셀에 대해서는 IB에서 “클립 서브 뷰”를 확인하십시오. 숨어있는 셀에는 ClipToBounds = YES가 있어야합니다. 그렇지 않으면 텍스트가 UITableView에 쌓입니다.

답변

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

인터페이스 빌더에서 정적 테이블 뷰를 정상적으로 설계하십시오. 잠재적으로 숨겨진 셀이 모두 있습니다. 그러나 숨길 수있는 모든 잠재적 인 셀에 대해 수행해야 할 한 가지가 있습니다. 셀의 “클립 하위 뷰”속성을 확인하십시오. 그렇지 않으면 셀을 숨기려고 할 때 셀의 내용이 사라지지 않습니다 (높이를 줄임으로써) – 더 늦게).

SO – 셀에 스위치가 있고 스위치는 일부 정적 셀을 숨기고 표시해야합니다. IBAction에 연결하고 다음을 수행하십시오.

[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와 비슷한 방향으로 진행되지만 몇 가지 작업은 다르게 수행합니다.

간다 :

1. 세포를 숨기십시오

셀을 직접 숨길 수는 없습니다. 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, section 및 row를 오프셋해야합니다.

또한 다음과 같은 메소드의 indexPath 매개 변수는 didSelectRowAtIndexPath: 같은 셀에 대해 같은 상태 (즉, 숨겨진 셀 수)에 따라 다를 수 있습니다. 따라서 항상 indexPath 매개 변수를 오프셋하고이 값으로 작업하는 것이 좋습니다.

2. 변화를 애니메이션

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 () 에서이 작업을 수행하십시오.

cellOneOutlet.hidden = true

이제 아래 방법을 재정의하고 어떤 셀 상태가 숨겨져 있는지 확인하고 해당 셀의 높이 0을 반환하십시오. 이것은 정적 tableView의 모든 셀을 신속하게 숨길 수있는 많은 방법 중 하나입니다.

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;

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

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

그런 다음 숨길 특정 행이있는 경우 numberOfRowsInSection 및 cellForRowAtIndexPath에 리턴되는 행을 조정할 수 있습니다. 이 예에는 3 개의 행이 있으며 3 개가 비어 있고 제거 해야하는 섹션이 있습니다.

- (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를 계산하려면이 offsetIndexPath를 사용하십시오. 섹션 만 숨기는 경우 필요하지 않습니다

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

재정의 할 방법이 많이 있지만이 방법에 대해 내가 좋아하는 것은 재사용 할 수 있다는 것입니다. hiddenSections 배열을 설정하고 추가하면 올바른 섹션이 숨겨집니다. 행을 숨기는 것은 조금 까다 롭지 만 가능합니다. 테두리가 올바르게 그려지지 않기 때문에 그룹화 된 UITableView를 사용하는 경우 숨기려는 행의 높이를 0으로 설정할 수 없습니다.


답변

정적 UITableView에서 애니메이션을 사용하여 셀을 숨기거나 표시 할 수 있습니다. 그리고 그렇게 어렵지 않습니다.

데모 프로젝트

데모 프로젝트 비디오

요점:

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

내 블로그에 추가 정보 (러시아어)