2013-01-31 3 views
16

Điều này có vẻ như là một vấn đề dễ dàng, nhưng tôi đã trúng một bức tường gạch ... Tìm kiếm đang làm cho một UITableView sử dụng UITableViewStyleGrouped, và tôi nhìn thấy một (1 pixel) dòng trắng nhỏ giữa hàng đầu tiên và thứ hai của mỗi phần của view bàn của tôi (xem hình)Khoảng cách 1 pixel giữa ô thứ nhất và ô thứ hai trong nhóm UITableView

example of gap

dường như lý do cho dòng này là ô đầu tiên trong mỗi phần cao hơn 1 pixel so với các phần khác. Khi tôi đặt ô ban đầu của mỗi nhóm là 29 pixel cao (những người khác là 30) khoảng cách biến mất và tất cả là tốt.

Trong khi giải pháp này là thành công, tôi muốn biết lý do cho điều này xảy ra vì vậy tôi có thể tránh sử dụng một hack lộn xộn.

FYI:

  • Tôi đã thực hiện chắc chắn đây không phải là một vấn đề với những hình ảnh nền Tôi có bằng cách sử dụng - họ là tất cả 30px cao, và tôi đã thay thế hình ảnh đầu với một hình ảnh trung với cùng kết quả.
  • Tôi đã gỡ bỏ tất cả các biên giới giữa các tế bào bằng cách thiết lập separatorStyle = UITableViewCellSeparatorStyleNone
  • Hiệu ứng này không xảy ra trên UITableViewStylePlain

Any help is appreciated rất nhiều.

Cảm ơn

Mã cho thiết lập bảng:

myTable = [[UITableView alloc] initWithFrame:CGRectMake(TABLE_SHIFT_OFFSET, 
                  DATE_SLIDER_HEIGHT - DATE_SLIDER_SHADOW_HEIGHT, 
                  326, 
                  self.view.frame.size.height - DATE_SLIDER_HEIGHT + DATE_SLIDER_SHADOW_HEIGHT) style:UITableViewStyleGrouped]; 
    myTable.backgroundColor = [UIColor clearColor]; 
    myTable.backgroundView = nil; 
    myTable.separatorStyle = UITableViewCellSeparatorStyleNone; 
    [self.view addSubview:myTable]; 
    myTable.dataSource = self; 
    myTable.delegate = self; 

Mã cho thiết lập tế bào:

- (float)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    // This is a hack to make sure that a white line doesnt appear between the 
    // first and second rows in the table, which happens for reasons I dont understand 
    if (indexPath.row == 0) { 
    return 29; 
    } 

    return 30; 
} 

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{  
    MyTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"satCell"]; 
    if (!cell) 
    { 
    cell = [[MyTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"satCell"]; 
    } 

    cell.backgroundView = nil; 
    cell.backgroundView = [[UIView alloc] initWithFrame:CGRectZero]; 

    cell.backgroundColor = [UIColor whiteColor]; 
    int numberOfRowsInThisSection = [self tableView:tableView numberOfRowsInSection:indexPath.section]; 

    if (numberOfRowsInThisSection == 1) 
    { 
    cell.backingImage = self.singleWhite; 
    } 
    else if (indexPath.row == 0) 
    { 
    cell.backingImage = self.topWhite; 
    } 
    else if (indexPath.row % 2 == 0) 
    { 
    // Even row 
    if (indexPath.row == numberOfRowsInThisSection - 1) 
    { 
     // Last row (even) 
     cell.backingImage = self.botWhite; 
    } 
    else 
    { 
     // Normal row (even) 
     cell.backingImage = self.midWhite; 
    } 
    } 
    else if (indexPath.row % 2 == 1) 
    { 
    // Odd row 
    if (indexPath.row == numberOfRowsInThisSection - 1) 
    { 
     // Last row (even) 
     cell.backingImage = self.botDark; 
    } 
    else 
    { 
     // Normal row (odd) 
     cell.backingImage = self.midDark; 
    } 
    } 

    // Setup cell text [REMOVED FOR BREVITY] 

    return cell; 
} 

Mã cho thiết lập các hình ảnh ủng hộ trong vòng MyTableViewCell:

- (void)setBackingImage:(UIImage *)backingImage 
{ 
    if (self.backingImage != backingImage) 
    { 
    _backingImage = nil; 
    _backingImage = backingImage; 
    self.backingView.image = backingImage; 
    } 
} 

self.backingView được thiết lập bằng cách sử dụng mã sau:

[[UIImageView alloc] initWithFrame:CGRectMake(7, 0, 307, 30)]; 
+0

Chúng tôi có thể xem một số mã không? Bạn có bất cứ điều gì đang xảy ra trong heightForRowAtIndexPath :? –

+0

Mã có liên quan đến chế độ xem ô sẽ đẹp. Chế độ xem nào trong ô là bạn thêm chế độ xem, chính ô đó, contentView hoặc backgroundView? Bạn thêm hình ảnh của riêng mình có đường viền? Tôi đã làm một số xét nghiệm và tôi nghĩ rằng phong cách phân cách suy nghĩ không hoạt động với các bảng được nhóm, chúng luôn thu hút dấu phân cách. –

+0

Tôi đã thêm tất cả các mã tôi có thể nghĩ rằng có thể ảnh hưởng đến cấu trúc bảng. Tôi rất sẵn lòng thêm bất kỳ thứ gì khác nếu được yêu cầu ... PS. Các hack trong heightForRowAtIndexPath: là workaround hiện tại của tôi. Nếu hack bị xóa, khoảng cách xuất hiện lại – sleeke

Trả lời

3

Đây là loại sự cố đã biết, chỉ xảy ra khi bạn ẩn dấu phân cách của một bảng đã được nhóm, điều tương tự đã xảy ra trong stack overflow question khác.

một cách đơn giản, phía trên và các tế bào thấp hơn sử dụng một phụ điểm, nhưng tách giấu nó, vì vậy giải pháp là:

  1. trừ khoảng cách bổ sung (như bạn đã làm)
  2. Make nền là mẫu lặp hoặc hình ảnh có thể kéo dài (Không cố gắng quảng bá bản thân mình, nhưng the answer I gave trên chuỗi được liên kết trước đó cũng giải thích cách tạo hình ảnh có thể kéo dài).
  3. Không ẩn dấu phân cách, nhưng đối sánh là màu với nền của ô để nó trông giống như ẩn của nó.

Tùy chọn 2 có vẻ là "sạch" nhất và thêm lợi ích của việc hỗ trợ chiều cao biến của ô bảngView.

Và tại sao lại có thêm điểm? Chỉ có Apple mới biết.

+0

Ba giải pháp tốt, trong đó # 1 phù hợp với yêu cầu của tôi tốt nhất. Tôi muốn có tất cả các hàng có cùng chiều cao, thay vì kéo dài nền của tôi để phù hợp với điểm thêm đó. Nó cũng đáng chú ý ở đây mà tôi đã không nhìn thấy hàng dưới cùng thể hiện hành vi tương tự - hàng đó luôn luôn có vẻ là 30 điểm, giống như phần còn lại. Thật đáng tiếc khi phải sử dụng phương pháp bẩn thỉu như vậy, nhưng như bạn nói - Apple chỉ biết tại sao nó được tạo ra như thế ... – sleeke

0

Đây là tiêu đề phần la hét với tôi. Bạn có ghi đè phương thức viewForHeaderInSection không? Đoán tốt nhất của tôi là các giới hạn cho ô đầu tiên của bạn trong mỗi phần bằng cách nào đó bỏ qua các giới hạn cho tiêu đề của phần đó.

Thử trọng các phương pháp:

– tableView:viewForHeaderInSection: 
– tableView:viewForFooterInSection: 
– tableView:heightForHeaderInSection: 
– tableView:heightForFooterInSection: 
– tableView:willDisplayHeaderView:forSection: 
– tableView:willDisplayFooterView:forSection: 

và chơi với những gì họ quay trở lại. Đặc biệt là heightForHeaderInSection/viewForHeaderInSection/willDisplayHeaderView: ForSection:

+0

Tôi đã cố gắng ghi đè những phương pháp đó, nhưng điều đó dường như không có bất kỳ ảnh hưởng nào. Từ câu trả lời của Có thể và Geoff ở trên, có vẻ như đây là vấn đề đã biết và không phải do lợi nhuận của phương thức đại biểu này ... – sleeke

1

Theo kinh nghiệm của tôi, các khung nhìn bảng được nhóm thêm 1 điểm (không phải pixel!) Vào chiều cao của hàng đầu tiên và cuối cùng trong mỗi phần. Bạn sẽ có thể thấy điều này bằng cách thêm mã gỡ lỗi để ghi đè lên layoutSubviews trên lớp ô bảng của bạn, có nó gọi siêu và sau đó in bounds.size.height.

Tôi đoán đây là cung cấp không gian cho bản vẽ đường viền và, giống như bạn, tôi vừa điều chỉnh giá trị tôi trả về cho chiều cao của ô đầu tiên và cuối cùng để hủy hiệu ứng. Điều này cũng có thể thay đổi trong iOS 7 vì giao diện trực quan đã thay đổi.

[Chỉnh sửa] Đây là một đoạn mã gỡ lỗi tốt để kiểm tra cấu trúc phân cấp xem. (Bạn không thể gọi recursiveDescription trực tiếp vì nó là tư nhân và mã của bạn sẽ không biên dịch theo các thiết lập mặc định Xcode.)

NSLog(@"%@", [self.view performSelector:@selector(recursiveDescription)]);

+0

Bạn có thể làm rõ sự khác biệt mà bạn đề cập giữa điểm và pixel không? Bạn có nghĩa là một điểm là đại diện phổ quát và hiển thị như là 2 điểm ảnh trên một màn hình võng mạc? – sleeke

+0

Vâng, đó là chính xác những gì tôi có ý nghĩa. Bạn đã đo pixel bằng cách nhìn vào màn hình võng mạc của bạn. Để điều chỉnh khoảng trống thừa bạn cần sử dụng tableView: heightForRowAtIndexPath: nhưng cung cấp điều chỉnh dưới dạng điểm, không phải pixel. –

1

Nếu bạn thực hiện như sau nó sẽ khắc phục vấn đề của bạn: Hãy loại bỏ 'backingImage' (backingView). Thay vào đó, sử dụng thuộc tính backgroundView của ô, chỉ cần gán UIImageView cho điều đó. Bây giờ khi bạn tạo ra bạn UIImageView cho nền chắc chắn rằng bạn làm cho UIImage căng ra như thế này:

UIImage *bg = [UIImage imageName:@"filename.png"]; 
bg = [bg resizableImageWithCapInsets:UIEdgeInsetsMake(15, 0, 15, 0)]; 

LƯU Ý: Tôi giả định hình ảnh của bạn có chiều cao là 30 điểm. Nhìn vào hình ảnh bạn đang sử dụng nó có thể được kéo dài theo chiều dọc, những gì tôi đang làm trong ví dụ này. Để tiết kiệm nhiều bộ nhớ hơn, bạn cũng có thể kéo dài nó theo chiều ngang, nhưng tài sản bạn có thể không cho vay chính nó.

Hy vọng điều này sẽ hữu ích!

+0

Đây là một câu trả lời hay, nhưng tiếc là không phải những gì tôi theo sau. Trong khi điều này sẽ bao gồm khoảng cách, tôi vẫn còn lại với hàng đầu là 1 điểm lớn hơn các hàng khác ... – sleeke

0

Trên iOS 8 không có bộ tách trên bảng phân nhóm, tôi cũng gặp sự cố. Có một khoảng cách 0,5 điểm giữa các phần của tôi. Kể từ khi nền phía sau tableview của tôi không phải là cùng một màu sắc, nó đã được rất đáng chú ý. Các giải pháp là để điền vào với một headerview trống 1 px cao, sau đó tràn ra khỏi nó bằng 1 px với một lần xem. Làm việc như một say mê.

- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { 
    UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 1)]; 
    view.backgroundColor = [UIColor whiteColor]; 
    view.opaque = YES; 
    view.clipsToBounds = NO; 

    //Spill a view out by one pixel. 
    UIView *subView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, 2)]; 
    subView.backgroundColor = [UIColor whiteColor]; 
    subView.opaque = YES; 
    [view addSubview:subView]; 
    return view; 
} 

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