2013-08-14 2 views
1

Apple docs에서 cellForRowAtIndexPath가 순서대로 지정하지 않는다는 것을 알고 있습니다. 즉, 먼저 Section 0, Index 0; 그렇다면 Section 0, Index 2; 그리고 나서 Section 1, Index 0 .... 등등. 나는 그것이 주위에 뛰어 오른다라고 생각한다.iOS : UITableViewController - cellForRowAtIndexPath 셀 생성

아래에서 더 좋은 방법은 무엇입니까? 현재 나는 오류가 계속

NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 3 beyond bounds [0 .. 2]' 
오류가 나타납니다

B 나는 cellForRowAtIndexPath 주위 점프 생각 마크 *sectioned = NULL, 그래서 조건은 건너 뛰고은 빈 배열로 전환되거나 잘못된로 이동하여 인덱스 수를 초과하는 C/조건.

... declared and synthesized 
NSManaged *object; 
@property (strong, nonatomic) NSNumber *sevenDaysSectionFilled; 
@property (strong, nonatomic) NSNumber *fourteenDaysSectionFilled; 
@property (strong, nonatomic) NSNumber *thirtyDaysSectionFilled; 


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    object = NULL; 
    static NSString *CellIdentifier = @"Cell"; 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; 

    if (indexPath.section == 0) 
    { 
     if ((SevenDaysArraySectioned == [NSNumber numberWithBool:YES]) && (sevenDaysSectionFilled != [NSNumber numberWithBool:YES])) 
     { 
      object = [pastSevenDayArray objectAtIndex:indexPath.row]; 
      sevenDaysSectionFilled = [NSNumber numberWithBool:YES]; 
     } 

     else if ((fourteenDaysArraySectioned == [NSNumber numberWithBool:YES]) && (fourteenDaysSectionFilled != [NSNumber numberWithBool:YES])) 
     { 
      object = [pastFourteenDaysArray objectAtIndex:indexPath.row]; 
      fourteenDaysSectionFilled = [NSNumber numberWithBool:YES]; 
     } 

     else if ((thirtyDaysArraySectioned == [NSNumber numberWithBool:YES]) && (thirtyDaysSectionFilled != [NSNumber numberWithBool:YES])) 
     { 
      object = [pastThirtyDaysArray objectAtIndex:indexPath.row]; 
      thirtyDaysSectionFilled = [NSNumber numberWithBool:YES]; 
     } 

    else if (indexPath.section == 1) 
    { 
     if ((fourteenDaysArraySectioned == [NSNumber numberWithBool:YES]) && (fourteenDaysSectionFilled != [NSNumber numberWithBool:YES])) 
     { 
      object = [pastFourteenDaysArray objectAtIndex:indexPath.row]; 
      fourteenDaysSectionFilled = [NSNumber numberWithBool:YES]; 
     } 

     else if ((thirtyDaysArraySectioned == [NSNumber numberWithBool:YES]) && (thirtyDaysSectionFilled != [NSNumber numberWithBool:YES])) 
     { 
      object = [pastThirtyDaysArray objectAtIndex:indexPath.row]; 
      thirtyDaysSectionFilled = [NSNumber numberWithBool:YES]; 
     } 

    else if (indexPath.section == 2) 
    { 
     if ((thirtyDaysArraySectioned == [NSNumber numberWithBool:YES]) && (thirtyDaysSectionFilled != [NSNumber numberWithBool:YES])) 
     { 
      object = [pastThirtyDaysArray objectAtIndex:indexPath.row]; 
      thirtyDaysSectionFilled = [NSNumber numberWithBool:YES]; 
     } 
    } 

NSString *entityName = [[object entity]name]; 
cell.textLabel.text = [NSString stringWithFormat:@"%@ %i", entityName, [indexPath row]]; 

    object = NULL; 
    return cell; 
} 

는 이러한 목표를 달성하기 위해 더 나은 방법이 있으면 알려 주시기 바랍니다 : 여기에

는 코드입니다. 감사.

* 편집

이 조금 복잡하지만 여기있다 :

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    numberOfSections = 0; 

    if ([pastSevenDayArray count] > 0) numberOfSections++; 
    if ([pastFourteenDaysArray count] > 0) numberOfSections++; 
    if ([pastThirtyDaysArray count] > 0) numberOfSections++; 
    if ([pastSixtyDaysArray count] > 0) numberOfSections++; 
    if ([pastNinteyDaysArray count] > 0) numberOfSections++; 
    if ([pastArray count] > 0) numberOfSections++; 

    [self numberOfCells]; 


    return numberOfSections; 
} 

numberOfCells

-(void)numberOfCells 
{ 
    for (int section = 0; section<numberOfSections; section ++) 
    { 
     if (section == 0) 
     { 
      if ([pastSevenDayArray count] > 0) 
      { 
       SevenDaysArraySectioned = [NSNumber numberWithBool:YES]; 
       sectionZeroCellCount = [pastSevenDayArray count]; 
       sectionZeroHeader = sevenDaysSectionLabel; 
      } 
      else if ([pastFourteenDaysArray count] > 0) 
      { 
       fourteenDaysArraySectioned = [NSNumber numberWithBool:YES]; 
       sectionZeroCellCount = [pastFourteenDaysArray count]; 
       sectionZeroHeader = fourteenDaysSectionLabel; 
      } 
      else if ([pastThirtyDaysArray count] > 0) 
      { 
       thirtyDaysArraySectioned = [NSNumber numberWithBool:YES]; 
       sectionZeroCellCount = [pastThirtyDaysArray count]; 
       sectionZeroHeader = thirtyDaysSectionLabel; 
      } 
      else if ([pastSixtyDaysArray count] > 0) 
      { 
       sixtyDaysArraySectioned = [NSNumber numberWithBool:YES]; 
       sectionZeroCellCount = [pastSixtyDaysArray count]; 
       sectionZeroHeader = sixtyDaysSectionLabel; 

      } 
      else if ([pastNinteyDaysArray count] > 0) 
      { 
       ninetyDaysArraySectioned = [NSNumber numberWithBool:YES]; 
       sectionZeroCellCount = [pastNinteyDaysArray count]; 
       sectionZeroHeader = ninetyDaysSectionLabel; 
      } 
      else if ([pastArray count] > 0) 
      { 
       pastArraySectioned = [NSNumber numberWithBool:YES]; 
       sectionZeroCellCount = [pastArray count]; 
       sectionZeroHeader = pastSectionLabel; 
      } 
     } 

     else if (section == 1) 
     {  
      if (([pastFourteenDaysArray count] > 0) && (fourteenDaysArraySectioned != [NSNumber numberWithBool:YES])) 

      { 
       fourteenDaysArraySectioned = [NSNumber numberWithBool:YES]; 
       sectionOneCellCount = [pastFourteenDaysArray count]; 
       sectionOneHeader = fourteenDaysSectionLabel; 
      } 
      else if (([pastThirtyDaysArray count] > 0) && (thirtyDaysArraySectioned != [NSNumber numberWithBool:YES])) 

      { 
       thirtyDaysArraySectioned = [NSNumber numberWithBool:YES]; 
       sectionOneCellCount = [pastThirtyDaysArray count]; 
       sectionOneHeader = thirtyDaysSectionLabel; 
      } 
      else if (([pastSixtyDaysArray count] > 0) && (sixtyDaysArraySectioned != [NSNumber numberWithBool:YES])) 
      { 
       sixtyDaysArraySectioned = [NSNumber numberWithBool:YES]; 
       sectionOneCellCount = [pastSixtyDaysArray count]; 
       sectionOneHeader = sixtyDaysSectionLabel; 
      } 
      else if (([pastNinteyDaysArray count] > 0) && (ninetyDaysArraySectioned != [NSNumber numberWithBool:YES])) 

      { 
       ninetyDaysArraySectioned = [NSNumber numberWithBool:YES]; 
       sectionOneCellCount = [pastNinteyDaysArray count]; 
       sectionOneHeader = ninetyDaysSectionLabel; 
      } 
      else if (([pastArray count] > 0) && (pastArraySectioned != [NSNumber numberWithBool:YES])) 
      { 
       pastArraySectioned = [NSNumber numberWithBool:YES]; 
       sectionOneCellCount = [pastArray count]; 
       sectionOneHeader = pastSectionLabel; 
      } 
     } 
     else if (section ==2) 
     { 
      if (([pastThirtyDaysArray count] > 0) && (thirtyDaysArraySectioned != [NSNumber numberWithBool:YES])) 

      { 
       thirtyDaysArraySectioned = [NSNumber numberWithBool:YES]; 
       sectionTwoCellCount = [pastThirtyDaysArray count]; 
       sectionTwoHeader = thirtyDaysSectionLabel; 
      } 
      else if (([pastSixtyDaysArray count] > 0) && (sixtyDaysArraySectioned != [NSNumber numberWithBool:YES])) 
      { 
       sixtyDaysArraySectioned = [NSNumber numberWithBool:YES]; 
       sectionTwoCellCount = [pastSixtyDaysArray count]; 
       sectionTwoHeader = sixtyDaysSectionLabel; 
      } 
      else if (([pastNinteyDaysArray count] > 0) && (ninetyDaysArraySectioned != [NSNumber numberWithBool:YES])) 

      { 
       ninetyDaysArraySectioned = [NSNumber numberWithBool:YES]; 
       sectionTwoCellCount = [pastNinteyDaysArray count]; 
       sectionTwoHeader = ninetyDaysSectionLabel; 
      } 
      else if (([pastArray count] > 0) && (pastArraySectioned != [NSNumber numberWithBool:YES])) 
      { 
       pastArraySectioned = [NSNumber numberWithBool:YES]; 
       sectionTwoCellCount = [pastArray count]; 
       sectionTwoHeader = pastSectionLabel; 
      } 
     } 
     else if (section ==3) 

     { 
      NSLog(@"Entered Section %i", section); 

      if (([pastSixtyDaysArray count] > 0) && (sixtyDaysArraySectioned != [NSNumber numberWithBool:YES]))   { 
       sixtyDaysArraySectioned = [NSNumber numberWithBool:YES]; 
       sectionThreeCellCount = [pastSixtyDaysArray count]; 
       sectionThreeHeader = sixtyDaysSectionLabel; 
      } 
      else if (([pastNinteyDaysArray count] > 0) && (ninetyDaysArraySectioned != [NSNumber numberWithBool:YES])) 
      { 
       ninetyDaysArraySectioned = [NSNumber numberWithBool:YES]; 
       sectionThreeCellCount = [pastNinteyDaysArray count]; 
       sectionThreeHeader = ninetyDaysSectionLabel;   
      } 
      else if (([pastArray count] > 0) && (pastArraySectioned != [NSNumber numberWithBool:YES])) 
      { 
       pastArraySectioned = [NSNumber numberWithBool:YES]; 
       sectionThreeCellCount = [pastArray count]; 
       sectionThreeHeader = pastSectionLabel; 
      } 
     } 
     else if (section ==4) 
     { 
      NSLog(@"Entered Section %i", section); 

      if (([pastNinteyDaysArray count] > 0) && (ninetyDaysArraySectioned != [NSNumber numberWithBool:YES])) 
      { 
       ninetyDaysArraySectioned = [NSNumber numberWithBool:YES]; 
       sectionFourCellCount = [pastNinteyDaysArray count]; 
       sectionFourHeader = ninetyDaysSectionLabel; 
      } 
      else if (([pastArray count] > 0) && (pastArraySectioned != [NSNumber numberWithBool:YES])) 
      { 
       pastArraySectioned = [NSNumber numberWithBool:YES]; 
       sectionFourCellCount = [pastArray count]; 
       sectionFourHeader = pastSectionLabel; 
      } 
     } 

     else if (section ==5) 
     { 
      NSLog(@"Entered Section %i", section); 

      if (([pastArray count] > 0) && (pastArraySectioned != [NSNumber numberWithBool:YES])) 
      { 
       pastArraySectioned = [NSNumber numberWithBool:YES]; 
       sectionFiveCellCount = [pastArray count]; 
       sectionFiveHeader = pastSectionLabel; 
      } 
     } 

    } 

} 

numberOfRowsInSection

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 

    if (section == 0) 
    { 
     return sectionZeroCellCount; 
    } 

    else if (section == 1) 
    { 
     return sectionOneCellCount; 
    } 
    else if (section == 2) 
    { 
     return sectionTwoCellCount; 
    } 
    else if (section == 3) 
    { 
     return sectionThreeCellCount; 
    } 
    else if (section == 4) 
    { 
     return sectionFourCellCount; 
    } 
    if (section == 5) 
    { 
     return sectionFiveCellCount; 
    } 
} 
,536,913 63,210

편집 2

헤더 :

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 
{ 
    return 30.0; 
} 

- (UIView *) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 
{ 
    UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, 150)]; 
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 3, tableView.bounds.size.width - 10, 25)]; 
    label.backgroundColor = [UIColor clearColor]; 
    [label setFont:[UIFont boldSystemFontOfSize:16]]; 
    label.textColor = [UIColor whiteColor]; 

    if (section == 0) 
    { 
     label.text = sectionZeroHeader; 
    } 
    else if (section == 1) 
    { 
     label.text = sectionOneHeader; 
    } 

    else if (section == 2) 
    { 
     label.text = sectionTwoHeader; 
    } 
    else if (section == 3) 
    { 
     label.text = sectionThreeHeader; 
    } 
    else if (section == 4) 
    { 
     label.text = sectionFourHeader; 
    } 
    else if (section == 5) 
    { 
     label.text = sectionFiveHeader; 
    }  

    [headerView addSubview:label]; 
    return headerView; 
} 
+0

나는 당신의 논리가 올바르지 않을 수 있습니다 각 섹션에 대한 행의 수를 반환 할 생각은 단지 세 가지 요소를 포함 –

+0

나는 그것을 확인한 배열로 tableviews 섹션 중 하나에 네 개의 행을 채우기 위해 시도하는 것 같은데 너무 여러 번. numberOfRowsInSection : cellForRowAtIndexPath의 올바른 셀과 일치하는 경우 올바른 값입니다. – user1107173

+0

왜 sectioned = NULL을하고 있습니까? –

답변

1

다양한 상태 변수가 유지 될 필요는 없습니다. 콜렉션 및 기타 데이터 구조를 사용하여 테이블이 어떻게 구성되는지에 대한 정의를 작성한 다음 데이터 소스/위임 메소드의 참조를 참조 할 수 있습니다.

이보기 컨트롤러의 기본 개념은 각 섹션이 해당 섹션에 대한 행 데이터와 헤더보기와 같은 섹션 별 정보가 포함 된 CVSectionModel 개체로 표시된다는 것입니다. 내부에 viewDidLoad이 섹션 모델을 빌드하고 데이터 업데이트를 마칠 때마다 다시 빌드해야합니다. 다양한 데이터 작업을 시도하려면 다른 테스트 방법 중 하나를 사용하여 viewDidLoad의 전화 번호를 testCase1으로 바꿉니다.

섹션 모델의 배열을 유지 관리하고 섹션에 모델을 생성하는 경우에만 섹션에 대한 모델을 생성합니다. 알 수 있듯이, 각 행에서 행 정보를 가져올 배열과 각 행의 행 수를 단순화합니다.여러 다른 인스턴스 변수를 동기화하는 대신 섹션 모델에 수행 할 작업을 간단하게 물어 봅니다.

이 테이블 컨트롤러는 내용 삽입, 삭제 또는 순서 재 지정의보다 정교한 애니메이션을 지원하지 않으므로 필요한 경우 추가 작업이 필요합니다. 하지만 viewDidLoad 후 10 초 동안 실행되는 블록에서 볼 수 있듯이 업데이트 후 일반 테이블 재로드를 지원합니다.

코드를 검토하고 질문하십시오. 이것은 구현 파일이지만 @interface CVViewController: UIViewController @end을 제외한 헤더에는 아무 것도 없습니다.

@interface CVSectionModel : NSObject 

@property (nonatomic) NSArray *rowModels; 
@property (nonatomic) NSString *sectionTitle; 
@property (nonatomic) NSInteger tag; // possibly useful for animations, different behavior on section, etc. 

@end 

@implementation CVSectionModel 

@end 


@interface CVViewController() <UITableViewDataSource, UITableViewDelegate> 

@property (weak, nonatomic) IBOutlet UITableView *tableView; 

@property (nonatomic) NSArray *sectionModels; 

@property (nonatomic) NSArray *sevenDays; 
@property (nonatomic) NSArray *fourteenDays; 
@property (nonatomic) NSArray *thirtyDays; 

@end 

@implementation CVViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

    // In your application, you'll be loading and processing your real data 
    // But here I'm just going to simulate a number of cases with strings for illustration 
    // Call the other methods to try different configurations 
    [self testCase1]; 

    // We call this once on viewDidLoad. You'll also want to call it whenever you update the underlying data, as in the block below 
    [self processSectionData]; 

    [self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"IDENTIFIER"]; 

    // Demonstrate support for modifying the underlying data and refresh the view. 
    // Uncomment to test it. 
// double delayInSeconds = 10.0; 
// dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); 
// dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ 
//  [self testCase2]; 
//  [self processSectionData]; 
//  [self.tableView reloadData]; 
// }); 
} 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{ 
    return [self.sectionModels count]; 
} 

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section 
{ 
    return [((CVSectionModel *)self.sectionModels[section]).rowModels count]; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"IDENTIFIER"]; 
    // In your app this appears to be an NSManagedObject of some type, here it's just a string 
    NSString *modelForRow = ((CVSectionModel *)self.sectionModels[indexPath.section]).rowModels[indexPath.row]; 
    cell.textLabel.text = modelForRow; 
    return cell; 
} 

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section 
{ 
    return 30.0; 
} 

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section 
{ 
    NSString *sectionTitle = ((CVSectionModel *)self.sectionModels[section]).sectionTitle; 
    UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.bounds.size.width, 150)]; 
    UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(10, 3, tableView.bounds.size.width - 10, 25)]; 
    label.backgroundColor = [UIColor clearColor]; 
    [label setFont:[UIFont boldSystemFontOfSize:16]]; 
    label.textColor = [UIColor whiteColor]; 
    label.text = sectionTitle; 
    [headerView addSubview:label]; 
    return headerView; 
} 

- (void)processSectionData 
{ 
    NSArray *allDayArrays = @[self.sevenDays, self.fourteenDays, self.thirtyDays]; 
    // You won't use hard-coded strings here - use your sevenDaysSectionLabel, etc. variables instead 
    NSArray *labelTitles = @[@"7 days", @"14 days", @"30 days"]; 
    NSMutableArray *mutableSectionModels = [NSMutableArray array]; 

    [allDayArrays enumerateObjectsUsingBlock:^(NSArray *array, NSUInteger index, BOOL *stop) { 
     if ([array count] > 0) { 
      CVSectionModel *sectionModel = [[CVSectionModel alloc] init]; 
      sectionModel.rowModels = array; 
      sectionModel.sectionTitle = labelTitles[index]; 
      sectionModel.tag = index+1; // track this to enable re-ordering in the future 
      [mutableSectionModels addObject:sectionModel]; 
     } 
    }]; 

    // If Animating insertions/deletions will require something more elaborate 
    self.sectionModels = [mutableSectionModels copy]; 
} 

// Case 1: 
// All three populated 
- (void)testCase1 
{ 
    self.sevenDays = @[@"sevendayitem1", @"sevendayitem2", @"sevendayitem3", @"sevendayitem4"]; 
    self.fourteenDays = @[@"14day item 1", @"14 day item 2"]; 
    self.thirtyDays = @[@"30 day item 1", @"30 day item 2", @"30 day item 3"]; 
} 

// Case 2: 
// self.fourteenDays is empty 
- (void)testCase2 
{ 
    self.sevenDays = @[@"sevendayitem1", @"sevendayitem2", @"sevendayitem3", @"sevendayitem4"]; 
    self.fourteenDays = @[]; 
    self.thirtyDays = @[@"30 day item 1", @"30 day item 2", @"30 day item 3"]; 
} 

// Case 3: 
// self.thirtydays is the only one 
- (void)testCase3 
{ 
    self.sevenDays = @[]; 
    self.fourteenDays = @[]; 
    self.thirtyDays = @[@"30 day item 1", @"30 day item 2", @"30 day item 3"]; 
} 

@end 
+0

자세한 답장을 보내 주셔서 감사합니다. 나는 이것을 AM에서 다시보고 너에게로 돌아갈 것이다. 간략하게 살펴보면, SevenDays, FourteenDays, ThirtyDays, SixtyDays, NinetyDays 및 PastDaysArray의 세 배열 만 표시했습니다. 내 질문에 각 시나리오에 대한 사례가 필요합니까? 모든 가능한 testCase를 생각해 보는 것이 약간 번거롭지 않습니까? 다시 한 번 감사드립니다! – user1107173

+1

@ user1107173 여러분을 환영합니다. 아니요, 테스트 케이스를 가져올 필요가 없습니다. 순전히 일러스트레이션을 위해 제 코드에 있습니다! 실제 데이터가 없기 때문에이 예제를 보여주고 싶었 기 때문입니다. 테스트 케이스에 대해 걱정하지 마십시오. 7Days, 14Days 등을 평소와 같이 업데이트하고, 각각과 함께'allDayArrays'를 생성 할 것입니다. 그래서'processSectionData' 메쏘드에서'allDayArrays = @ [sevenDays, fourteenDays, 30Days, 60Days, 90Days, past];와 같은 것을 갖게 될 것입니다. 분명하니? –

+0

초 만에 채팅 할 수 있습니까? – user1107173

1

나는 당신이 설정되었는지 확인해야 생각 적절한

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section; 

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; 

당신이 갖고 싶어

다중 섹션과 각 섹션에서 많은 행의 탄원 NSDictionary를 사용하고 키 -> 배열 값을 설정하면

NSDictionary *dict = @{@"section1": @[@"obj1", @"obj2"],@"section2": @[@"obj3", @"obj4"]}; 
NSInteger numberOfSections = [[dict allKeys] count];// return in numberOfSections 
NSArray *values = [dict valueForKey:@"obj1"];// get appropriate array 
관련 문제