Jak dostosować kolor tła UITableViewCell?

188

Chciałbym dostosować tło (a może także ramkę) wszystkich UITableViewCells w moim UITableView. Do tej pory nie byłem w stanie dostosować tego, więc mam kilka białych komórek, które są domyślne.

Czy można to zrobić za pomocą zestawu iPhone SDK?

jpm
źródło

Odpowiedzi:

193

Musisz ustawić kolor tła zawartości komórki Wyświetl na swój kolor. Jeśli używasz akcesoriów (takich jak strzałki ujawnienia itp.), Będą one wyświetlane jako białe, więc może być konieczne zwinięcie ich niestandardowych wersji.

Ben Gottlieb
źródło
108
np. myCell.contentView.backgroundColor = [UIColor greenColor];
JoBu1324
1
Odpowiedź vlado.grigorov jest bardziej elastyczna - patrz odpowiedź Williama Dennisa
JoBu1324
3
Na przykład jakieś linki na temat tego, jak się zrolować UITableViewCellAccessoryCheckmark? Dzięki.
Dan Rosenstark,
6
Aby to zobaczyć, musisz ustawić:cell.textLabel.backgroundColor = [UIColor clearColor];
Evan Moran
205

Oto najbardziej skuteczny sposób, w jaki udało mi się rozwiązać ten problem, użyj metody delegowania willDisplayCell (dba o biały kolor tła etykiety tekstowej również podczas korzystania z cell.textLabel.text i / lub cell.detailTextLabel.text ):

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

Po wywołaniu tej metody delegowania kolor komórki jest kontrolowany za pośrednictwem komórki, a nie widoku tabeli, tak jak w przypadku użycia:

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

Tak więc w treści metody delegowania komórek dodaj następujący kod, aby naprzemiennie kolory komórek lub po prostu użyj wywołania funkcji, aby wszystkie komórki tabeli miały ten sam kolor.

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

To rozwiązanie działało dobrze w moich okolicznościach ...

Nathan B.
źródło
To rozwiązanie jest o wiele czystsze. Większość innych rozwiązań wymaga albo podklasy UITableViewCell. Rozwiązanie vlado.grigorov nie działa dla mnie.
Ronnie Liew
Rzeczywiście, i jest to metoda, którą sami zalecają Apple według różnych prezentacji WWDC, które widziałem.
Mike Weller,
Fajnie - Z WYJĄTKIEM, gdy musisz dodać nowe wiersze na górze listy. Ta metoda sprawia, że ​​wszystkie dodatki mają ten sam kolor. Odśwież naprawia to, ale zajmuje niepotrzebny czas. Dowiedziałem się wczoraj ...
JOM
Wydaje się, że działa to dobrze, z wyjątkiem korzystania z podstawowych danych. Nowe komórki dodane przez NSFetchedResultsController nie wydają się poprawnie wywoływać willDisplayCell. Nie wiem, czy to działa ...
radven,
Równoważna linia do ustawiania koloru tła w Swift 2.0:cell.backgroundColor = UIColor.clearColor
kbpontius
104

Jest to bardzo proste, ponieważ OS 3.0 ustawia tylko kolor tła komórki w metodzie willDisplayCell. Nie wolno ustawiać koloru w cellForRowAtIndexPath.

Działa to zarówno dla stylu zwykłego, jak i zgrupowanego:

Kod:

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

PS: tutaj fragment dokumentacji willDisplayCell:

„Widok tabeli wysyła ten komunikat do swojego delegata tuż przed użyciem komórki do narysowania wiersza, umożliwiając w ten sposób dostosowanie obiektu komórki przed jego wyświetleniem. Ta metoda daje delegatowi możliwość zastąpienia właściwości opartych na stanie określonych wcześniej przez widok tabeli, taki jak zaznaczenie i kolor tła. Po powrocie delegata widok tabeli ustawia tylko właściwości alfa i ramki, a następnie tylko podczas animowania wierszy, gdy się wsuwają lub wysuwają. ”

Znalazłem tę informację w tym poście od Colionela . Podziękuj mu!

Seba
źródło
3
To powinno być oznaczone jako poprawna odpowiedź, ponieważ nie musisz nawet niczego, jeśli masz ujawnienie
.Indiator
1
To nie działa, jeśli chcesz dla mnie innego koloru tła komórki niż tło widoków tabeli.
Chris
Dla komórki grupy możesz ustawić ją na cellForRow
Sharen Eayrs
58

Najlepszym podejściem, jakie do tej pory znalazłem, jest ustawienie widoku tła komórki i wyczyszczenie tła widoków komórki. Oczywiście wygląda to ładnie tylko na stołach z indeksowanym stylem, bez względu na to, czy są z akcesoriami, czy bez.

Oto próbka, w której tło komórki jest spłaszczone na żółto:

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 ];
}
Vladimir Grigorov
źródło
1
Jeśli to zrobisz, ustaw również nieprzezroczystą właściwość na NIE.
Lily Ballard
11
Używanie przezroczystych kontrolek komórek naprawdę nie jest zalecane. Na wydajność przewijania będzie to miało duży wpływ, dlatego Apple zawsze mówi, aby używać nieprzezroczystych elementów sterujących.
Mike Weller,
3
W iOS 4.2 i nowszych wygląda na to, że pętla nie jest już potrzebna.
Frank Schmitt,
Bardzo dobrze. Działa idealnie, gdy używasz widoków akcesoriów !!
RyanG,
19

Po prostu włóż to do pliku UITableView klasy pliku delegowanego (.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;
}
WYSTĘP
źródło
7

Zgadzam się z Sebą, próbowałem ustawić swój zmienny kolor wiersza w metodzie delegowania rowForIndexPath, ale uzyskiwałem niespójne wyniki między 3.2 a 4.2. Poniższe działało dla mnie świetnie.

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

}
Cipherz
źródło
1
Nadal nie rozumiem, dlaczego ustawienie go w willDisplayCell robi jakąkolwiek różnicę. Nazywa się tak czy inaczej, czy to wdrażamy, czy nie?
Sharen Eayrs
6

Po wypróbowaniu wszystkich różnych rozwiązań, najbardziej elegancka jest następująca metoda. Zmień kolor w następującej metodzie delegowania:

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {
    if (...){
        cell.backgroundColor = [UIColor blueColor];
    } else {
        cell.backgroundColor = [UIColor whiteColor];
    }
}
Jim Huang
źródło
4

vlado.grigorov ma kilka dobrych rad - najlepszym sposobem jest utworzenie widoku tła i nadanie mu koloru, ustawiając wszystko inne na clearColor. Myślę też, że w ten sposób jest to jedyny sposób, aby poprawnie wyczyścić kolor (wypróbuj jego próbkę - ale ustaw „clearColor” zamiast „yellowColor”), co właśnie próbowałem zrobić.

William Denniss
źródło
Zaletą tego podejścia jest to, że można zachować kolor w czasie projektowania w Konstruktorze interfejsów. Jeden mniej problemu projektowego, który wymaga interakcji programisty.
Whitneyland,
1
cell.backgroundView = [[[[UIView przydziel]] initWithFrame: cell.bounds] autorelease]; cell.backgroundView.backgroundColor = [UIColor redColor];
Brian
3

Dostosowywanie tła komórki widoku tabeli w końcu staje się i podejście „wszystko albo nic”. Bardzo trudno jest zmienić kolor lub obraz użyty na tle komórki treści w sposób, który nie wygląda dziwnie.

Powodem jest to, że komórka faktycznie obejmuje szerokość widoku. Zaokrąglone rogi są tylko częścią stylu rysowania, a widok zawartości znajduje się w tym obszarze.

Jeśli zmienisz kolor komórki treści, zobaczysz białe bity widoczne w rogach. Jeśli zmienisz kolor całej komórki, uzyskasz blok koloru obejmujący szerokość widoku.

Możesz zdecydowanie dostosować komórkę, ale nie jest to tak łatwe, jak mogłoby się początkowo wydawać.

Andrew Grant
źródło
1
Jest to z pewnością prawda w przypadku komórek w zgrupowanych tabelach, ale zwykłe tabele nie mają się o co martwić. Bez ozdoby komórka bez akcesoriów powinna dobrze wyglądać.
Ben Gottlieb,
Ben - dobry punkt. Używam przede wszystkim zgrupowanych tabel, ale jak wspominasz, zwykłe tabele nie cierpią na żaden z tych problemów.
Andrew Grant,
3

Utwórz widok i ustaw go jako widok tła komórki

UIView *lab = [[UIView alloc] initWithFrame:cell.frame];
            [lab setBackgroundColor:[UIColor grayColor]];
            cell.backgroundView = lab;
            [lab release];
Senthil
źródło
3

Aby rozszerzyć odpowiedź N.Berendt - Jeśli chcesz ustawić kolor komórki w oparciu o jakiś stan w rzeczywistym obiekcie danych komórki, w czasie konfigurowania reszty informacji dla komórki tabeli, to jest zwykle, gdy jesteś w W przypadku metody cellForRowAtIndexPath można to zrobić, zastępując metodę willDisplayCell w celu ustawienia koloru tła komórki z koloru tła widoku zawartości - to rozwiązuje problem tła przycisków ujawnienia itp., które nie są prawidłowe, ale nadal pozwala kontrolować kolor w metodzie cellForRowAtIndexPath gdzie wykonujesz wszystkie inne dostosowania komórek.

Więc: Jeśli dodasz tę metodę do delegata widoku tabeli:

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

Następnie w metodzie cellForRowAtIndexPath możesz wykonać:

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

Oszczędza to konieczności ponownego pobierania obiektów danych w metodzie willDisplayCell, a także zapisuje dwa miejsca, w których dostosowujesz / dostosowujesz komórkę tabeli - wszystkie dostosowania można przeprowadzić w metodzie cellForRowAtIndexPath.

gamozzii
źródło
3

Utwórz obraz, który będzie używany jako tło w Photoshopie lub Gimpie i nazwij go myimage. Następnie dodaj tę metodę do klasy tableViewController:

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

Działa to również, jeśli ustawiłeś UITableView na niestandardowy w Inspektorze atrybutów.

Davide
źródło
2

Moje rozwiązanie polega na dodaniu następującego kodu do zdarzenia 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];

Działa w każdych okolicznościach, nawet z przyciskami ujawniania, i lepiej, aby logika działała na stan koloru komórek w cellForRowAtIndexPath niż w zdarzeniu cellWillShow.

albertoFlagSolutions
źródło
1

Podklasa UITableViewCell i dodaj to do implementacji:

-(void)layoutSubviews
{
    [super layoutSubviews];
    self.backgroundColor = [UIColor blueColor];
}
JonahGabriel
źródło
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];
Bhavesh Nayi
źródło
1

Będzie to działać w najnowszym Xcode.

-(UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath {
    cell.backgroundColor = [UIColor grayColor];
}
Sameera R.
źródło
0

Spróbuj tego:

- (void)tableView:(UITableView *)tableView1 willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    [cell setBackgroundColor:[UIColor clearColor]];
    tableView1.backgroundColor = [UIColor colorWithPatternImage: [UIImage imageNamed: @"Cream.jpg"]];
}
Ostry ból
źródło