Inset pemisah UITableView iOS 8 0 tidak berfungsi

662

Saya memiliki aplikasi tempat UITableViewinset pemisah diatur ke nilai khusus - Kanan 0, Kiri 0. Ini berfungsi dengan baik iOS 7.x, namun dalam iOS 8.0saya melihat bahwa inset pemisah diatur ke default 15di sebelah kanan. Meskipun dalam file xib yang diaturnya 0, masih muncul salah.

Bagaimana cara menghapus UITableViewCellmargin pemisah?

pengguna3570727
sumber
Sudahkah Anda mencoba mengatur inset menjadi 0,001 bukannya 0? Saya ingat memiliki masalah yang sama di mana inset tepi tidak akan bereaksi terhadap 0 tetapi bereaksi terhadap 0,001 (atau sesuatu yang serupa kecil).
freshking
Saya mencoba itu dan tidak berhasil juga ..
user3570727
4
Kemudian saya akan menyarankan untuk mengatur warna pemisah [UIColor clearColor]dan menggambar pemisah Anda sendiri. Anda jauh lebih fleksibel dengan cara itu.
freshking
1
Saya masih tidak percaya bahwa ini masih bukan salah satu UITableViewCellSeparatorStyledefault. Bahkan jawaban yang diterima adalah hack yang sangat kotor menurut saya.
Enrico Susatyo

Jawaban:

1071

iOS 8.0 memperkenalkan properti layoutMargins pada tampilan sel DAN tabel.

Properti ini tidak tersedia di iOS 7.0 jadi Anda perlu memastikan Anda memeriksa sebelum menugaskannya!

Perbaikan yang mudah adalah dengan subkelas sel Anda dan menimpa properti tata letak margin seperti yang disarankan oleh @ user3570727. Namun Anda akan kehilangan perilaku sistem seperti mewarisi margin dari Area Aman jadi saya tidak merekomendasikan solusi di bawah ini:

(ObjectiveC)

-(UIEdgeInsets)layoutMargins { 
     return UIEdgeInsetsZero // override any margins inc. safe area
}

(cepat 4.2):

override var layoutMargins: UIEdgeInsets { get { return .zero } set { } }

Jika Anda tidak ingin menimpa properti, atau perlu mengaturnya secara kondisional, teruskan membaca.


Selain layoutMarginsproperti, Apple telah menambahkan properti ke sel Anda yang akan mencegahnya mewarisi pengaturan margin Table View Anda. Saat properti ini disetel, sel Anda diizinkan untuk mengonfigurasi marginnya sendiri secara terpisah dari tampilan tabel. Anggap saja sebagai penggantian.

Properti ini dipanggil preservesSuperviewLayoutMargins, dan pengaturannya NOakan memungkinkan pengaturan sel layoutMarginuntuk menimpa apa pun layoutMarginyang diatur pada TableView Anda. Keduanya menghemat waktu ( Anda tidak perlu mengubah pengaturan Tampilan Tabel ), dan lebih ringkas. Silakan merujuk ke jawaban Mike Abdullah untuk penjelasan terperinci.

CATATAN: yang berikut adalah implementasi bersih untuk pengaturan margin level sel , seperti yang dinyatakan dalam jawaban Mike Abdullah. Pengaturan sel AndapreservesSuperviewLayoutMargins=NO akan memastikan bahwa Tampilan Tabel Anda tidak mengesampingkan pengaturan sel. Jika Anda benar-benar ingin seluruh tampilan tabel memiliki margin konsisten, harap sesuaikan kode Anda.

Siapkan margin sel Anda:

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

    // Prevent the cell from inheriting the Table View's margin settings
    if ([cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)]) {
        [cell setPreservesSuperviewLayoutMargins:NO];
    }

    // Explictly set your cell's layout margins
    if ([cell respondsToSelector:@selector(setLayoutMargins:)]) {
        [cell setLayoutMargins:UIEdgeInsetsZero];
    }
}

Swift 4:

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    // Remove seperator inset
    if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
        cell.separatorInset = .zero
    }
    // Prevent the cell from inheriting the Table View's margin settings
    if cell.responds(to: #selector(setter: UITableViewCell.preservesSuperviewLayoutMargins)) {
        cell.preservesSuperviewLayoutMargins = false
    }
    // Explictly set your cell's layout margins
    if cell.responds(to: #selector(setter: UITableViewCell.layoutMargins)) {
        cell.layoutMargins = .zero
    }
}

Menyetel preservesSuperviewLayoutMarginsproperti pada sel Anda ke NO harus mencegah tampilan tabel Anda mengesampingkan margin sel Anda. Dalam beberapa kasus, sepertinya tidak berfungsi dengan baik.

Jika semuanya gagal, Anda dapat memaksa margin Table View Anda:

-(void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];

    // Force your tableview margins (this may be a bad idea)
    if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) {
        [self.tableView setSeparatorInset:UIEdgeInsetsZero];
    }

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

Swift 4:

func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    // Force your tableview margins (this may be a bad idea)
    if tableView.responds(to: #selector(setter: UITableView.separatorInset)) {
        tableView.separatorInset = .zero
    }
    if tableView.responds(to: #selector(setter: UITableView.layoutMargins)) {
        tableView.layoutMargins = .zero
    }
}

... dan itu dia! Ini harus bekerja di iOS 7 dan 8.


EDIT: Mohamed Saleh dibawa ke perhatian saya kemungkinan perubahan di iOS 9. Anda mungkin perlu mengatur Table View ini cellLayoutMarginsFollowReadableWidthuntukNO jika Anda ingin menyesuaikan insets atau margin. Jarak tempuh Anda mungkin bervariasi, ini tidak didokumentasikan dengan baik.

Properti ini hanya ada di iOS 9 jadi pastikan untuk memeriksa sebelum pengaturan.

if([myTableView respondsToSelector:@selector(setCellLayoutMarginsFollowReadableWidth:)])
{
    myTableView.cellLayoutMarginsFollowReadableWidth = NO;
} 

Swift 4:

if myTableView.responds(to: #selector(setter: self.cellLayoutMarginsFollowReadableWidth)) {
    myTableView.cellLayoutMarginsFollowReadableWidth = false
}

(kode di atas dari iOS 8 UITableView separator inset 0 tidak berfungsi )

EDIT: Berikut ini pendekatan Pembuat Antarmuka murni:

TableViewAttributesInspector TableViewCellSizeInspector

CATATAN: iOS 11 mengubah & menyederhanakan banyak perilaku ini, pembaruan akan segera ...

cdstamper
sumber
2
Untuk tampilan tabel di dalam UIPopoverController, saya harus melakukan keduanya seperti yang ditunjukkan di atas, bukan hanya di willDisplayCell.
Zhang
44
Saya juga menemukan bahwa terlepas dari semua kode di atas saya masih harus menambahkan saran cell.preservesSuperviewLayoutMargins = NOper @ bffmike atau setelah menggulir cara inset akan muncul. (wtf ??)
inorganik
Bagaimana jika kita ingin mengatur margin hanya untuk satu jenis sel dalam tableView yang dikelompokkan?
SAHM
Anda dapat mencoba mengaturnya di willDisplayCell dan melihat apakah itu benar-benar berfungsi (Anda memiliki pegangan pada sel sehingga harus sepele). Jika tidak, kita perlu mengajukan bug. Margin tata letak spesifik sel harus dimungkinkan, IMO.
cdstamper
2
Ini bekerja untuk saya dengan penambahan cell.preservesSuperviewLayoutMarginsdalam metode sumber data saya:- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
mts
257

Arg !!! Setelah bermain-main baik melakukan ini di Cellsubclass Anda :

- (UIEdgeInsets)layoutMargins
{
    return UIEdgeInsetsZero;
}

atau mengatur cell.layoutMargins = UIEdgeInsetsZero;perbaikan untuk saya.

pengguna3570727
sumber
13
solusi pertama dalam jawaban ini bekerja untuk saya, yang ke-2 tidak berhasil.
spybart
5
Jangan hanya menggunakan cell.layoutMargins = UIEdgeInsetsZero; karena akan macet di iOS 7.x. Lebih baik untuk memeriksa apakah pemilih ada terlebih dahulu sebelum menggunakannya. Lihat solusi saya di bawah ini.
Ricky
3
Dia tidak mengatur cell.layoutMargins ... Solusi ini berfungsi dengan baik ketika Anda sudah memiliki sel khusus.
Sjoerd Perfors
11
Ini akan berfungsi dengan baik di iOS 7, karena metode ini tidak akan dipanggil! Anda juga perlu mengatur layoutMargins tampilan tabel, atau itu tidak akan berfungsi.
cdstamper
2
mengganti accessor bekerja untuk saya. tetapi semua solusi lain tidak. bahkan mengkonfigurasi separatorInsetdalam IB tidak berhasil. ada juga masalah dengan warna latar belakang tampilan tabel. ini benar-benar sakit.
glasz
178

Mari luangkan waktu sejenak untuk memahami masalah sebelum mengisi daya secara membabi buta untuk berupaya memperbaikinya.

Poke cepat di debugger akan memberi tahu Anda bahwa garis pemisah adalah subview UITableViewCell . Tampaknya sel itu sendiri mengambil cukup banyak tanggung jawab untuk tata letak garis-garis ini.

iOS 8 memperkenalkan konsep margin tata letak . Secara default, margin tata letak tampilan ada 8ptdi semua sisi, dan margin tersebut diwarisi dari tampilan leluhur.

Sebaiknya kita tahu, ketika meletakkan garis pemisahnya, UITableViewCellmemilih untuk menghormati margin tata letak sebelah kiri, menggunakannya untuk membatasi inset kiri.

Menyatukan semua itu, untuk mencapai inset yang diinginkan benar-benar nol, kita perlu:

  • Setel margin tata letak kiri ke 0
  • Hentikan setiap margin yang diwarisi dan timpa

Dengan kata lain, ini adalah tugas yang cukup sederhana untuk dicapai:

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

Hal yang perlu diperhatikan:

  • Kode ini hanya perlu dijalankan sekali per sel (Anda hanya mengkonfigurasi properti sel setelah semua), dan tidak ada yang istimewa tentang ketika Anda memilih untuk menjalankannya. Lakukan apa yang tampaknya paling bersih untuk Anda.
  • Sayangnya tidak ada properti yang tersedia untuk dikonfigurasi di Interface Builder, tetapi Anda dapat menentukan atribut runtime yang ditentukan pengguna preservesSuperviewLayoutMarginsjika diinginkan.
  • Jelas, jika aplikasi Anda juga menargetkan OS yang dirilis sebelumnya, Anda harus menghindari mengeksekusi kode di atas hingga berjalan di iOS 8 dan di atasnya.
  • Daripada pengaturan preservesSuperviewLayoutMargins, Anda dapat mengonfigurasi pandangan leluhur (seperti tabel) untuk 0meninggalkan margin juga, tetapi ini tampaknya lebih rentan terhadap kesalahan karena Anda tidak mengontrol keseluruhan hierarki.
  • Mungkin akan sedikit lebih bersih untuk mengatur hanya margin kiri 0dan membiarkan yang lain.
  • Jika Anda ingin memiliki inset 0 pada pemisah "ekstra" yang UITableViewmenarik di bagian bawah tabel gaya biasa, saya menduga itu akan memerlukan menetapkan pengaturan yang sama di tingkat tabel juga (belum mencoba yang ini!)
Mike Abdullah
sumber
3
Terima kasih! Ini benar-benar jawaban yang lebih ringkas. Jauh lebih baik daripada mengganti dua metode dan dengan kasar memaksanya.
LunaCodeGirl
16
Di iOS 8, bagi saya, ini tidak akan berhasil tanpa[self.tableView setSeparatorInset:UIEdgeInsetsMake(0, 0, 0, 0)];
davetw12
1
Anda memiliki suara saya, terima kasih atas penjelasan yang jelas. Saya hanya akan menyebutkan bahwa TableView itu sendiri juga memiliki layoutMargins yang mungkin perlu diatur selain separatorInset, dalam beberapa kasus.
cdstamper
@ davetw12 dan @cdstamper Bisakah Anda memberikan bukti tentang ini? Semua eksplorasi saya sejauh ini mengatakan bahwa pengaturan keduanya layoutMarginsdan preservesSuperviewLayoutMarginspada sel adalah semua yang diperlukan. Ada hal lain yang terasa seperti percaya pada voodoo.
Mike Abdullah
3
Tidak, ini bukan bentuk voodoo @MikeAbdullah. Agar Anda dapat menghindari default separatorInseta UITableViewCelldi iOS 8, Anda harus mengatur set UIEdgeInsetske nol di kedua UITableViewdan UITableViewCell. Jika Anda tidak melakukan keduanya, Anda akan tetap memiliki inset kiri yang lebih besar dari nol. Saya sudah mengkonfirmasi ini beberapa kali.
davetw12
58

Saya percaya ini adalah pertanyaan yang sama yang saya tanyakan di sini: Hapus SeparatorInset di iOS 8 UITableView untuk XCode 6 iPhone Simulator

Di iOS 8 , ada satu properti baru untuk semua objek yang diwarisi darinya UIView. Jadi, solusi untuk mengaturSeparatorInset di iOS 7.x tidak akan dapat menghapus ruang putih yang Anda lihat di UITableView di iOS 8.

Properti baru disebut " layoutMargins ".

@property(nonatomic) UIEdgeInsets layoutMargins
Description   The default spacing to use when laying out content in the view.
Availability  iOS (8.0 and later)
Declared In   UIView.h
Reference UIView Class Reference

iOS 8 UITableView setSeparatorInset: UIEdgeInsetsZero setLayoutMargins: UIEdgeInsetsZero

Solusinya:-

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{

    if ([tableView respondsToSelector:@selector(setSeparatorInset:)]) {
        [tableView setSeparatorInset:UIEdgeInsetsZero];
    }

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

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

Jika Anda mengatur cell.layoutMargins = UIEdgeInsetsZero;tanpa memeriksa apakah layoutMarginsada, aplikasi akan macet di iOS 7.x. Jadi, cara terbaik akan memeriksa apakah layoutMarginsada terlebih dahulu setLayoutMargins:UIEdgeInsetsZero.

Ricky
sumber
Bagaimana pendekatan ini digunakan jika target penyebaran diatur ke iOS 7?
Petar
Saya meletakkan kode untuk tableView di viewDidLoad dan berfungsi dengan baik. Saya pikir tidak perlu memanggil mereka setiap kali di willDisplayCell ().
Abdullah Umer
46

Anda dapat menggunakan tampilan UIA sekali, saat startup aplikasi Anda (sebelum UI dimuat), untuk menjadikannya sebagai pengaturan global default:

// iOS 7:
[[UITableView appearance] setSeparatorStyle:UITableViewCellSeparatorStyleSingleLine];
[[UITableView appearance] setSeparatorInset:UIEdgeInsetsZero];

[[UITableViewCell appearance] setSeparatorInset:UIEdgeInsetsZero];

// iOS 8:
if ([UITableView instancesRespondToSelector:@selector(setLayoutMargins:)]) {

    [[UITableView appearance] setLayoutMargins:UIEdgeInsetsZero];
    [[UITableViewCell appearance] setLayoutMargins:UIEdgeInsetsZero];
    [[UITableViewCell appearance] setPreservesSuperviewLayoutMargins:NO];

}

Dengan cara ini, Anda menjaga kode UIViewController Anda tetap bersih dan selalu dapat menimpanya jika Anda mau.

Lukasz
sumber
41

iOS memperkenalkan properti layoutMargins pada tampilan sel DAN tabel.

Properti ini tidak tersedia di iOS 7.0 jadi Anda perlu memastikan Anda memeriksa sebelum menugaskannya!

Namun, Apple telah menambahkan properti yang disebut preservesSuperviewLayoutMargins ke sel Anda yang akan mencegahnya mewarisi pengaturan margin Table View Anda. Dengan cara ini, sel Anda dapat mengonfigurasi marginnya sendiri secara terpisah dari tampilan tabel. Anggap saja sebagai penggantian.

Properti ini disebut preservesSuperviewLayoutMargins , dan menyetelnya ke TIDAK dapat memungkinkan Anda untuk mengesampingkan pengaturan LayMagin Table View Anda dengan pengaturan LayMargin sel Anda sendiri. Keduanya menghemat waktu ( Anda tidak harus mengubah pengaturan Table View ), dan lebih ringkas. Silakan merujuk ke jawaban Mike Abdullah untuk penjelasan terperinci.

CATATAN: ini adalah implementasi yang tepat dan tidak berantakan, seperti yang dinyatakan dalam jawaban Mike Abdullah; mengatur sel Anda preservesSuperviewLayoutMargins = TIDAK akan memastikan bahwa Tampilan Tabel Anda tidak mengesampingkan pengaturan sel.

Langkah pertama - Siapkan margin sel Anda:

/*
    Tells the delegate that the table view is about to draw a cell for a particular row.
*/
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,
    forRowAtIndexPath indexPath: NSIndexPath)
{
    // Remove separator inset
    if cell.respondsToSelector("setSeparatorInset:") {
        cell.separatorInset = UIEdgeInsetsZero
    }

    // Prevent the cell from inheriting the Table View's margin settings
    if cell.respondsToSelector("setPreservesSuperviewLayoutMargins:") {
        cell.preservesSuperviewLayoutMargins = false
    }

    // Explictly set your cell's layout margins
    if cell.respondsToSelector("setLayoutMargins:") {
        cell.layoutMargins = UIEdgeInsetsZero
    }
}

Menyetel properti preservesSuperviewLayoutMargins pada sel Anda ke NO harus mencegah tampilan tabel Anda mengesampingkan margin sel Anda. Dalam beberapa kasus, sepertinya tidak berfungsi dengan baik.

Langkah kedua - Hanya jika semua gagal, Anda dapat memaksa margin Table View Anda:

/*
    Called to notify the view controller that its view has just laid out its subviews.
*/
override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    // Force your tableview margins (this may be a bad idea)
    if self.tableView.respondsToSelector("setSeparatorInset:") {
        self.tableView.separatorInset = UIEdgeInsetsZero
    }

    if self.tableView.respondsToSelector("setLayoutMargins:") {
        self.tableView.layoutMargins = UIEdgeInsetsZero
    }
}

... dan itu dia! Ini harus bekerja di iOS 8 dan juga iOS 7.

Catatan: diuji menggunakan iOS 8.1 dan 7.1, dalam kasus saya, saya hanya perlu menggunakan langkah pertama dari penjelasan ini.

Langkah Kedua hanya diperlukan jika Anda memiliki sel tidak berpenghuni di bawah sel yang diberikan, yaitu. jika tabel lebih besar dari jumlah baris dalam model tabel. Tidak melakukan langkah kedua akan menghasilkan offset pemisah yang berbeda.

Raja-Penyihir
sumber
1
Anda tidak perlu memeriksa penyeleksi dalam willDisplayCellmetode karena metode itu sendiri sudah iOS 8+ dan tidak akan pernah dipanggil dari versi yang lebih lama.
Rivera
38

Di Swift, ini sedikit lebih menyebalkan karena layoutMarginsmerupakan properti, jadi Anda harus mengganti pengambil dan penyetel.

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

Ini secara efektif akan membuat hanya layoutMarginsbaca, yang dalam kasus saya baik-baik saja.

swilliams
sumber
Hanya solusi ini yang bekerja untuk saya. Dan saya tidak perlu menambahkan kode tambahan dalam metode ini. Saya memang menggunakan sel khusus.
Ramis
2
Untuk sel statis, kecuali dari menimpa layoutMargins, Anda masih perlu mengubah gaya pemisah sel menjadi "Custom Insets" dan menetapkan nilai kiri ke "0" di storyboard.
hufeng03
22

Untuk iOS 9 Anda perlu menambahkan:

if([myTableView respondsToSelector:@selector(setCellLayoutMarginsFollowReadableWidth:)])
{
    myTableView.cellLayoutMarginsFollowReadableWidth = NO;
} 

Untuk lebih jelasnya silakan merujuk ke pertanyaan .

Julian Król
sumber
12
itu lucu untuk menambahkan beberapa kode untuk setiap versi sehingga penampilan awal tetap sama ...
Christian
20

Ekstensi Swift 2.0

Saya hanya ingin berbagi ekstensi yang saya buat untuk menghapus margin dari pemisah sel tampilan tabel.

extension UITableViewCell {
    func removeMargins() {

        if self.respondsToSelector("setSeparatorInset:") {
            self.separatorInset = UIEdgeInsetsZero
        }

        if self.respondsToSelector("setPreservesSuperviewLayoutMargins:") {
            self.preservesSuperviewLayoutMargins = false
        }

        if self.respondsToSelector("setLayoutMargins:") {
            self.layoutMargins = UIEdgeInsetsZero
        }
    }
}

Digunakan dalam konteks:

    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as! CustomCell

    cell.removeMargins()
    return cell
Dan Beaulieu
sumber
15

Cepat:

override func viewDidLoad() {
    super.viewDidLoad()

    if self.tableView.respondsToSelector("setSeparatorInset:") {
        self.tableView.separatorInset = UIEdgeInsetsZero
    }
    if self.tableView.respondsToSelector("setLayoutMargins:") {
        self.tableView.layoutMargins = UIEdgeInsetsZero
    }

    self.tableView.layoutIfNeeded()            // <--- this do the magic
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
     ...

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

    return cell
}
Alexander Volkov
sumber
11

Saya membuatnya bekerja dengan melakukan ini:

tableView.separatorInset = UIEdgeInsetsZero;
tableView.layoutMargins = UIEdgeInsetsZero;
cell.layoutMargins = UIEdgeInsetsZero;
ideawu
sumber
9

Seperti apa yang disarankan cdstamper daripada tampilan tabel, menambahkan baris di bawah ini dalam metode layoutSubview sel bekerja untuk saya.

- (void)layoutSubviews 
{
    [super layoutSubviews];

    if ([self respondsToSelector:@selector(setSeparatorInset:)])
                [self setSeparatorInset:UIEdgeInsetsZero];

        if ([self respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)])
        {
            [self setPreservesSuperviewLayoutMargins:NO];;
        }

        if ([self respondsToSelector:@selector(setLayoutMargins:)]) 
        {
            [self setLayoutMargins:UIEdgeInsetsZero];
        }
}
Vijay VS
sumber
9

Contoh Swift 3.0:

func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
    // removing seperator inset
    if cell.responds(to: #selector(setter: UITableViewCell.separatorInset)) {
        cell.separatorInset = .zero
    }
    // prevent the cell from inheriting the tableView's margin settings
    if cell.responds(to: #selector(setter: UIView.preservesSuperviewLayoutMargins)) {
        cell.preservesSuperviewLayoutMargins = false
    }
    // explicitly setting cell's layout margins
    if cell.responds(to: #selector(setter: UITableViewCell.layoutMargins)) {
        cell.layoutMargins = .zero
    }
}
mkz
sumber
9

Setelah banyak penyelidikan ...

Inilah satu-satunya cara untuk sepenuhnya mengendalikan hal ini (yang dapat saya temukan)

Untuk mengontrol sepenuhnya inset pemisah dan margin tata letak pada setiap sel. Lakukan ini dalam willDisplayCellmetode pada Anda UITableviewDelegate.

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

Objek sel mengontrol pemisah, dan contentViewmengontrol yang lainnya. Jika ruang inset pemisah Anda muncul dalam warna yang tidak terduga, ini harus menyelesaikannya:

cell.backgroundColor = cell.contentView.backgroundColor
Matjan
sumber
8

Solusi sederhana di Swift untuk iOS 8 dengan kustomUITableViewCell

override func awakeFromNib() {
    super.awakeFromNib()

    self.layoutMargins = UIEdgeInsetsZero
    self.separatorInset = UIEdgeInsetsZero
}

Dengan cara ini Anda menetapkan layoutMargindan separatorInsethanya satu kali alih-alih melakukannya untuk masing-masingwillDisplayCell seperti kebanyakan jawaban di atas menyarankan.

Jika Anda menggunakan kebiasaan, UITableViewCellini adalah tempat yang tepat untuk melakukannya. Kalau tidak, Anda harus melakukannyatableView:cellForRowAtIndexPath .

Hanya petunjuk lain: Anda tidak perlu mengatur preservesSuperviewLayoutMargins = falsekarena nilai default sudah NO!

Francesco Vadicamo
sumber
8

Bagi saya garis sederhana melakukan pekerjaan

cell.layoutMargins = UIEdgeInsetsZero
apinho
sumber
menyebutnya dalam metode delegasi cellForRowAtIndexPath. Jawaban bagus :)
saintjab
7

Cukup tambahkan kode di bawah ini untuk menyelesaikan program ini.

Semoga beruntung untukmu!

-(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];
       }

}
JimmyChang
sumber
5

Lukasz menjawab dalam Swift:

    // iOS 7:
    UITableView.appearance().separatorStyle = .SingleLine
    UITableView.appearance().separatorInset = UIEdgeInsetsZero
    UITableViewCell.appearance().separatorInset = UIEdgeInsetsZero

    // iOS 8:
    if UITableView.instancesRespondToSelector("setLayoutMargins:") {
        UITableView.appearance().layoutMargins = UIEdgeInsetsZero
        UITableViewCell.appearance().layoutMargins = UIEdgeInsetsZero
        UITableViewCell.appearance().preservesSuperviewLayoutMargins = false
    }
Naka
sumber
5

Ini adalah kode yang berfungsi untuk saya, di Swift:

override func viewDidLoad() 
{
    super.viewDidLoad()
    ...
    if tableView.respondsToSelector("setSeparatorInset:") {
        tableView.separatorInset = UIEdgeInsetsZero
    }
}

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,forRowAtIndexPath indexPath: NSIndexPath)
{
    if cell.respondsToSelector("setSeparatorInset:") {
        cell.separatorInset.left = CGFloat(0.0)
    }
    if tableView.respondsToSelector("setLayoutMargins:") {
        tableView.layoutMargins = UIEdgeInsetsZero
    }
    if cell.respondsToSelector("setLayoutMargins:") {
        cell.layoutMargins.left = CGFloat(0.0)
    }
}

Ini tampaknya paling bersih bagi saya (untuk saat ini), karena semua sel / tableView edge / margin penyesuaian dilakukan dalam tableView:willDisplayCell:forRowAtIndexPath:metode ini, tanpa menjejalkan kode yang tidak perlu ke dalam tableView:cellForRowAtIndexPath:.

Btw, saya hanya mengatur separatorInset / layoutMargins kiri sel, karena dalam hal ini saya tidak ingin mengacaukan kendala saya yang telah saya atur di sel saya.

Kode diperbarui ke Swift 2.2:

 override func viewDidLoad() {
   super.viewDidLoad()       

    if tableView.respondsToSelector(Selector("setSeparatorInset:")) {
      tableView.separatorInset = UIEdgeInsetsZero
        }
    }

 override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell,forRowAtIndexPath indexPath: NSIndexPath) {
        if cell.respondsToSelector(Selector("setSeparatorInset:")) {
            cell.separatorInset.left = CGFloat(0.0)
        }
        if tableView.respondsToSelector(Selector("setLayoutMargins:")) {
            tableView.layoutMargins = UIEdgeInsetsZero
        }
        if cell.respondsToSelector(Selector("setLayoutMargins:")) {
            cell.layoutMargins.left = CGFloat(0.0)
        }
    }
Ivan
sumber
Apa sebenarnya yang tidak bekerja untuk Anda? Baru saja menguji kode ini pada simulator iPhone 5, dengan iOS 8.1 SDK diinstal, dan semuanya seperti ketika saya awalnya diposting jawaban ini. Kode dikompilasi & dijalankan dengan Xcode 6.1.1.
Ivan
4

Kebanyakan jawaban yang menunjukkan insets pemisah dan tata letak margin yang ditetapkan melalui berbagai metode (yaitu, viewDidLayoutSubviews, willDisplayCell, dll) untuk sel dan tableviews, tapi aku telah menemukan bahwa hanya menempatkan ini dalam cellForRowAtIndexPathkarya-karya besar. Sepertinya cara terbersih.

// kill insets for iOS 8
if ([[UIDevice currentDevice].systemVersion floatValue] >= 8) {
    cell.preservesSuperviewLayoutMargins = NO;
    [cell setLayoutMargins:UIEdgeInsetsZero];
}
// iOS 7 and later
if ([cell respondsToSelector:@selector(setSeparatorInset:)])
    [cell setSeparatorInset:UIEdgeInsetsZero];
anorganik
sumber
4

Gunakan cuplikan kode di bawah ini untuk menghindari masalah bantalan yang tidak diinginkan untuk UITableView di iOS 8 & 7.

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath{

    if ([tableView respondsToSelector:@selector(setSeparatorInset:)])
    {
        [tableView setSeparatorInset:UIEdgeInsetsZero];
    }

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

    if ([cell respondsToSelector:@selector(setLayoutMargins:)])
    {
        [cell setLayoutMargins:UIEdgeInsetsZero];
    }
}
Anooj VM
sumber
4

Alih-alih memperbarui preservesSuperviewLayoutMarginsdan layoutMarginssetiap kali sel menggulir (menggunakan willDisplayCell), saya sarankan untuk melakukannya sekali dalam cellForRowAtIndexPath::

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

    let cell = super.tableView(tableView, cellForRowAtIndexPath: indexPath)

    cell.preservesSuperviewLayoutMargins = false
    cell.layoutMargins = UIEdgeInsetsZero

    return cell

}
Rudolf Adamkovič
sumber
4

Berikut cara mudah untuk menghapus inset secara global.

Dalam UITableViewCell+Extensions.swift:

import UIKit

extension UITableViewCell {

  override public var layoutMargins: UIEdgeInsets {
    get { return UIEdgeInsetsZero }
    set { }
  }

}

Dalam AppDelegate application:didFinishLaunchingWithOptions::

  UITableViewCell.appearance().separatorInset = UIEdgeInsetsZero

Anda mungkin berpikir untuk a) juga hanya mengganti separatorInsetdalam ekstensi, atau b) mengatur proxy penampilan layoutMargins. Tidak akan bekerja. Meskipun separatorInsetdiindikasikan sebagai properti, mencoba menimpanya sebagai properti (atau metode) menghasilkan kesalahan kompilator. Dan pengaturan proxy penampilan untuk UITableViewCell'slayoutMargins (atau, dalam hal ini, juga pengaturan proxy penampilan untuk UITableView' s layoutMarginsdan separatorInset) tidak berpengaruh.

Scott Gardner
sumber
3

Di iOS8:

Menambahkan ini ke Subclass UITableViewCell saya:

- (UIEdgeInsets)layoutMargins {
    return UIEdgeInsetsZero;
}

dan ini untuk "tableView: cellForRowAtIndexPath" atau "tableView: willDisplayCell":

[editCell setSeparatorInset:UIEdgeInsetsZero];

BEKERJA untuk saya.

Saru
sumber
2
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        // ... Get the cell
        cell.separatorInset = UIEdgeInsetsMake(0.f, 20.f, 0.f, [UIScreen mainScreen].bounds.size.width - 20);
        // others
        return cell;
}

Untuk sel tertentu yang ingin Anda sembunyikan pemisah.

xmurobi
sumber
2

Setelah melihat jawaban di lantai 3, saya mencoba mencari tahu apa hubungan pengaturan pemisah antara TableView & TableViewCell dan melakukan beberapa tes. Inilah kesimpulan saya:

  1. kita dapat mempertimbangkan bahwa mengatur pemisah sel ke nol harus memindahkan pemisah dalam dua langkah: langkah pertama adalah mengatur pemisah sel ke nol. Langkah kedua adalah mengatur marginlayout sel ke nol.

  2. mengatur setel separatorins TableView dan marginlayout dapat mempengaruhi setel separatorinset Cell . Namun, dari pengujian, saya menemukan bahwa separatorinset TableView tampaknya tidak berguna, marginlayout TableView sebenarnya dapat mempengaruhi marginlayout sel .

  3. atur Cell's PreservesSuperviewLayoutMargins = false, dapat memotong efek marginlayout TableView pada Sel.

  4. salah satu solusinya:

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        var cell = UITableViewCell()
    
        cell.preservesSuperviewLayoutMargins = false
        cell.separatorInset = UIEdgeInsetsZero
        cell.layoutMargins = UIEdgeInsetsZero
    
        return cell
    }
Xin Chen
sumber
2

Ini solusi saya. Ini berlaku untuk subkelas sel khusus, cukup tambahkan keduanya ke subkelas.

  1. - (UIEdgeInsets)layoutMargins {    
        return UIEdgeInsetsMake(0, 10, 0, 10);
    }

2.

self.separatorInset = UIEdgeInsetsMake(0, 10, 0, 10);

Dan akan lebih mudah jika Anda dapat menyesuaikan posisi pemisah tanpa meminta desainer Anda untuk menggambar satu untuk Anda ..........

Guoyu
sumber
1

Dengan cara yang lebih ringkas daripada jawaban yang paling banyak dipilih ...

- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath {

    if ([cell respondsToSelector:@selector(setSeparatorInset:)] && [cell respondsToSelector:@selector(setPreservesSuperviewLayoutMargins:)] && [cell respondsToSelector:@selector(setLayoutMargins:)]) {
         [cell setSeparatorInset:UIEdgeInsetsZero];
         [cell setPreservesSuperviewLayoutMargins:NO];
         [cell setLayoutMargins:UIEdgeInsetsZero];
    }

}

subharb
sumber
1

Menambahkan potongan ini, elegan sederhana di Swift bekerja untuk saya di iOS8 :)

    // tableview single line
func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    cell.preservesSuperviewLayoutMargins = false
    cell.layoutMargins = UIEdgeInsetsZero
}
ddnl
sumber
1

Ini bekerja dengan baik untuk saya di iOS 8 dan iOS 9.

Untuk OBJ-C

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

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

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