Cara mengatur lebar sel dalam UITableView dalam gaya berkelompok

107

Saya telah mengerjakan ini selama sekitar 2 hari, jadi saya pikir saya berbagi pembelajaran saya dengan Anda.

Pertanyaannya adalah: Apakah mungkin membuat lebar sel dalam UITableView yang dikelompokkan menjadi lebih kecil?

Jawabannya adalah tidak.

Tetapi ada dua cara untuk mengatasi masalah ini.

Solusi # 1: Tabel yang lebih tipis Anda dapat mengubah bingkai tableView, sehingga tabel akan menjadi lebih kecil. Ini akan menghasilkan UITableView merender sel di dalamnya dengan lebar yang diperkecil.

Solusi untuk ini dapat terlihat seperti ini:

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

Solusi # 2: Memiliki sel yang dirender oleh gambar

Solusi ini dijelaskan di sini: http://cocoawithlove.com/2009/04/easy-custom-uitableview-drawing.html

Saya harap informasi ini bermanfaat untuk Anda. Saya membutuhkan waktu sekitar 2 hari untuk mencoba banyak kemungkinan. Inilah yang tersisa.

Tomen
sumber
3
Saya pikir ini seharusnya dibuat sebagai pertanyaan hanya dengan baris kedua ("Pertanyaannya adalah: ..."), kemudian Solusi # 1 dan Solusi # 2 diposting sebagai dua jawaban terpisah, dengan salah satunya diterima. Kemudian jika pengguna lain menambahkan jawaban mereka sendiri, dan salah satunya menjadi lebih baik, jawaban yang diterima dapat diubah nanti.
GeneralMike

Jawaban:

226

Cara yang lebih baik dan lebih bersih untuk mencapai ini adalah subclass UITableViewCell dan mengganti -setFrame:metodenya seperti ini:

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

Mengapa lebih baik? Karena dua lainnya lebih buruk.

  1. Sesuaikan lebar tampilan tabel -viewWillAppear:

    Pertama-tama, ini tidak dapat diandalkan, superview atau pengontrol tampilan induk dapat menyesuaikan bingkai tampilan tabel lebih lanjut setelah -viewWillAppear:dipanggil. Tentu saja, Anda dapat membuat subkelas dan mengganti -setFrame:untuk UITableView Anda seperti yang saya lakukan di sini untuk UITableViewCells. Namun, subclass UITableViewCells adalah cara yang lebih umum, ringan, dan Apple.

    Kedua, jika UITableView Anda memiliki backgroundView, Anda tidak ingin backgroundView-nya dipersempit bersamaan. Menjaga lebar backgroundView sambil mempersempit lebar UITableView bukanlah pekerjaan yang mudah, belum lagi memperluas subview di luar superview bukanlah hal yang sangat elegan untuk dilakukan.

  2. Rendering sel kustom untuk memalsukan lebar yang lebih sempit

    Untuk melakukan ini, Anda harus menyiapkan gambar latar belakang khusus dengan margin horizontal, dan Anda harus membuat tata letak subview sel sendiri untuk mengakomodasi margin tersebut. Sebagai perbandingan, jika Anda hanya menyesuaikan lebar seluruh sel, pengaturan otomatis akan melakukan semua pekerjaan untuk Anda.

an0
sumber
2
ini adalah solusi yang bagus dan elegan, saya melakukannya dalam kategori :) Saya juga mencatat bahwa objek yang lebih transparan, semakin banyak beban cpu :)
mister koz
11
@misterkoz - peringatan: Beberapa kontrol iOS (UIDatePicker untuk yang pasti) secara internal menggunakan UITableViewCells dan berhenti jika Anda mengimplementasikannya dalam kategori.
Clafou
7
Metode ini sepertinya tidak berfungsi di iOS8 saat mencoba menghapus sel dalam mode edit. SetFrame dipanggil saat Anda masuk / keluar dari mode edit sehingga sel terus menyusut. Ada solusi untuk ini?
John Baum
3
@JohnBaum ini mungkin membantu (setidaknya dalam kasus saya ini berhasil): stackoverflow.com/questions/25911484/ios-8-cell-resizing/…
HashtagMarkus
2
Solusi ini benar-benar berkah. Jika seseorang bertanya-tanya bagaimana melakukan hal yang sama dengan cepat - reddit.com/r/swift/comments/2fr849/…
sysuser
16

Untuk melakukan ini di Swift, yang tidak menyediakan metode untuk menyetel variabel, Anda harus mengganti penyetel untuk frame. Awalnya diposting (setidaknya di tempat saya menemukannya) di sini

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
sumber
Bekerja untuk cepat
Simon McNeil
9

Jika tidak ada yang berhasil, Anda dapat mencoba ini

Jadikan warna background sel sebagai warna bening lalu letakkan gambar sel dengan ukuran yang diinginkan. Jika Anda ingin menampilkan beberapa teks di sel itu, beri label di atas gambar. Jangan lupa juga untuk mengatur warna background label menjadi warna yang jelas.

termasuk saya
sumber
8

Saya menemukan solusi yang diterima tidak berfungsi pada rotasi. Untuk mencapai UITableViewCells dengan lebar tetap & margin fleksibel, saya baru saja mengadaptasi solusi di atas menjadi berikut:

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

Metode dipanggil setiap kali perangkat berputar, jadi sel akan selalu berada di tengah.

Graham
sumber
0

Ada metode yang dipanggil saat layar diputar: viewWillTransitionToSize

Di sinilah Anda harus mengubah ukuran bingkai. Lihat contoh. Ubah coord bingkai sesuai kebutuhan.

- (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);
    }];
}
Orang
sumber
-2

saya melakukannya di

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

Dan ini berhasil untuk saya

Lều Đức Quý
sumber
-6

Dalam file .h tambahkan delegasi 'UITableViewDataSource'

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{ 
    return size;
}
bharath gangupalli
sumber
4
Dia ingin mengatur lebar, bukan tingginya
Christopher Pickslay
oh hoo. sry atas ketidaknyamanan.
bharath gangupalli
Anda salah paham dengan pertanyaan dan jawaban Anda untuk tinggi dan Anda tahu apa yang berhasil untuk saya karena saya mencari tinggi bukan untuk lebar .. terima kasih jawabannya
Pooja