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.