Jak dodać odstępy między UITableViewCell


182

Czy istnieje sposób na dodanie odstępów między UITableViewCell?

Utworzyłem tabelę, a każda komórka zawiera tylko obraz. Obraz jest przypisywany do komórki w następujący sposób:

cell.imageView.image = [myImages objectAtIndex:indexPath.row];

ale to sprawia, że ​​obraz jest powiększany i dopasowywany do całej komórki, a między obrazami nie ma odstępów.

Albo powiedzmy w ten sposób, wysokość obrazu to np. 50, a ja chcę dodać 20 odstępów między obrazami. Czy jest jakiś sposób, aby to osiągnąć?


1
Dla Swift 2.2 zobacz moją odpowiedź tutaj: stackoverflow.com/a/37673417/2696626
ibrahimyilmaz

Odpowiedzi:


160

Szybka wersja

Zaktualizowano dla Swift 3

Ta odpowiedź jest nieco bardziej ogólna niż pierwotne pytanie ze względu na przyszłych widzów. Jest to przykład uzupełniający do podstawowego przykładu UITableView dla języka Swift .

wprowadź opis obrazu tutaj

Przegląd

Podstawowym pomysłem jest utworzenie nowej sekcji (zamiast nowego wiersza) dla każdego elementu tablicy. Sekcje można następnie rozstawić na podstawie wysokości nagłówka sekcji.

Jak to zrobić

  • Skonfiguruj projekt zgodnie z opisem w przykładzie UITableView dla języka Swift . (Oznacza to, że należy dodać UITableViewi podłączyć tableViewwylot do kontrolera widoku).

  • W programie Interface Builder zmień kolor tła widoku głównego na jasnoniebieski, a UITableViewkolor tła na wyczyść.

  • Zastąp kod ViewController.swift następującym.

ViewController.swift

import UIKit
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
    
    // These strings will be the data for the table view cells
    let animals: [String] = ["Horse", "Cow", "Camel", "Sheep", "Goat"]
    
    let cellReuseIdentifier = "cell"
    let cellSpacingHeight: CGFloat = 5
    
    @IBOutlet var tableView: UITableView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // These tasks can also be done in IB if you prefer.
        self.tableView.register(UITableViewCell.self, forCellReuseIdentifier: cellReuseIdentifier)
        tableView.delegate = self
        tableView.dataSource = self
    }
    
    // MARK: - Table View delegate methods
    
    func numberOfSections(in tableView: UITableView) -> Int {
        return self.animals.count
    }
    
    // There is just one row in every section
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }
    
    // Set the spacing between sections
    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return cellSpacingHeight
    }
    
    // Make the background color show through
    func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
        let headerView = UIView()
        headerView.backgroundColor = UIColor.clear
        return headerView
    }
    
    // create a cell for each table view row
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        
        let cell:UITableViewCell = self.tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier) as UITableViewCell!
        
        // note that indexPath.section is used rather than indexPath.row
        cell.textLabel?.text = self.animals[indexPath.section]
        
        // add border and color
        cell.backgroundColor = UIColor.white
        cell.layer.borderColor = UIColor.black.cgColor
        cell.layer.borderWidth = 1
        cell.layer.cornerRadius = 8
        cell.clipsToBounds = true
        
        return cell
    }
    
    // method to run when table view cell is tapped
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        // note that indexPath.section is used rather than indexPath.row
        print("You tapped cell number \(indexPath.section).")
    }
}

Zauważ, że indexPath.sectionjest on używany raczej niż indexPath.roww celu uzyskania odpowiednich wartości dla elementów tablicy i pozycji zaczepów.

Jak uzyskałeś dodatkowe wypełnienie / przestrzeń po prawej i lewej stronie?

Mam to w ten sam sposób, w jaki dodajesz odstępy do dowolnego widoku. Użyłem ograniczeń układu automatycznego. Po prostu użyj narzędzia pinezki w Interface Builder, aby dodać odstępy dla wiodących i końcowych ograniczeń.


Cześć, zastanawiałem się, czy jest to możliwe bez konwertowania wszystkich twoich wierszy na sekcje. Mam obramowania na każdym tableViewCell, więc zwiększenie wysokości nie pomoże. Mam wiele dostosowań w mojej komórce i nie chcę konwertować jej na sekcje. Dzięki!
Ujjwal-Nadhani

3
@ user2901306, na początku wahałem się przed użyciem tej metody, również dlatego, że czułem, że powinienem być w stanie po prostu użyć wierszy i zwiększyć margines lub coś w tym stylu. Jednak nie znalazłem sposobu, aby to zrobić i ta metoda działała całkiem dobrze. Nie musisz zmieniać dostosowań w swojej komórce. W zasadzie wystarczy dodać numberOfSectionsInTableViewi return 1dla liczby wierszy. Następnie użyj, indexPath.sectionaby uzyskać bieżący indeks komórki. Spróbuj raz. Myślę, że odkryjesz, że nie musisz wprowadzać zbyt wielu zmian w swojej obecnej konfiguracji. Jest to zdecydowanie łatwiejsze niż tworzenie podklas.
Suragch

Korzystanie z cell.layer.xxx w cellForRow może dać ci hit w wydajności. Lepiej ustaw te wartości w XIB
Abhishek Bedi,

@AbhishekBedi, zawsze uważałem, że layermanipulacje są dość szybkie. Czy mówisz to, ponieważ zauważyłeś hit wydajnościowy, czy jako ogólną dobrą praktykę? Nawet jeśli ustawisz je w XIB, nadal muszą być ustawione podczas tworzenia komórki.
Suragch

1
@FateNuller, nie zgadzam się z tobą. Odpowiedź Husama wygląda całkiem nieźle.
Suragch

150

Moje proste rozwiązanie przy użyciu Swift :

// Inside UITableViewCell subclass

override func layoutSubviews() {
    super.layoutSubviews()

    contentView.frame = contentView.frame.inset(by: UIEdgeInsets(top: 10, left: 10, bottom: 10, right: 10))
}

Wynik wprowadź opis obrazu tutaj


11
Niezłe rozwiązanie. Gdyby ktoś miał problemy, musiałem super.layoutSubviews()najpierw zadzwonić, aby upewnić się, że cały widok został prawidłowo rozplanowany przed ustawieniem ramki.
ruttopia,

@Husam Twoje rozwiązanie zadziałało dla mnie. Ale mam problem przy wybranej komórce. Ustawiłem obramowanie dla contentView i za każdym razem, gdy wybiorę komórkę, obramowanie będzie mniejsze. Jak mogę to naprawić?
Bad_Developer,

@SonHoang Być może trzeba przesłonić didSetdla selectedzmiennej i połączeń layoutSubviews()wewnątrz!
Husam

1
Hej, Husam. Dzięki za świetne rozwiązanie. Nie mów mi, jak zmienić kolor dodanej zawartości między komórkami?
A.Kant

1
To o wiele lepsze rozwiązanie niż przyjęta odpowiedź. Przyjęta odpowiedź ma cholernie blisko 100 linii kodu, a to tylko jedna. Niesamowite.
YungGun

135

Sposobem dodawania odstępów między komórkami jest ustawienie numberOfSections = "Twoja liczba tablic" i sprawienie, że każda sekcja zawiera tylko jeden wiersz. Następnie zdefiniuj headerView i jego wysokość.

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return yourArry.count;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return 1;
}

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return cellSpacingHeight;
}

-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    UIView *v = [UIView new];
    [v setBackgroundColor:[UIColor clearColor]];
    return v;
}

22
To działa świetnie. Musiałem trochę zmienić cellForRowAtIndexPath, nie normalną tablicę [indexPath.row], ale tablicę [indexPath.section]. W przeciwnym razie pokaże pierwszy element tablicy we wszystkich sekcjach.
Tom Spee,

@TomSpee - Jak rozwiązałeś ten problem w cellForRowAtIndexPath?

5
@TKutal - Tak jak normalny kod w cellForRowAtIndexPath, ale zmień indexPath.row na indexPath.section
Tom Spee

Chociaż pozwala to osiągnąć to, czego pragnie pytający, nie sądzę, aby firma Apple zalecała takie podejście. Popraw mnie, jeśli się mylę, ale uważam, że „sekcje” służą do logicznego oddzielania „sekcji” danych, które reprezentujesz w tabeli. Nie powinieneś używać „sekcji” do nadawania stylu odstępom między każdą komórką danych, które w przeciwnym razie powinny być wyświetlane w jednej sekcji. Myślę, że lepszym podejściem, choć trudniejszym, byłoby utworzenie podklasy UITableViewCell i zasymulowanie separatora widoku tabeli przez dodanie widoku na dole komórki.
FateNuller

2
Wtedy Apple nie powinno raczej narzekać, ale stworzyć wygodny sposób na zróżnicowanie przestrzeni między rzędami.
Arnie Schwarzvogel

44

Musiałem zastosować tę samą koncepcję, aby komórki UITableCell miały „przestrzeń” między nimi. Ponieważ nie możesz dosłownie dodać spacji między komórkami, możesz to sfałszować, manipulując wysokością komórki UITableView, a następnie dodając UIView do contentView swojej komórki. Oto zrzut ekranu prototypu, który wykonałem w innym projekcie testowym, kiedy to symulowałem:

Odstępy między UITableViewCells

Oto kod (uwaga: istnieje wiele wartości zakodowanych na stałe do celów demonstracyjnych)

Najpierw musiałem ustawić, heightForRowAtIndexPathaby zezwolić na różne wysokości w UITableViewCell.

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{

    NSString *text = [self.newsArray  objectAtIndex:[indexPath row]];
    if ([text isEqual:@"December 2012"])
    {
        return 25.0;
    }

    return 80.0;
}

Następnie chcę manipulować wyglądem i działaniem UITableViewCells, więc robię to w willDisplayCell:(NewsUITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPathmetodzie.

- (void)tableView:(UITableView *)tableView willDisplayCell:(NewsUITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (cell.IsMonth)
    {
        UIImageView *av = [[UIImageView alloc] initWithFrame:CGRectMake(20, 20, 20, 20)];
        av.backgroundColor = [UIColor clearColor];
        av.opaque = NO;
        av.image = [UIImage imageNamed:@"month-bar-bkgd.png"];
        UILabel *monthTextLabel = [[UILabel alloc] init];
        CGFloat font = 11.0f;
        monthTextLabel.font = [BVFont HelveticaNeue:&font];

        cell.backgroundView = av;
        cell.textLabel.font = [BVFont HelveticaNeue:&font];
        cell.textLabel.textColor = [BVFont WebGrey];
    }


    if (indexPath.row != 0)
    {
        cell.contentView.backgroundColor = [UIColor clearColor];
        UIView *whiteRoundedCornerView = [[UIView alloc] initWithFrame:CGRectMake(10,10,300,70)];
        whiteRoundedCornerView.backgroundColor = [UIColor whiteColor];
        whiteRoundedCornerView.layer.masksToBounds = NO;
        whiteRoundedCornerView.layer.cornerRadius = 3.0;
        whiteRoundedCornerView.layer.shadowOffset = CGSizeMake(-1, 1);
        whiteRoundedCornerView.layer.shadowOpacity = 0.5;
        [cell.contentView addSubview:whiteRoundedCornerView];
        [cell.contentView sendSubviewToBack:whiteRoundedCornerView];

    }
}

Zwróć uwagę, że zrobiłem mój whiteRoundedCornerView wysokość 70,0 i to właśnie powoduje symulowaną przestrzeń, ponieważ wysokość komórki wynosi w rzeczywistości 80,0, ale mój contentView to 70,0, co nadaje mu wygląd.

Mogą istnieć inne sposoby na osiągnięcie tego jeszcze lepiej, ale właśnie tak znalazłem, jak to zrobić. Mam nadzieję, że pomoże to komuś innemu.


Tylko FYI, dla bardzo dużej liczby komórek, chciałbyś ustawić widok zawartości wewnątrz podklasy komórki zamiast willDisplayCell. Wydajność zaczyna być ogromna, robiąc to w ten sposób, im więcej komórek dodasz do kolejki
BBH1023

@ BBH1023 Warstwa cienia mnoży się za każdym razem, gdy pojawia się widok podczas nawigacji tam i z powrotem w celu szybkiego podglądu. Jak byś zasugerował anulowanie tego, jeśli zostało już raz zastosowane
soulshined

aby privent dodać więcej cienia, wykonaj następujące czynności: NSInteger tag = 120; if (indexPath.row! = 0) {if (cell.tag! = 120) {cell.contentView.backgroundColor = [UIColor clearColor]; ... [cell.contentView sendSubviewToBack: whiteRoundedCornerView]; cell.tag = tag; }}
user3001228

24

Będziesz musiał ustawić ramkę do swojego obrazu. Niesprawdzony kod to

cell.imageView.frame = CGRectOffset(cell.frame, 10, 10);

2
Właśnie przetestowany z backgroundView i jest to najprostsze działające rozwiązanie
Sam

2
Tylko upewnij się, że wywołujesz ten kod, layoutSubviewsjeśli tworzysz podklasyUITableViewCell
Mazyod

30
@ NicoHämäläinen Cóż, w ciągu ostatnich trzech lat opracowałem ponad 20 aplikacji i ZAWSZE tworzyłem podklasy UITableViewCell, aby uzyskać wynik, którego potrzebuję :) ... Podklasy UITableViewCellsą bardzo powszechne.
Mazyod

1
@ NicoHämäläinen nie ma nic złego w tworzeniu podklas UITableViewCell. Podczas tworzenia niestandardowych UITableViewCellsnależy tworzyć podklasy UITableViewCell.
Popeye

1
@ NicoHämäläinen powinieneś zaktualizować swój komentarz. Ludzie mają tendencję do chwytania informacji i nie czytają dalej. Ponieważ ta strona jest świetnym źródłem informacji, a programiści mają tendencję do ufania faktom, które tu widzą, może to ich wprowadzić w błąd, aby myśleli o strasznych rzeczach… tylko moje dwie monety. Może mam histerię
chrs

11

Byłem na tej samej łodzi. Na początku próbowałem przejść do sekcji, ale w moim przypadku okazało się, że przyprawiło to o ból głowy bardziej, niż początkowo sądziłem, więc szukałem alternatywy. Aby nadal używać wierszy (i nie mieszać w sposobie uzyskiwania dostępu do danych modelu), oto co zadziałało dla mnie po prostu przy użyciu maski :

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath)
{
    let verticalPadding: CGFloat = 8

    let maskLayer = CALayer()
    maskLayer.cornerRadius = 10    //if you want round edges
    maskLayer.backgroundColor = UIColor.black.cgColor
    maskLayer.frame = CGRect(x: cell.bounds.origin.x, y: cell.bounds.origin.y, width: cell.bounds.width, height: cell.bounds.height).insetBy(dx: 0, dy: verticalPadding/2)
    cell.layer.mask = maskLayer
}

Pozostało tylko zwiększyć wysokość komórki o taką samą wartość, jak żądana verticalPadding, a następnie zmodyfikować układ wewnętrzny, aby wszystkie widoki, które miały odstępy od krawędzi komórki, miały ten sam odstęp zwiększony o verticalPadding/2. Drobna wada: verticalPadding/2dopełnienie uzyskuje się zarówno u góry, jak iu dołu tableView, ale można to szybko naprawić, ustawiając tableView.contentInset.bottom = -verticalPadding/2i tableView.contentInset.top = -verticalPadding/2. Mam nadzieję, że to komuś pomoże!


1
Działa również w Swift 5.
LondonGuy

1
Najlepsza odpowiedź!! Dziękuję Ci. Jeśli używasz niestandardowej komórki, działa to w funkcji „override func awakeFromNib ()”
trees_are_great

10

Myślę, że najprostszym rozwiązaniem, jeśli szukasz tylko trochę miejsca i prawdopodobnie najmniej kosztownego, byłoby po prostu ustawienie koloru obramowania komórki na kolor tła tabel, a następnie ustawienie szerokości obramowania, aby uzyskać pożądany efekt!

    cell.layer.borderColor = blueColor.CGColor
    cell.layer.borderWidth = 3

1
Nie jest to dobry pomysł na przezroczyste tło. W przeciwnym razie może działać.
ergunkocak

1
To prawda. Nie jest to rozwiązanie dla wszystkich przypadków, ale w niektórych zadziała! @ergunkocak
Craig

8

Jeśli nie używasz jeszcze nagłówków (lub stopek) sekcji, możesz ich użyć, aby dodać dowolne odstępy do komórek tabeli. Zamiast mieć jedną sekcję z n wierszami, utwórz tabelę z n sekcjami z jednym wierszem w każdej.

Zaimplementuj tableView:heightForHeaderInSection:metodę, aby kontrolować odstępy.

Możesz również chcieć zaimplementować, tableView:viewForHeaderInSection:aby kontrolować wygląd odstępów.


8

Rozwiązałem to w ten sposób w Swift 4.

Tworzę rozszerzenie UITableViewCell i dołączam ten kod:

override open var frame: CGRect {
    get {
        return super.frame
    }
    set (newFrame) {
        var frame =  newFrame
        frame.origin.y += 10
        frame.origin.x += 10
        frame.size.height -= 15
        frame.size.width -= 2 * 10
        super.frame = frame
    }
}

override open func awakeFromNib() {
    super.awakeFromNib()
    layer.cornerRadius = 15
    layer.masksToBounds = false
}

Mam nadzieję, że Ci to pomoże.


tekst w komórce jest przycięty.
Mehdico

nadpisywanie CGRect działa, a ja nie dodałem jednego awakeFromNib.
Eric Tan

5

Przykład w Swift 3 ..

wprowadź opis obrazu tutaj

  1. Utwórz aplikację z pojedynczym widokiem
  2. dodaj widok tabeli w kontrolerze widoku
  3. dodaj komórkę niestandardową do komórki tablview
  4. Wyświetl kod kontrolera poniżej

       class ViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
    
       @IBOutlet weak var tableView: UITableView!
    
    
        var arraytable = [[String:Any]]()
         override func viewDidLoad() {
         super.viewDidLoad()
    
         arraytable = [
         ["title":"About Us","detail":"RA-InfoTech Ltd -A Joint Venture IT Company formed by Bank Asia Ltd"],
         ["title":"Contact","detail":"Bengal Center (4th & 6th Floor), 28, Topkhana Road, Dhaka - 1000, Bangladesh"]
    ]
    
    
    
    
    
    
       tableView.delegate = self
       tableView.dataSource = self
    
       //For Auto Resize Table View Cell;
      tableView.estimatedRowHeight = 44
       tableView.rowHeight = UITableViewAutomaticDimension
    
       //Detault Background clear
       tableView.backgroundColor = UIColor.clear
    }

    func numberOfSections (in tableView: UITableView) -> Int {return arraytable.count}

       func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
     return 1
     }
    
    // Set the spacing between sections
     func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 10
    }
    
    // Make the background color show through
      func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    let headerView = UIView()
    headerView.backgroundColor = UIColor.clear
    
    return headerView
    }
    
         func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    
         let cell = tableView.dequeueReusableCell(withIdentifier: "cell")! as! CustomCell
    
         cell.tv_title.text = arraytable[indexPath.section]["title"] as! String?
        cell.tv_details.text = arraytable[indexPath.section]["detail"] as! String?
    
       //label height dynamically increase
       cell.tv_details.numberOfLines = 0
    
    
    
    
       //For bottom border to tv_title;
       let frame =  cell.tv_title.frame
        let bottomLayer = CALayer()
       bottomLayer.frame = CGRect(x: 0, y: frame.height - 1, width: frame.width, height: 1)
        bottomLayer.backgroundColor = UIColor.black.cgColor
       cell.tv_title.layer.addSublayer(bottomLayer)
    
      //borderColor,borderWidth, cornerRadius
      cell.backgroundColor = UIColor.lightGray
      cell.layer.borderColor = UIColor.red.cgColor
      cell.layer.borderWidth = 1
      cell.layer.cornerRadius = 8
      cell.clipsToBounds = true
    
      return cell
      }
    
       }
  5. Pobierz pełne źródło na Github: link

    https://github.com/enamul95/CustomSectionTable


dubluje inną odpowiedź, na którą wcześniej udzielono odpowiedzi na @Suragch w sprawie szybkiej wersji, proszę unikać duplikowania
Amr Angry

1
to nie jest dobre rozwiązanie. Jeśli potrzebujesz sekcji nagłówka z tytułem, to nie zadziała
kuzdu

4

Trzy podejścia, które przychodzą mi do głowy:

  1. Utwórz niestandardową komórkę tabeli, która przedstawia widok całej komórki w żądany sposób

  2. Zamiast dodawać obraz do widoku obrazu, wyczyść podglądy widoku obrazu, utwórz widok niestandardowy, który dodaje UIImageView dla obrazu i inny widok, być może prosty UIView, który zapewnia żądane odstępy, i dodaj go jako widok podrzędny widok obrazu.

  3. Chcę zasugerować, abyś bezpośrednio manipulował UIImageView, aby ustawić stały rozmiar / dopełnienie, ale nie jestem w pobliżu Xcode, więc nie mogę potwierdzić, czy / jak to zadziała.

Czy to ma sens?


4

Tak, możesz zwiększyć lub zmniejszyć odstępy (wypełnienie) między dwiema komórkami, tworząc jeden widok bazowy w widoku zawartości w komórce.Ustaw wyraźny kolor tła widoku zawartości i możesz dostosować wysokość widoku bazowego, aby utworzyć odstęp między komórkami.


4

Na podstawie odpowiedzi Husama: użycie warstwy komórek zamiast widoku zawartości umożliwia dodanie obramowania wokół całej komórki i akcesoriów w razie potrzeby. Ta metoda wymaga starannego dostosowania dolnych ograniczeń komórki, a także tych wstawek, w przeciwnym razie widok nie będzie właściwy.

@implementation TableViewCell

- (void)awakeFromNib { 
    ... 
}

- (void) layoutSubviews {
    [super layoutSubviews];

    CGRect newFrame = UIEdgeInsetsInsetRect(self.layer.frame, UIEdgeInsetsMake(4, 0, 4, 0));
    self.layer.frame = newFrame;
}

@end

3

Zmień liczbę wierszy w sekcji na 1 Zmieniłeś liczbę sekcji zamiast liczby wierszy

 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        1
    }

    func numberOfSections(in tableView: UITableView) -> Int {
        return 2
    }

Tutaj wstawiasz odstępy między rzędami

 func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
        return 50
    }

2

Myślę, że to najczystsze rozwiązanie:

class MyTableViewCell: UITableViewCell {
    override func awakeFromNib() {
        super.awakeFromNib()
        layoutMargins = UIEdgeInsetsMake(8, 0, 8, 0)
    }
}

1
Po zastosowaniu w layoutMarginsten sposób nie widziałem żadnej wizualnej zmiany . Może dlatego, że używam autoukładu.
Cœur

Marginesy nie „złamałyby” wyraźnej wysokości komórki, więc aby to zadziałało, musisz mieć automatyczną wysokość komórek
Aviel Gross,

1
Mam automatyczną wysokość.
Cœur

2

Ten artykuł pomógł, to mniej więcej to, co powiedziały inne odpowiedzi, ale podsumowujące i zwięzłe

https://medium.com/@andersongusmao/left-and-right-margins-on-uitableviewcell-595f0ba5f5e6

W nim stosuje je tylko do lewej i prawej strony, ale UIEdgeInsetsMake init pozwala na dodanie wypełnienia do wszystkich czterech punktów.

func UIEdgeInsetsMake (_ top: CGFloat, _ left: CGFloat, _ bottom: CGFloat, _ right: CGFloat) -> UIEdgeInsets

Opis
Tworzy wstawkę krawędzi dla przycisku lub widoku. Wstawka to margines wokół prostokąta. Wartości dodatnie reprezentują marginesy bliżej środka prostokąta, podczas gdy wartości ujemne reprezentują marginesy dalej od środka.

Parametry
top: Wstawka na górze obiektu.
left: Wstawka po lewej stronie
dołu obiektu : Wstawka na dole obiektu.
po prawej: wstawka po prawej stronie obiektu.

Zwraca
Wstawkę do przycisku lub widoku

Zauważ, że UIEdgeInsets można również osiągnąć to samo.

Xcode 9.3 / Swift 4


Ta odpowiedź błędnie mówi, że kod jest zgodny ze Swift 4, ale UIEdgeInsetsMake jest przestarzały. Zamiast tego należy użyć UIEdgeInsets.
José

developer.apple.com/documentation/uikit/ ... gdzie dokładnie jest napisane, że zostało wycofane? Używam tego w moich projektach i pracuję z najnowszym Xcode, dlatego Swift 9.3 @ José
Mauricio Chirino

Masz rację, przepraszam, moja wina. Preferowany jest UIEdgeInsets, ale to nie znaczy, że drugi jest przestarzały. SwiftLint będzie jednak narzekał na starszy konstruktor podczas korzystania z UIEdgeInsetsMake.
José

1
Ok, rozumiem. Usuń głos przeciw, jeśli to ty oddałeś głos. Nigdy nie powiedziałem, że moja odpowiedź jest jedyna możliwa.
Mauricio Chirino

Mówi, że nie mogę zmienić swojego głosu, dopóki nie zmienisz odpowiedzi. Czy możesz trochę poprawić sformułowanie?
José

2

Używanie kilku różnych sekcji nie jest potrzebne. Inne odpowiedzi wykorzystują wstawki ramek, CGRect i warstwy oraz ... BLAH. Niedobrze; użyj automatycznego układu i niestandardowego UITableViewCell. W tym UITableViewCell, zamiast wyświetlać zawartość wewnątrz contentView, utwórz nowy containerView (UIView), wyświetl widok kontenera w ramach contentView, a następnie przejrzyj wszystkie widoki w widoku kontenera.

Aby wprowadzić odstępy teraz, po prostu edytuj marginesy układu widoku kontenera, na przykład:

class CustomTableViewCell: UITableViewCell {
    let containerView = UIView()
    let imageView = UIImageView()

    required init?(coder aDecoder: NSCoder) {super.init(coder: aDecoder)}

    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        containerView.translatesAutoResizingMaskIntoConstraints = false
        imageView.translatesAutoResizingMaskIntoConstraints = false
        contentView.addSubview(containerView)
        containerView.addSubview(imageView)

        contentView.layoutMargins = UIEdgeInsets(top: 15, left: 3, bottom: 15, right: 3)
        containerView.layoutMargins = UIEdgeInsets(top: 15, left: 17, bottom: 15, right: 17) // It isn't really necessary unless you've got an extremely complex table view cell. Otherwise, you could just write e.g. containerView.topAnchor

        let cg = contentView.layoutMarginsGuide
        let lg = containerView.layoutMarginsGuide
        NSLayoutConstraint.activate([
            containerView.topAnchor.constraint(equalTo: cg.topAnchor),
            containerView.leadingAnchor.constraint(equalTo: cg.leadingAnchor),
            containerView.trailingAnchor.constraint(equalTo: cg.trailingAnchor),
            containerView.bottomAnchor.constraint(equalTo: cg.bottomAnchor),
            imageView.topAnchor.constraint(equalTo: lg.topAnchor),
            imageView.leadingAnchor.constraint(equalTo: lg.leadingAnchor),
            imageView.trailingAnchor.constraint(equalTo: lg.trailingAnchor),
            imageView.bottomAnchor.constraint(equalTo: lg.bottomAnchor)
        ])
    }
}


1

Moja sytuacja była taka, że ​​użyłem niestandardowego UIView, aby viewForHeader w sekcji również heightForHeader w sekcji zwrócić stałą wysokość, powiedzmy 40, problem polegał na tym, że nie ma danych, wszystkie widoki nagłówka zostały ze sobą dotknięte. więc chciałem ustawić odstęp między sekcją w przypadku braku danych, więc naprawiłem go, zmieniając po prostu płaszczyznę „stylu tabeli” na „Grupa”. I to zadziałało.


1

Sprawdź moje rozwiązanie na GitHub z podklasą UITableViewi korzystaniem z funkcji środowiska uruchomieniowego Objective-C.
Zasadniczo wykorzystuje prywatną strukturę danych Apple UITableViewRowData, którą uzyskałem, wyszukując prywatny nagłówek środowiska uruchomieniowego UITableView:

https://github.com/JaviSoto/iOS10-Runtime-Headers/blob/master/Frameworks/UIKit.framework/UITableView.h ,

a oto pożądana klasa prywatna, która zawiera wszystko, czego potrzebujesz, aby rozmieścić odstępy między komórkami w dowolny sposób, bez ustawiania ich w klasach komórek:

https://github.com/JaviSoto/iOS10-Runtime-Headers/blob/master/Frameworks/UIKit.framework/UITableViewRowData.h


1

Miałem problem z uruchomieniem tego razem z kolorami tła i widokami akcesoriów w komórce. Skończyło się na:

1) Ustaw właściwość widoku tła komórek za pomocą zestawu UIView z kolorem tła.

let view = UIView()
view.backgroundColor = UIColor.white
self.backgroundView = view

2) Zmień położenie tego widoku w layoutSubviews, aby dodać ideę odstępów

override func layoutSubviews() {
    super.layoutSubviews()
    backgroundView?.frame = backgroundView?.frame.inset(by: UIEdgeInsets(top: 2, left: 0, bottom: 0, right: 0)) ?? CGRect.zero
}

1

Używanie nagłówków jako odstępów działałoby dobrze, jeśli nie chcesz używać żadnych nagłówków. W przeciwnym razie prawdopodobnie nie jest to najlepszy pomysł. Myślę o utworzeniu niestandardowego widoku komórki.

Przykłady:

W komórce niestandardowej utwórz widok tła z ograniczeniami, aby nie wypełniał całej komórki, nadaj jej trochę wypełnienia.

Następnie spraw, aby tło widoku tabeli było niewidoczne i usuń separatory:

// Make the background invisible
tableView.backgroundView = UIView()
tableView.backgroundColor = .clear

// Remove the separators
tableview.separatorStyle = .none

1

Jeśli nie chcesz zmieniać sekcji i numeru wiersza widoku tabeli (tak jak ja), oto co musisz zrobić:

1) Dodaj ImageView na dole widoku komórki tabeli.

2) Ustaw ten sam kolor, co kolor tła widoku tabeli.

Zrobiłem to w mojej aplikacji i działa idealnie. Twoje zdrowie! :RE


0

wprowadź opis obrazu tutajSWift-5, odstępy między UITableViewCell

    1. use sections instead of rows
    2. each section should return one row
    3. assign your cell data like this e.g [indexPath.section], instead of row
    4. use UITableView Method "heightForHeader" and return your desired spacing
    5. Do rest things as you were doing it

    Thanks!

0

Możesz po prostu użyć ograniczenia w kodzie w następujący sposób:

class viewCell : UITableViewCell 
{

@IBOutlet weak var container: UIView!



func setShape() {
    self.container.backgroundColor = .blue
    self.container.layer.cornerRadius = 20
    container.translatesAutoresizingMaskIntoConstraints = false
    self.container.widthAnchor.constraint(equalTo:contentView.widthAnchor , constant: -40).isActive = true
           self.container.heightAnchor.constraint(equalTo: contentView.heightAnchor,constant: -20).isActive = true
           self.container.centerXAnchor.constraint(equalTo: contentView.centerXAnchor).isActive = true
           self.container.centerYAnchor.constraint(equalTo: contentView.centerYAnchor).isActive = true

    }
}

ważne jest, aby dodać widok podrzędny (kontener) i umieścić w nim inne elementy.


-2

dodaj widok wewnętrzny do komórki, a następnie dodaj do niej własne widoki.


-2

Rozwiązanie Swift 5.0

W podklasie UITableViewCell

override func layoutSubviews() {
    super.layoutSubviews()
    let padding = UIEdgeInsets(top: 0, left: 0, bottom: 10, right: 0)
    bounds = UIEdgeInsetsInsetRect(bounds, padding)
}

-4

Użyj UITableViewDelegate heightForRowAtIndexPathi zwróć wysokość wiersza.

 (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
 return 100.0f ;
}

Pytanie brzmi, jak dodać odstępy między komórkami, a nie wysokość komórki
shippo7
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.