Jak ustawić szerokość komórki w UITableView w stylu zgrupowanym

107

Pracowałem nad tym od około 2 dni, więc pomyślałem, że podzielę się z wami swoimi doświadczeniami.

Pytanie brzmi: czy można zmniejszyć szerokość komórki w zgrupowanym widoku UITableView?

Odpowiedź brzmi nie.

Ale istnieją dwa sposoby obejścia tego problemu.

Rozwiązanie nr 1: Cieńszy stół Można zmienić ramkę tableView, tak aby tabela była mniejsza. Spowoduje to renderowanie komórki przez UITableView o zmniejszonej szerokości.

Rozwiązanie tego może wyglądać następująco:

-(void)viewWillAppear:(BOOL)animated
{
    CGFloat tableBorderLeft = 20;
    CGFloat tableBorderRight = 20;

    CGRect tableRect = self.view.frame;
    tableRect.origin.x += tableBorderLeft; // make the table begin a few pixels right from its origin
    tableRect.size.width -= tableBorderLeft + tableBorderRight; // reduce the width of the table
    tableView.frame = tableRect;
}

Rozwiązanie nr 2: renderowanie komórek przez obrazy

Rozwiązanie to opisano tutaj: http://cocoawithlove.com/2009/04/easy-custom-uitableview-drawing.html

Mam nadzieję, że te informacje są dla Ciebie pomocne. Wypróbowanie wielu możliwości zajęło mi około 2 dni. Oto, co zostało.

Tomen
źródło
3
Myślę, że powinno to zostać ustawione jako pytanie z tylko drugą linią („Pytanie brzmi: ...”), a następnie rozwiązanie nr 1 i rozwiązanie nr 2 zostały opublikowane jako dwie oddzielne odpowiedzi, przy czym jedna z nich została zaakceptowana. Następnie, jeśli inni użytkownicy dodają własne odpowiedzi, a jeden z nich będzie lepszy, zaakceptowaną odpowiedź można później zmienić.
GeneralMike,

Odpowiedzi:

226

Lepszym i czystszym sposobem osiągnięcia tego jest podklasa UITableViewCell i zastąpienie jej -setFrame:metody w następujący sposób:

- (void)setFrame:(CGRect)frame {
    frame.origin.x += inset;
    frame.size.width -= 2 * inset;
    [super setFrame:frame];
}

Dlaczego to jest lepsze? Ponieważ pozostałe dwa są gorsze.

  1. Dostosuj szerokość widoku tabeli w -viewWillAppear:

    Przede wszystkim jest to zawodne, kontroler nadzoru lub nadrzędnego widoku może dalej regulować ramkę widoku tabeli po -viewWillAppear:wywołaniu. Oczywiście możesz podklasować i przesłonić -setFrame:dla swojego UITableView, tak jak to, co robię tutaj dla UITableViewCells. Jednak tworzenie podklas UITableViewCells jest bardzo powszechnym, lekkim i Apple sposobem.

    Po drugie, jeśli twój UITableView ma backgroundView, nie chcesz, aby jego backgroundView był zawężany razem. Utrzymywanie szerokości backgroundView podczas zawężania szerokości UITableView nie jest trywialną pracą, nie wspominając o tym, że rozszerzanie podglądów podrzędnych poza jego superview nie jest przede wszystkim elegancką rzeczą do zrobienia.

  2. Renderowanie niestandardowych komórek w celu sfałszowania węższej szerokości

    Aby to zrobić, musisz przygotować specjalne obrazy tła z poziomymi marginesami i musisz samodzielnie ułożyć podglądy komórek, aby uwzględnić marginesy. Dla porównania, jeśli po prostu dostosujesz szerokość całej komórki, automatyczna zmiana rozmiaru wykona całą pracę za Ciebie.

an0
źródło
2
to ładne i eleganckie rozwiązanie, zrobiłem to w kategorii :) Zwracam też uwagę, że im więcej przezroczystych obiektów, tym większe obciążenie procesora :)
pan koz
11
@misterkoz - słowo ostrzeżenia: niektóre kontrolki iOS (UIDatePicker dla określonego) wewnętrznie używają UITableViewCells i przerywają, jeśli zaimplementujesz to w kategorii.
Clafou,
7
Ta metoda wydaje się nie działać w iOS8 podczas próby usunięcia komórki w trybie edycji. Funkcja setFrame jest wywoływana po wejściu / wyjściu z trybu edycji, więc komórka wciąż się kurczy. Jakieś rozwiązanie tego problemu?
John Baum,
3
@JohnBaum to może pomóc (przynajmniej w moim przypadku to działa): stackoverflow.com/questions/25911484/ios-8-cell-resizing/ ...
HashtagMarkus
2
To rozwiązanie jest naprawdę darem niebios. Na wypadek, gdyby ktoś się zastanawiał, jak zrobić to samo w swift - reddit.com/r/swift/comments/2fr849/…
sysuser
16

Aby to zrobić w języku Swift, który nie zapewnia metod ustawiania zmiennych, będziesz musiał nadpisać metodę ustawiającą frame. Pierwotnie opublikowane (przynajmniej tam, gdzie je znalazłem) tutaj

override var frame: CGRect {
    get {
        return super.frame
    }
    set (newFrame) {
        let inset: CGFloat = 15
        var frame = newFrame
        frame.origin.x += inset
        frame.size.width -= 2 * inset
        super.frame = frame
    }
}
JuJoDi
źródło
Działa szybko
Simon McNeil
9

Jeśli nic nie działa, możesz spróbować

Ustaw kolor tła komórki jako czysty kolor, a następnie umieść obraz komórki o wymaganym rozmiarze. Jeśli chcesz wyświetlić tekst w tej komórce, umieść etykietę nad obrazem. Nie zapomnij ustawić koloru tła etykiety również na wyraźny kolor.

includeMe
źródło
8

Zauważyłem, że zaakceptowane rozwiązanie nie działa po rotacji. Aby uzyskać UITableViewCells ze stałymi szerokościami i elastycznymi marginesami, właśnie dostosowałem powyższe rozwiązanie do następującego:

- (void)setFrame:(CGRect)frame {

    if (self.superview) {
        float cellWidth = 500.0;
        frame.origin.x = (self.superview.frame.size.width - cellWidth) / 2;
        frame.size.width = cellWidth;
    }

    [super setFrame:frame];
}

Metoda jest wywoływana za każdym razem, gdy urządzenie się obraca, więc komórki zawsze będą wyśrodkowane.

Graham
źródło
0

Istnieje metoda wywoływana podczas obracania ekranu: viewWillTransitionToSize

Tutaj powinieneś zmienić rozmiar ramki. Zobacz przykład. Zmieniaj współrzędne ramy według potrzeb.

- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator
{
    [coordinator animateAlongsideTransition:nil completion:^(id<UIViewControllerTransitionCoordinatorContext> context)
    {
        int x = 0;
        int y = 0;
        self.tableView.frame = CGRectMake(x, y, 320, self.tableView.frame.size.height);
    }];
}
Chłopak
źródło
-2

robię to w

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell;
    CGFloat tableBorderLeft = self.view.frame.origin.x + 10;
    CGFloat tableBorderRight = self.view.frame.size.width - 20;

    CGRect tableRect = self.view.frame;
    tableRect.origin.x = tableBorderLeft; 
    tableRect.size.width = tableBorderRight; 
    tableView.frame = tableRect;
}

I to zadziałało dla mnie

Lều Đức Quý
źródło
-6

W pliku .h dodaj delegata „UITableViewDataSource”

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{ 
    return size;
}
bharath gangupalli
źródło
4
Chce ustawić szerokość, a nie wysokość
Christopher Pickslay
oh hoo. sry za niedogodności.
bharath gangupalli
źle rozumiesz pytanie i odpowiadasz na wysokość i wiesz, co to działa dla mnie, ponieważ szukam wysokości, a nie szerokości ... dzięki za odpowiedź
Pooja