Làm cách nào để tùy chỉnh màu nền của UITableViewCell?


188

Tôi muốn tùy chỉnh nền (và có thể cả đường viền) của tất cả các UITableViewCells trong UITableView của tôi. Cho đến nay tôi không thể tùy chỉnh công cụ này, vì vậy tôi có một loạt các ô nền trắng là mặc định.

Có cách nào để làm điều này với SDK iPhone không?

Câu trả lời:


193

Bạn cần đặt màu nền của nội dung của ô thành màu của bạn. Nếu bạn sử dụng các phụ kiện (như mũi tên tiết lộ, v.v.), chúng sẽ hiển thị màu trắng, do đó bạn có thể cần phải cuộn các phiên bản tùy chỉnh của chúng.


108
ví dụ: myCell.contentView.backgroundColor = [UIColor greenColor];
JoBu1324

1
Câu trả lời của vlado.grigorov linh hoạt hơn - xem câu trả lời của William Denniss
JoBu1324

3
Bất kỳ liên kết về làm thế nào để cuộn của riêng mình UITableViewCellAccessoryCheckmark, ví dụ? Cảm ơn.
Dan Rosenstark

6
Để thấy điều đó đôi khi bạn cần phải thiết lập:cell.textLabel.backgroundColor = [UIColor clearColor];
Evan Moran

205

Đây là cách hiệu quả nhất mà tôi đã gặp để giải quyết vấn đề này, sử dụng phương thức ủy nhiệm willDisplayCell (cách này cũng quan tâm đến màu trắng cho nền nhãn văn bản khi sử dụng cell.textLabel.text và / hoặc cell.detailTextLabel.text ):

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { ... }

Khi phương thức ủy nhiệm này được gọi là màu của ô được điều khiển thông qua ô chứ không phải dạng xem bảng, như khi bạn sử dụng:

- (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath { ... }

Vì vậy, trong phần thân của phương thức ủy nhiệm ô, thêm đoạn mã sau vào màu xen kẽ của các ô hoặc chỉ sử dụng lệnh gọi hàm để làm cho tất cả các ô của bảng có cùng màu.

if (indexPath.row % 2)
{
    [cell setBackgroundColor:[UIColor colorWithRed:.8 green:.8 blue:1 alpha:1]];
}
else [cell setBackgroundColor:[UIColor clearColor]];

Giải pháp này hoạt động tốt trong hoàn cảnh của tôi ...


Đây là một giải pháp sạch hơn. Hầu hết các giải pháp khác đều yêu cầu phân lớp UITableViewCell. Giải pháp của vlado.grigorov không làm việc cho tôi.
Ronnie Liew

Thật vậy, và đây là phương pháp mà Apple tự đề xuất theo các bài thuyết trình WWDC khác nhau mà tôi đã thấy.
Mike Weller

Đẹp - NGOẠI TRỪ khi bạn cần thêm hàng mới ở đầu danh sách. Phương pháp này làm cho tất cả các bổ sung cùng màu. Làm mới không sửa nó, nhưng mất thời gian không cần thiết. Phát hiện ra ngày hôm qua ...
JOM

Điều này dường như hoạt động tốt, ngoại trừ khi sử dụng Core Data. Các ô mới được thêm thông qua NSFetchedResultsControll dường như không gọi willDisplayCell đúng cách. Tôi thua lỗ khiến nó hoạt động ...
rạng sáng

Dòng tương đương để cài đặt màu nền trong Swift 2.0:cell.backgroundColor = UIColor.clearColor
kbpontius

104

Điều này thực sự đơn giản, vì OS 3.0 chỉ đặt màu nền của ô trong phương thức willDisplayCell. Bạn không được đặt màu trong cellForRowAtIndexPath.

Điều này hoạt động cho cả phong cách đơn giản và nhóm:

Mã số:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    cell.backgroundColor = [UIColor redColor];
}

PS: Ở đây trích xuất tài liệu cho willDisplayCell:

"Một khung nhìn bảng gửi thông báo này đến đại biểu của nó ngay trước khi nó sử dụng ô để vẽ một hàng, do đó cho phép đại biểu tùy chỉnh đối tượng ô trước khi nó được hiển thị. Phương thức này cho phép đại biểu ghi đè các thuộc tính dựa trên trạng thái được đặt trước đó bởi Chế độ xem bảng, chẳng hạn như lựa chọn và màu nền. Sau khi đại biểu trả về, chế độ xem bảng chỉ đặt các thuộc tính alpha và khung, và sau đó chỉ khi hoạt ảnh các hàng khi chúng trượt vào hoặc ra. "

Tôi đã tìm thấy thông tin này trong bài viết này từ colionel . Cảm ơn anh ấy!


3
Điều này nên được đánh dấu là câu trả lời chính xác vì bạn thậm chí không phải làm gì nếu bạn có một tiết lộ
Ashish Awaghad

1
Điều này không hoạt động nếu bạn muốn một màu nền ô khác với nền xem bảng cho tôi.
Chris

Đối với ô nhóm, bạn có thể đặt nó trên cellForRow
Sharen Eayrs

58

Cách tiếp cận tốt nhất mà tôi đã tìm thấy cho đến nay là thiết lập chế độ xem nền của ô và xóa nền của các cuộc phỏng vấn tế bào. Tất nhiên, điều này trông đẹp trên các bảng chỉ với kiểu được lập chỉ mục, bất kể có hoặc không có phụ kiện.

Đây là một mẫu mà nền của ô được tô màu vàng:

UIView* backgroundView = [ [ [ UIView alloc ] initWithFrame:CGRectZero ] autorelease ];
backgroundView.backgroundColor = [ UIColor yellowColor ];
cell.backgroundView = backgroundView;
for ( UIView* view in cell.contentView.subviews ) 
{
    view.backgroundColor = [ UIColor clearColor ];
}

1
Nếu bạn làm điều này, hãy đảm bảo đặt thuộc tính mờ thành KHÔNG.
Lily Ballard

11
Sử dụng điều khiển tế bào trong suốt thực sự không được khuyến khích. Hiệu suất cuộn sẽ bị ảnh hưởng rất nhiều, đó là lý do tại sao Apple luôn nói phải sử dụng các điều khiển mờ.
Mike Weller

3
Trên iOS 4.2 trở lên, có vẻ như vòng lặp không còn cần thiết nữa.
Frank Schmitt

Rất đẹp. Hoạt động hoàn hảo khi sử dụng chế độ xem phụ kiện !!
RyanG

19

Chỉ cần đặt tệp này vào tệp lớp đại biểu UITableView (.m):

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell  forRowAtIndexPath:(NSIndexPath *)indexPath 
{
    UIColor *color = ((indexPath.row % 2) == 0) ? [UIColor colorWithRed:255.0/255 green:255.0/255 blue:145.0/255 alpha:1] : [UIColor clearColor];
    cell.backgroundColor = color;
}

7

Tôi đồng tình với Seba, tôi đã cố gắng đặt màu hàng xen kẽ của mình trong phương thức ủy nhiệm rowForIndexPath nhưng nhận được kết quả không nhất quán giữa 3.2 và 4.2. Sau đây làm việc tuyệt vời cho tôi.

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {

    if ((indexPath.row % 2) == 1) {
        cell.backgroundColor = UIColorFromRGB(0xEDEDED);
        cell.textLabel.backgroundColor = UIColorFromRGB(0xEDEDED);
        cell.selectionStyle = UITableViewCellSelectionStyleGray;
    }
    else
    {
        cell.backgroundColor = [UIColor whiteColor];
        cell.selectionStyle = UITableViewCellSelectionStyleGray;
    }

}

1
Vẫn không hiểu tại sao việc đặt nó trong willDisplayCell lại tạo ra sự khác biệt. Dù sao nó cũng được gọi là liệu chúng ta có thực hiện điều đó hay không?
Sharen Eayrs

6

Sau khi thử tất cả các giải pháp khác nhau, phương pháp sau đây là phương pháp thanh lịch nhất. Thay đổi màu trong phương thức ủy nhiệm sau:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (...){
        cell.backgroundColor = [UIColor blueColor];
    } else {
        cell.backgroundColor = [UIColor whiteColor];
    }
}

4

vlado.grigorov có một số lời khuyên tốt - cách tốt nhất là tạo một BackgroundView và cung cấp màu đó, đặt mọi thứ khác thành ClearColor. Ngoài ra, tôi nghĩ rằng cách đó là cách duy nhất để xóa màu chính xác (thử mẫu của anh ấy - nhưng đặt 'ClearColor' thay vì 'yellowColor'), đó là điều tôi đang cố gắng thực hiện.


Một lợi thế của phương pháp này là bạn có thể giữ màu sắc là thuộc tính thời gian thiết kế trong Trình tạo giao diện. Một vấn đề thiết kế ít hơn đòi hỏi sự tương tác của nhà phát triển.
whitneyland

1
cell.backgroundView = [[[UIView alloc] initWithFrame: cell.bound] autorelease]; cell.backgroundView.backgroundColor = [UIColor redColor];
Brian

3

Tùy chỉnh nền của một ô xem bảng cuối cùng trở thành và cách tiếp cận "tất cả hoặc không có gì". Rất khó để thay đổi màu sắc hoặc hình ảnh được sử dụng cho nền của ô nội dung theo cách trông không lạ.

Lý do là tế bào thực sự kéo dài chiều rộng của khung nhìn. Các góc tròn chỉ là một phần của phong cách vẽ của nó và chế độ xem nội dung nằm trong khu vực này.

Nếu bạn thay đổi màu của ô nội dung, bạn sẽ kết thúc với các bit trắng hiển thị ở các góc. Nếu bạn thay đổi màu của toàn bộ ô, bạn sẽ có một khối màu trải dài theo chiều rộng của chế độ xem.

Bạn chắc chắn có thể tùy chỉnh một ô, nhưng nó không hoàn toàn dễ dàng như bạn nghĩ lúc đầu.


1
Điều này hoàn toàn đúng với các ô trong các bảng được nhóm, nhưng các bảng Plain không có quá nhiều điều phải lo lắng. Một tế bào không được trang bị không có phụ kiện sẽ trông ổn.
Ben Gottlieb

Bến - điểm tốt. Tôi chủ yếu sử dụng các bảng được nhóm nhưng như bạn đề cập đến các bảng đơn giản không gặp phải bất kỳ vấn đề nào trong số này.
Andrew Grant

3

Tạo chế độ xem và đặt chế độ xem này làm chế độ xem nền của ô

UIView *lab = [[UIView alloc] initWithFrame:cell.frame];
            [lab setBackgroundColor:[UIColor grayColor]];
            cell.backgroundView = lab;
            [lab release];

3

Để mở rộng câu trả lời của N.Berendt - Nếu bạn muốn đặt màu ô dựa trên một số trạng thái trong đối tượng dữ liệu ô thực tế, tại thời điểm bạn đang định cấu hình phần còn lại của thông tin cho ô bảng, thường là khi bạn ở trong Phương thức cellForRowAtIndexPath, bạn có thể thực hiện việc này bằng cách ghi đè phương thức willDisplayCell để đặt màu nền của ô từ màu nền của chế độ xem nội dung - điều này xoay quanh vấn đề của nền nút tiết lộ, v.v. không đúng nhưng vẫn cho phép bạn kiểm soát màu trong phương thức cellForRowAtIndexPath nơi bạn đang làm tất cả các tùy chỉnh tế bào khác của bạn.

Vì vậy: Nếu bạn thêm phương thức này vào đại biểu xem bảng của bạn:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    cell.backgroundColor = cell.contentView.backgroundColor;
}

Sau đó, trong phương thức cellForRowAtIndexPath của bạn, bạn có thể làm:

if (myCellDataObject.hasSomeStateThatMeansItShouldShowAsBlue) {
    cell.contentView.backgroundColor = [UIColor blueColor];
}

Điều này giúp tiết kiệm việc phải truy xuất lại các đối tượng dữ liệu của bạn trong phương thức willDisplayCell và cũng tiết kiệm có hai nơi bạn thực hiện chỉnh sửa / tùy chỉnh ô của bảng - tất cả các tùy chỉnh có thể đi theo phương thức cellForRowAtIndexPath.


3

Tạo một hình ảnh để sử dụng làm nền với Photoshop hoặc gimp và đặt tên cho nó là myimage. Sau đó, thêm phương thức này vào lớp tableViewControll của bạn:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    UIImage *cellImage = [UIImage imageNamed:@"myimage.png"];//myimage is a 20x50 px with  gradient  color created with gimp
    UIImageView *cellView = [[UIImageView alloc] initWithImage:cellImage];
    cellView.contentMode = UIContentViewModeScaleToFill;
    cell.backgroundView = cellView;
    //set the background label to clear
    cell.titleLabel.backgroundColor= [UIColor clearColor];
}

Điều này cũng sẽ hoạt động nếu bạn đã đặt UITableView thành tùy chỉnh trong trình kiểm tra thuộc tính.


2

Giải pháp của tôi là thêm đoạn mã sau vào sự kiện cellForRowAtIndexPath:

UIView *solidColor = [cell viewWithTag:100];
if (!solidColor) {

    solidColor = [[UIView alloc] initWithFrame:cell.bounds];
    solidColor.tag = 100; //Big tag to access the view afterwards
    [cell addSubview:solidColor];
    [cell sendSubviewToBack:solidColor];
    [solidColor release];
}
solidColor.backgroundColor = [UIColor colorWithRed:254.0/255.0
                                             green:233.0/255.0
                                              blue:233.0/255.0
                                             alpha:1.0];

Hoạt động trong mọi trường hợp, ngay cả với các nút tiết lộ và tốt hơn là logic của bạn sẽ hoạt động trên trạng thái màu của ô trong cellForRowAtIndexPath so với trong sự kiện cellWillShow tôi nghĩ.


1

Phân lớp UITableViewCell và thêm phần này vào phần triển khai:

-(void)layoutSubviews
{
    [super layoutSubviews];
    self.backgroundColor = [UIColor blueColor];
}

1
    UIView *bg = [[UIView alloc] initWithFrame:cell.frame];
    bg.backgroundColor = [UIColor colorWithRed:175.0/255.0 green:220.0/255.0 blue:186.0/255.0 alpha:1]; 
    cell.backgroundView = bg;
    [bg release];

1

Điều này sẽ hoạt động trong Xcode mới nhất.

-(UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath {
    cell.backgroundColor = [UIColor grayColor];
}

0

Thử cái này:

- (void)tableView:(UITableView *)tableView1 willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    [cell setBackgroundColor:[UIColor clearColor]];
    tableView1.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed: @"Cream.jpg"]];
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.