iOS 개발 TableView 간소화

6047 단어
번역,수정IO 텍스트 링크: Clean Table View Code

안내문


TableView는 iOS app에서 가장 자주 사용하는 컨트롤러로 많은 코드가 테이블 뷰 작업에 직접적이거나 간접적으로 관련되어 있다. 이는 데이터 제공, 테이블 뷰 업데이트, 테이블 뷰 행위 제어 등을 포함한다.다음은tableView 코드를 깔끔하고 명확하게 유지하는 방법을 제공할 것입니다.

UITableViewController vs. UIViewController


TableViewController의 특징


테이블 뷰 controllers는 테이블 뷰의 데이터를 읽을 수 있고 테이블 뷰의 편집 모드를 설정하고 키보드 알림에 반응할 수 있습니다.또한 Table view controller는 UIRefreshControl를 사용하여 드롭다운 새로 고침을 지원할 수 있습니다.

Child View Controllers


tableViewController는childview controller로 다른view Controller에 추가할 수 있습니다. 그리고 tableViewController는tableView를 계속 관리하고parentViewController는 우리가 관심을 가지는 다른 것들을 관리할 수 있습니다.
    -(void)addDetailTableView
    {
        DetailViewController *detail = [DetailViewController new];
        [detail setup];
        detail.delegate = self;
        [self addChildViewController:detail];
        [detail setupView];
        [self.view addSubview:detail.view];
        [detail didMoveToParentViewController:self];
    }

위 코드를 사용할 때childView controller와parent view controller 간의 연결을 설정해야 합니다.예를 들어, 만약 사용자가tableView의cell을 선택했다면,parentViewController는 클릭 시간에 응답할 수 있도록 이 사실을 알아야 한다.그래서 가장 좋은 방법은 테이블 뷰 컨트롤러가 프로토콜을 정의하고parent 뷰 컨트롤러가 이 프로토콜을 실현하는 것이다.
@protocol DetailViewControllerDelegate
-(void)didSelectCell;
@end

@interface ParentViewController () 
@end

@implementation ParentViewController
//....
-(void)didSelectCell
{
    //do something...
}
@end

이렇게 하면view controller 간의 빈번한 교류를 초래하지만, 이렇게 하면 코드의 낮은 결합과 복용성을 보장한다.

분산 코드


테이블뷰를 처리할 때 모델층, controller층,view층을 뛰어넘는 다양한 작업이 있습니다.따라서 이러한 서로 다른 코드를 분산시켜view Controller가 이런 문제들을 처리하는 '퇴적 구역'이 되는 것을 방지할 필요가 있다.가능한 한 이 코드들을 독립시키면 코드의 가독성을 더욱 높일 수 있고 유지보수성과 테스트성을 더욱 높일 수 있다.이 부분의 내용은 iOS 개발 간소화view controller를 참고할 수 있으며,tableView 이 장에서view와view Controller를 어떻게 분리하는지에 전념할 것이다

ModelObeject와 Cell 사이의 간격을 없애다


많은 상황에서 우리는view층에 보여주고 싶은 데이터를 제출해야 하고 우리도view층과 모델층의 분리를 유지해야 하기 때문에tableView의dateSource는 항상 초과 작업을 했다.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    Cell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
    [cell setup];
    NSString *text = self.title;
    cell.label.text = text;
    UIImage *photo = [UIImage imageWithName:text];
    cell.photoView.image = photo;
}

이렇게 dataSorce하면 매우 어지러워질 수 있으므로cell의category에 이 물건들을 나누어야 한다.
@implementation Cell (ConfigText)

-(void)configCellWithTitle:(NSString *)title
{
    self.label.text = title;
    UIImage *photo = [UIImage imageWithName:title];
    cell.photoView.image = photo;
    return cell;
}

이렇게 되면 dataSource 매우 간단해질 것이다.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    Cell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
    [cell configCellWithTitle:self.title];
    return cell;
}

재사용 cell


사실 더 나아가 같은 셀을 다양한 모델 Object를 보여줄 수 있도록 할 수 있다.우선cell에서 프로토콜을 정의해야 합니다. 이cell에서 보여주려는object는 이 프로토콜을 준수해야 합니다.그리고 분류config method를 수정하여object가 이 프로토콜을 준수하도록 할 수 있다.이렇게 하면cell은 서로 다른 데이터 형식에 적응할 수 있다.

cell에서 cell 상태 처리


선택한 후 하이라이트 상태를 변경하는 등 테이블 뷰의 동작을 설정하려면 테이블 뷰 Controller에서 위임 방법을 사용합니다.
-(void)tableView:(UITableView *)tableView didHighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
    Cell *cell = [tableView cellForRowAtIndexPath:indexPath];
    cell.label.shadowColor = [UIColor greenColor];
}

-(void)tableView:(UITableView *)tableView didUnhighlightRowAtIndexPath:(NSIndexPath *)indexPath
{
    Cell *cell = [tableView cellForRowAtIndexPath:indexPath];
    cell.label.shadowColor = nil;
}

그러나 이cell을 바꾸거나 다시 디자인하고 싶을 때 의뢰 방법에 적응해야 한다.cell 안의detail의 실현과 위탁 방법에서detail의 실현이 한데 얽혀 있기 때문에 이러한 논리를cell 안으로 옮겨야 한다.
@implementation Cell
//...
-(void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
{
    [super setHighlighted:highlighted animated:animated];
    if(highlighted)
    {
        self.label.shadowColor = [UIColor greenColor];
    }
    else
    {
        self.label.shadowColor = nil;
    }
}
@end

하나의 의뢰는view의 다른 상태를 알아야 하지만,view를 어떻게 수정하거나 어떤 속성을 설정해서 이view의 상태를 전환시켜야 하는지 알 필요가 없고, 모든 논리는view로 완성해야 하며, 외부에서는 API만 제공해야 한다.이것이야말로view층과controller층이 코드 간의 유효한 분리를 실현한다.

다른 cell 유형 처리


만약tableView에 서로 다른cell유형이 있다면 dataSource팽창하여 조작하기 어려워질 것이다. 아래 코드에는 두 가지의cell유형이 있는데 하나는 그림과 제목을 보여주고 다른 하나는 별표를 보여준다.서로 다른cell 코드를 분리 처리하기 위해dataSource 방법은 서로 다른cell 자체의 설정 방법만 실행할 뿐이다.
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    BOOL isStarRank = self.keys[(NSUInteger)indexPath.row];
    UITableViewCell *cell;
    if(isStarRank)
    {
        cell = [self setupStarCell];
    }
    else
    {
        cell = [self setupDefaultCell];
    }
}

-(StarCell *)setupStarCell
{
    //do something...
}

-(UITableViewCell *)setupDefaultCell
{
    //do something...
}

TableView 편집


TableView는 셀을 삭제하고 이동할 수 있는 편리한 편집 기능을 제공합니다.이러한 이벤트에서tableViewdataSource는 위탁 방법을 통해 알림을 받기 때문에 이러한 위탁 방법에서 데이터에 대한 수정이 자주 나타나고 수정 데이터는 모델층의 임무가 분명하다.모델은 삭제, 정렬 등의 인터페이스를 제공하여 dataSource 방법으로 호출할 수 있도록 해야 한다.따라서 controller는view와 모델 간의 조율자 역할을 하며 모델층의 실현 세부 사항을 알 필요가 없다.이 동시에 모델의 논리는view Controller의 작업이 혼합되지 않았기 때문에 더욱 쉽게 테스트할 수 있습니다.

총결산


tableView Controller 및 기타 controller는 모델과view의 조율자와 중개자 역할을 해야지view나 모델층에 속하는 임무에 관심을 가져서는 안 된다.이 점을 명심하여 의뢰와dataSource를 더욱 작게 하고 공식화된 코드만 포함하도록 한다.
이것은tableViewController의 부피와 복잡도를 줄일 뿐만 아니라 역 논리와 인터페이스 논리를 관련 클래스에 넣고 세부 사항을 간단한 API 인터페이스에 감싸서 최종적으로 코드의 가독성과 코드의 조화 능력을 향상시켰다.
더 많은 것을 알고 싶으면 나의 홈페이지를 보십시오

좋은 웹페이지 즐겨찾기