Jak ustawić pełną szerokość separatora w UITableView


149

Mam UITableViewgdzie separatory nie mają pełnej szerokości. Kończy się jak 10 pikseli przed lewą stroną. Bawiłem się tym kodem w viewDidLoad().

self.tableView.layoutMargins = UIEdgeInsetsZero;

Również w scenorysie, kiedy możesz wybrać selektory niestandardowe lub domyślne. Teraz wszystkie wypełnione komórki nie mają selektorów o pełnej szerokości, ale komórki, które są puste, mają pełną szerokość.

Jak mogę to naprawić?


9
UITableViewposiada własność separatorInset. Ustaw wstawkę UITableViewseparatora linii na zero. Możesz także zmienić separatorInsetz storyboardu
KRUKUSA

Odpowiedzi:


220

To zadziałało dla mnie na urządzeniach iOS 8.4 - 9.0 przy użyciu Xcode 6.4 i Swift 1.2:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    var cell = UITableViewCell()


    cell.preservesSuperviewLayoutMargins = false
    cell.separatorInset = UIEdgeInsetsZero
    cell.layoutMargins = UIEdgeInsetsZero

    return cell
}

Aktualizacja Swift 5:

cell.preservesSuperviewLayoutMargins = false
cell.separatorInset = UIEdgeInsets.zero
cell.layoutMargins = UIEdgeInsets.zero

Dlaczego to powoduje usunięcie mojej tabeli z pustą? Separatory są przesunięte, ale nie widzę żadnego z moich przycisków
Oscar

1
@James czy mógłbyś wyjaśnić „usunąć mój stół z pustym?”. Jak dodałeś swoje przyciski (przez IB, kod)?
MB_iOSDeveloper

1
Bardzo fajne rozwiązanie. Ale w moim przypadku wstawiłem kod bezpośrednio do inicjalizacji komórki, ponieważ chciałem mieć pełną szerokość separatora we wszystkich kontrolerach.
Vojta

Jeśli nie jest to oczywiste, działa to również dla Objective-C z poprawnymi zmianami składni.
cohenadair

1
Żadne z tych rozwiązań nie działa na iPadzie. Działa to tylko na iPhonie ...
Charles Robertson,

103

Otrzymałem odpowiedź z tego postu: Wstawka separatora UITableView w iOS 8 nie działa

Po prostu dodaj ten kod do swojego UITableViewController

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
        [cell setSeparatorInset:UIEdgeInsetsZero];
    }

    if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
        [cell setLayoutMargins:UIEdgeInsetsZero];
    }
}

-(void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
        [self.tableView setSeparatorInset:UIEdgeInsetsZero];
    }

    if ([self.tableView respondsToSelector:@selector(setLayoutMargins:)]) {
        [self.tableView setLayoutMargins:UIEdgeInsetsZero];
    }
}

2
to działa dla mnie do dodania tylko metody delegata tableView
TonyTony

Przepraszam, że nie zrozumiałem. Masz na myśli, że wystarczyło dodać TableViewDeleagte ?. Po prostu próbowałem dodać, że to nie działa dla mnie @TonyTony
Timo Cengiz

3
dla mnie metoda viewDidLayoutSubviewsnie jest konieczna
TonyTony

Czy próbowałeś uruchomić swój kod z innymi wersjami IOS niż 8? Może to działa w przypadku najnowszych. W przeciwnym razie dobrze, że to działa. Próbowałem po prostu dodać metodę delegata widoku tabeli i to nie pomogło. @TonyTony
Timo Cengiz

Musiałem użyć obu. Próbowałem używać każdego z osobna bez powodzenia. Działało tylko wtedy, gdy użyłem obu. Ponadto wypróbowałem to, gdy mój kontroler widoku był podklasą UITableViewController, a kiedy był podklasą UIViewController. Bez różnicy. Zauważ, że pracuję w symulatorze 8.1.
Ron

100

W Twoim UITableViewCell

Przejdź do Inspektora atrybutów w swoim Interface Builder i po prostu zmień „15” na 0. Zrób to dla wszystkich komórek, które chcesz zmienić.

instets

Może być konieczne dodanie [cell setLayoutMargins:UIEdgeInsetsZero];dotableViewCell


1
Albo to dziwne. To zadziałało dla mnie (dziękuję!) W wierszach, w których miały być wyświetlane UITableViewCells, ale we wszystkich pustych wierszach poniżej separator był nadal wcięty o 15 pikseli.
Mike Gledhill

Jeśli korzystasz z komórek statycznych, wystarczy zmienić lewą wstawkę na 0, jak opisano na obrazku (Praca w iOS 10, Xcode 8.3.1)
Ignacio Valdivieso

29

dla Swift 3:

override func viewDidLoad() {
  super.viewDidLoad()

  tableView.separatorInset = .zero
  tableView.layoutMargins = .zero
}

20
  1. Wybierz swój UITableViewCell
  2. Idź do Inspektora Atributes
  3. Idź do Separator i zmień go na „niestandardowe wstawki”
  4. Zestaw lefti / lub rightpola. (Domyślnie left: 15, right: 0)

Zobacz, jak to działa (używając left: 100):

wprowadź opis obrazu tutaj

Wynik:

wprowadź opis obrazu tutaj


1
duplikat poprzedniej odpowiedzi od @Hannah Louisa Carney
Konstantin Salavatov

19

Dziedziczę z UITableViewControllerdwóch ustawień wstawek i potrzebowałem ich dodatkowych, willDisplayCellaby ustawić wartość preservesSuperviewLayoutMarginsfałsz. W Swift wygląda to tak:

override func tableView(_tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {

    if cell.respondsToSelector("setSeparatorInset:") {
        cell.separatorInset = UIEdgeInsetsZero
    }
    if cell.respondsToSelector("setLayoutMargins:") {
        cell.layoutMargins = UIEdgeInsetsZero
    }
    if cell.respondsToSelector("setPreservesSuperviewLayoutMargins:") {
        cell.preservesSuperviewLayoutMargins = false
    }
}

Nie musisz ustawiać, preservesSuperviewLayoutMargins = falseponieważ wartość domyślna jest już false
crubio

2
Zwróć uwagę, że nie spowoduje to dostosowania separatorów w komórkach „zastępczych” wyświetlanych przez kontroler, aby wypełnić widok poniżej komórek, jeśli komórki nie zajmują pełnej wysokości.
Tieme

11

Separator Insetjest domyślnie ustawiony na 15 od lewej. Zmień Insetopcję separatora z autona customi ustaw wstawkę na 0.

wprowadź opis obrazu tutaj


9

Dla Swift w iOS 9+

Jeśli używasz niestandardowego UITableViewCell:

override var layoutMargins: UIEdgeInsets {
    get { return UIEdgeInsetsZero }
    set(newVal) {}
}

wtedy dla twojego UITableVieww viewDidLoad:

self.tableView?.separatorInset = UIEdgeInsetsZero;
self.tableView?.layoutMargins = UIEdgeInsetsZero;

To jedyna odpowiedź, która naprawiła to dla mnie (zaktualizowano do Swift 3). Jednak ... działa, gdy w komórce są dane. W przypadku pustych komórek, które nie zostały jeszcze wypełnione (i chyba nie nazwałem tej nadpisanej zmiennej layoutMargins) separator nadal nie wypełnia całej szerokości mojej niestandardowej komórki w widoku tabeli. Jakieś pomysły na to?
RanLearns

Na iPhonie separator kończy się zaledwie kilka pikseli od lewej i kilka pikseli od prawej na pustych komórkach. To wygląda dobrze bez użycia tej sztuczki do wyzerowania marginesów. Na iPadzie jest prawdziwy problem - separatory na pustej komórce wychodzą od lewej krawędzi widoku tabeli, tylko około 80% szerokości komórki. Kiedy w komórce znajdują się dane, separator nadal zajmuje 80% szerokości komórki, ale zaczyna się w 20% i przechodzi do prawej krawędzi widoku tabeli
RanLearns

1
Znalazłem rozwiązanie ... używając if #available (iOS 9, *) {self.tableView.cellLayoutMarginsFollowReadableWidth = false} sprawiło, że nie potrzebuję Twojego kodu na iPhonie. Separator przechodzi przez całą szerokość. Na iPadzie puste komórki mają separator o pełnej szerokości, ale potrzebuję Twojego kodu, aby zachować pełną szerokość po dodaniu danych. W przeciwnym razie po lewej stronie zostanie dodanych kilka pikseli, w których nie ma separatora po wypełnieniu komórki przez dane.
RanLearns

1
Odpowiedź, skąd otrzymałem kod w powyższym komentarzu z: stackoverflow.com/a/31538250/428981
RanLearns

9

Dla osób, które mają problemy z iPadem - dzięki temu uzyskasz taki sam stan jak iPhone. Następnie możesz dostosować w separatorInsetrazie potrzeby.

tableView.cellLayoutMarginsFollowReadableWidth = false

To był mój problem na iOS 10 i iOS 11. iOS 11 był w porządku, ale 10 miał inne marginesy. Dzięki!!!
migs647

9

Użyj go w cellForRowAtIndexPathmetodzie, aby skonfigurować specyfikacje separatora komórki,
działa idealnie na iOS9.0 +

 cell.separatorInset = UIEdgeInsetsZero;
 cell.layoutMargins = UIEdgeInsetsZero;
 cell.preservesSuperviewLayoutMargins = NO;

8

Przetestowano na iOS 9.3 i Swift 2.2. Upewnij się, że kod, willDisplayCellktóry jest wywoływany, znajduje się tuż przed wyświetleniem komórki, a nie w cellForRowAtIndexPathmiejscu, w którym tworzysz samą komórkę.

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    cell.separatorInset = UIEdgeInsetsZero
    cell.layoutMargins = UIEdgeInsetsZero
}

Dodaj overridedo funkcji UITableViewController, na przykład:

override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {

5

Żadne z powyższych nie działało dla mnie w Swift 2.2 i Xcode 7.3.1

Okazało się, że jest to najprostsze rozwiązanie ze wszystkich. Nie potrzeba żadnego kodu. Po prostu zmień TableViewCellwartości Layout Margins w swoim UITableViewInspektorze:


4

Dla Swift 3:

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
        cell.separatorInset = UIEdgeInsets.zero
    }
    if cell.responds(to: #selector(setter: UITableViewCell.layoutMargins)) {
        cell.layoutMargins = UIEdgeInsets.zero
    }
    if cell.responds(to: #selector(setter: UITableViewCell.preservesSuperviewLayoutMargins)) {
        cell.preservesSuperviewLayoutMargins = false
    }
}

1

W viewDidLoad (testowany iOS11 - swift 4.1)

próbować

tableView.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0)


0

Żadne z tych rozwiązań nie działa na iPadzie, ale wymyśliłem rozwiązanie, które obejmuje oba urządzenia:

Z ogniwami wielokrotnego użytku:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
    ...[other code]...
    [cell setLayoutMargins:UIEdgeInsetsZero];
    [cell setSeparatorInset:UIEdgeInsetsZero];
    return cell;
}

Z ogniwami jednorazowego użytku:

- (void)removeSeparatorInset:(UITableView*)tableView{
    NSArray *cells = [tableView visibleCells];
    for (UITableViewCell *cell in cells){
        [cell setLayoutMargins:UIEdgeInsetsZero];
        [cell setSeparatorInset:UIEdgeInsetsZero];
    }
}

-(void) viewDidLayoutSubviews{
   [super viewDidLayoutSubviews];
   [self removeSeparatorInset:self.tableView];
}

Aby rozwinąć to podejście:

@property(nonatomic) UIEdgeInsets separatorInset;
@property(nonatomic) UIEdgeInsets layoutMargins;

Obie właściwości mogą być używane przez UITableView& UITableViewCell. Ta ostatnia jest w rzeczywistości właściwością UIView, która jest klasą nadrzędną obu UITableView& UITableViewCell.


1
Jedyne działające rozwiązanie, które znalazłem dla komórek jednorazowego użytku
Mickey

0

swift 5, Xcode 11 Update

umieść to w widokuDidLoad ()

yourTableView.separatorInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)

dla separatora od krawędzi do krawędzi po prostu ustaw wartość lewego i prawego na 0.

przy okazji zmień „yourTableView” na nazwę TableView Outlet.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.