2012-10-13 11 views
5

Posiadam podklasowy UITableViewCell.Nie można zaktualizować ramki obiektu UI w katalogu UITableViewCell

Potrzebuję dynamicznie zmieniać ramkę UILabel.

Oto co zrobiłem:

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

    cell.Content.Text = @"Content!"; 
    [cell.Content setFrame:CGRectMake(0, 0, 10, 10)]; 
} 

Tekst UILabel nie zmienia, więc nie jest to problem IBOutlet. Ramka pozostaje jednak taka sama jak zdefiniowano w IB.

Robiłem rzeczy, jak to już wcześniej, więc nie jestem pewien, co poszło nie tak tutaj ...

Dzięki za wszelką pomoc.

Edit:

używam

[self.tableView registerNib:[UINib nibWithNibName:@"MessageCell" bundle:nil] 
    forCellReuseIdentifier:@"MessageCell"]; 

w viewDidLoad

Odpowiedz

4

Dobrze kilka dni po zaksięgowaniu nagrodę Znalazłem odpowiedź, mam nadzieję, że to pomoże ktoś kiedyś ...

nie jestem w 100% pewien dlaczego, ale to, co starałem się robić po prostu nie może zrobić:

Nie możesz zmienić ramki obiektu, jeśli umieściłeś go za pomocą Konstruktora interfejsu.

Aby wprowadzić zmiany, które chciałem wykonać, po prostu utworzyłem te obiekty programowo w mojej podklasie, wewnątrz "initWithCoder".

content = [[UILabel alloc] initWithFrame:CGRectMake(120, 100, 200, 50)]; 
content.opaque = NO; 
content.numberOfLines = 0; 
[self.contentView addSubview:content]; 

byłem wtedy w stanie zmienić ramek wewnątrz „- (void) layoutSubviews” (ale w zasadzie wszędzie chciałem)

- (void)layoutSubviews 
{ 
    [super layoutSubviews]; 
    [cell.Content setFrame:CGRectMake(0, 0, 10, 10)]; 

    ... 
2

Tam musi być coś nie istnieje.

spróbować tylkodo testowania zaimplementować to:

tableView:willDisplayCell:forRowAtIndexPath: 

Jak

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    MessageCell* aCell = (MessageCell*)cell; 
    aCell.Content.Text = @"Content!"; 
    [aCell.Content setFrame:CGRectMake(0, 0, 10, 10)]; 
} 

Jaki jest wynik?

+0

pozostaje ten sam niefortunny ... – BenB

+0

Wielki Daniel to działało dla mnie. W końcu podałeś rozwiązanie bardzo znanego problemu. –

1

Dodaj wydział do cell.Content i zmień rozmiar tego podglądu zamiast samej treści. Komórka będzie zawsze rozciągnięta, aby pasowała do widoku tabeli, więc nie można jej zmniejszyć.
(i oczywiście, aby wysokość komórki była mniejsza, wystarczy zastosować)

+0

Nie próbowałem edytować widoku komórki, ale UILabel wewnątrz tej komórki. – BenB

1

Może to dotyczyć faktu ponownego użycia komórki. Spróbuj tego

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
    { 
     static NSString *CellIdentifier = @"messageCell"; 
     MessageCell *cell = (MessageCell*) [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath]; 
    if(cell == nil) 
     { 
     cell = [[[MessageCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier]autorelease]; 
     } 
     cell.Content.Text = @"Content!"; 
     [cell.Content setFrame:CGRectMake(0, 0, 10, 10)]; 
     return cell; 
    } 
+0

Aplikacja nigdy nie dociera (komórka == zero) ... – BenB

+0

Czy ustawiłeś źródło danych swojego tableview? Co masz na myśli mówiąc, że aplikacja nie osiąga (komórka == zero), czy wywoływana jest funkcja cellForRowAtIndexPath? – Animesh

+0

Mam na myśli komórkę nigdy nie jest pusta – BenB

1

Czy rozważałeś przesłanianie metody - (void) layoutSubviews w Twojej komórce (tj MessageCell) i układ swoje rzeczy w środku? Myślę, że jest to najbezpieczniejsze miejsce do umieszczania kodu zmieniającego układ, ponieważ w innych miejscach może nie mieć żadnego efektu. Nie zapomnij zadzwonić pod numer [super layoutSubviews]; w swojej implementacji layoutSubviews.

Rozważ skorzystanie z tego podejścia i daj nam znać, jeśli to zadziałało! Należy jednak wziąć pod uwagę wpływ wydajności na takie podejście, ponieważ layoutSubviews będzie wywoływane za każdym razem, gdy tabela będzie przewijana.

EDIT:

pomieścić do właściwych rozmiarów ramki dla etykiety wewnątrz layoutSubviews rozważyć użycie - (CGSize)sizeWithFont:(UIFont *)font constrainedToSize:(CGSize)size lineBreakMode:(UILineBreakMode)lineBreakMode przy obliczaniu ramki.

+0

Nadal nie uzyskuję żadnego wyniku ... Upewniłem się, że nadpisywany jest layoutSubviews w MessageCell, i nazwałem także super-funkcję – BenB

+0

Kolejna bardzo niezręczna próba: nadpisanie metody "- (void) setFrame: (CGRect) frame" w twoim MessageCell.m (zadzwoń do super raz jeszcze) i umieść tam instrukcję NSLog, aby zobaczyć, kiedy zostanie wywołana podczas cyklu odświeżania widoku tabeli! –

+0

I kolejne pytanie dotyczące mojej początkowej odpowiedzi: w swojej nadpisanej metodzie "layoutSubviews", kiedy nazywacie "[super layoutSubviews]"? Spróbuj ustawić połączenie super po ustawieniu ramki dla etykiety. –

2

Nie możesz edytować klatkę obiektu UI utworzony przez XIb jeśli autoLayout jest włączone. Są na to dwa sposoby:

  1. Wyłącz Autolayout dla tego xib.

LUB

  1. Złóż IBOutlet konkretnej NSlayout przymusu dołączyć go odpowiednio i aktualizować swoją stałą wartość nieruchomości poprzez kod i nie zapomnij zadzwonić layOutIfNeeded odpowiednio na obiekcie na którym implementowane jest constarint lub superview zgodnie z implementacją.
Powiązane problemy