UITableView'da ilk bölüm başlığı nasıl gizlenir (gruplanmış stil)


108

Gruplanmış stili kullanan tablo görünümlerinin tasarımı iOS 7 ile önemli ölçüde değiştiğinden, ilk bölüm başlığını gizlemek (veya kaldırmak) istiyorum. Şimdiye kadar bunu başaramadım.

Biraz basitleştirilmiş, kodum şöyle görünüyor:

- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    if (section == 0)
        return 0.0f;
    return 32.0f;
}

- (UIView*) tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
    if (section == 0) {
        UIView* view = [[UIView alloc] initWithFrame: CGRectMake(0.0f, 0.0f, 640.0f, 0.0f)];
        return view;
    }
    return nil;
}

- (NSString*) tableView:(UITableView *) tableView titleForHeaderInSection:(NSInteger)section
{
    if (section == 0) {
        return nil;
    } else {
        // return some string here ...
    }
}

Yüksekliği 0 döndürürsem, diğer iki yöntem hiçbir zaman bölüm dizini 0 ile çağrılmaz. Yine de boş bir bölüm başlığı varsayılan yükseklik ile çizilir. (İOS 6'da iki yöntem çağrılır. Ancak görünen sonuç aynıdır.)

Farklı bir değer döndürürsem, bölüm başlığı belirtilen yüksekliği alır.

0.01 döndürürsem, neredeyse doğrudur. Ancak, simülatörde "Yanlış Hizalanmış Görüntüler" i açtığımda, tüm tablo görünümü hücrelerini işaretliyor (bu mantıksal bir sonuç gibi görünüyor).

UITableView: üstbilgiyi boş bölümden gizle sorusunun yanıtları , bazı kişilerin bölüm başlığını gizlemede başarılı olduğunu gösteriyor gibi görünüyor. Ancak düz stile de uygulanabilir (gruplanmış olanın yerine).

Şimdiye kadarki en iyi uzlaşma, yüksekliği 0,5'e döndürmek ve bunun sonucunda gezinme çubuğunun altında biraz daha kalın bir çizgi oluşması. Ancak, birisi ilk bölüm başlığının nasıl tamamen gizlenebileceğini bilirse memnun olurum.

Güncelleme

Göre caglar'ait 'nin analizi ( https://stackoverflow.com/a/19056823/413337 Tablo görünümü, bir navigasyon kontrol içerdiği takdirde), sorun yalnızca ortaya çıkar.


Bu parçayı almadım => if (bölüm == 0) görünümü döndür; sıfır dönüş; yani, ilk bölümü olduğu zaman bir görünüm döndürmek, aksi takdirde sıfır mı?
Zen

Buradaki fikir, ilk bölüm için yüksekliği 0 olan bir görünüm döndürmek ve diğer tüm bölümler için sıfır döndürmektir, böylece tablo görünümü onlar için varsayılan başlık görünümünü kullanır. Nil kısmı güzel çalışıyor; tablo görünümü bu bölümler için bir başlık gösterir. Ancak bölüm 0'ın parçası alakasızdır çünkü yöntem asla çağrılmaz section == 0.
Codo

1
Bu cevap kısa ve tatlı görünüyor. stackoverflow.com/a/23955420/3965
Mr Rogers

Yanıtlar:


154

Bana oldukça temiz görünen bir çözümüm var. Bu yüzden kendi sorumu cevaplıyorum.

İlk bölüm başlığının yüksekliği 0 çalışmadığından, 1 döndürürüm. Sonra bu yüksekliği gezinme çubuğunun altında gizlemek için contentInset'i kullanırım.

Objective-C:

- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    if (section == 0)
            return 1.0f;
    return 32.0f;
}

- (NSString*) tableView:(UITableView *) tableView titleForHeaderInSection:(NSInteger)section
{
    if (section == 0) {
        return nil;
    } else {
        // return some string here ...
    }
}

- (void) viewDidLoad
{
    [super viewDidLoad];

     self.tableView.contentInset = UIEdgeInsetsMake(-1.0f, 0.0f, 0.0f, 0.0);
}

Swift:

override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return section == 0 ? 1.0 : 32
}

override func viewDidLoad() {
    super.viewDidLoad()

    tableView.contentInset = UIEdgeInsets(top: -1, left: 0, bottom: 0, right: 0)
}

6
0.1f'lik bir başlık yüksekliği kullanmak, gizlemek için daha da iyidir.
Chuck Krutsinger

4
0.1f kullanmayı denedim. Ancak sonuç, çizimlerin artık piksellerle hizalanmaması, bulanıklığa neden olması ve performansı düşürmesidir. Simülatörde deneyin: Sorunlu hizalamayı vurgulama seçeneği vardır.
Codo

31
Aslında, daha iyi bir uygulama (gelecekte kırılma olasılığı daha düşük), CGFLOAT_MINsabit kodlanmış bir değer yerine kullanmaktır . Başka bir deyişle, yapma return 1.0fveya 0.1fbunun yerine, return CGFLOAT_MINApple minimum kabul edilebilir değeri değiştirirse, dönüş değerini sabit kodlarsanız değiştirecek kodunuz olur. Ayrıca, mümkün olan en küçük değeri kullanıp kullanmadığınızı zaten bilmiyorsunuz. Tanımlanan sabiti kullanarak, mümkün olan en küçük değeri kullandığınız garanti edilir ve kodunuz işletim sistemi değişikliklerinden kurtulacaktır.
Chris Ostmo

11
@Chris: Korkarım bu fikri anlamadınız. Çizimin piksel hizalı kalması için çok küçük bir değer değil, piksel boyutunun katlarını döndürüyorum (iyi performans ve netlik için). Daha sonra içerik ekini kullanarak onu dengeliyorum. Önemli, görünür bir mesafe olduğundan ve işletim sisteminin görmezden gelemeyeceği bir şey olduğundan, bunun gelecekte değişmesi olası değildir.
Codo

8
+1 Kesirli piksel değerlerini UI ofsetleri olarak kullanmamak için.
Ricardo Sanchez-Saez

52

UITableView'da (gruplanmış stil) ilk bölüm başlığının nasıl gizleneceği budur.

Swift 3.0 ve Xcode 8.0 Çözümü

  1. TableView temsilcisi, heightForHeaderInSection yöntemini uygulamalıdır

  2. HeightForHeaderInSection yöntemi içinde, en az pozitif sayıyı döndür. (sıfır değil!)

    func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    
        let headerHeight: CGFloat
    
        switch section {
        case 0:
            // hide the header
            headerHeight = CGFloat.leastNonzeroMagnitude
        default:
            headerHeight = 21
        }
    
        return headerHeight
    }
    

6
0 yerine CGFloat.leastNonzeroMagnitude döndürmek bana yardımcı oldu. Teşekkürler!
anoo_radha

Mükemmel cevap, Teşekkürler
Pierre

Bu arada, CGFLOAT_MINiçin objc özdeş olduğunu CGFloat.leastNonzeroMagnitudeolarak Swift
DawnSong

36

Cevap benim ve ekibim için çok komikti ve harika çalıştı

  • Arabirim Oluşturucu'da, tablo görünümünü görünüm hiyerarşisinde başka bir görünümün altına taşımanız yeterlidir.

NEDEN:

Bu ilk görünüm bir UITableView ise, bunun yalnızca Görünüm Hiyerarşisindeki İlk Görünüm için gerçekleştiğini gözlemledik . Yani, diğer tüm benzer UITableView'ların ilki dışında bu sinir bozucu bölümü yoktur. UITableView'ı görünüm hiyerarşisinde ilk sıranın dışına taşımayı denedik ve her şey beklendiği gibi çalışıyordu.


1
Tablo görünümünü kaydırdığınızda hala gezinme çubuğunun buzlu cam efektini görüyor musunuz?
Codo

TableView'unuzu buna göre kurduğunuzda bu bulanıklık efektine sahip olacaksınız . contentInsetÖrneğin {0, 64, 0, 0}, 64px yukarıdan uzaklığa (durum çubuğu artı gezinme çubuğu) sahip olacak şekilde ayarlamanız gerekir . TableView ekranın üst kısmına eklenmelidir, topLayoutGuide'a değil (gezinme çubuğunun altına ulaşmasına izin vermek için)
Julian

Yenilemek için çekme kullanmıyorsanız, bu iyi görünecektir.
Michael

2
Vay. Bu benim için iOS 9'da çalıştı ve aklımı başımdan aldı.
tahsis edin

Kabul edilen cevap bu olmalıdır. Ne kadar tuhaf bir böcek!
Oded Harth

25

Gruplanmış tablo türü için bu numarayı kullanın

ViewDidLoad yönteminde tablo görünümünüz için aşağıdaki kodu yapıştırın :

tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, tableView.bounds.size.width, 0.01f)];

Denemedim, ancak bu çözümün diğer önerilen çözümlerden bazılarıyla aynı dezavantaja sahip olduğundan şüpheleniyorum: çizimler artık piksellerle hizalanmıyor, bulanıklığa neden oluyor ve performansı düşürüyor. Simülatör bunu ortaya çıkarabilir: sorunlu hizalamayı vurgulama seçeneğine sahiptir. Bununla birlikte, 0'a yuvarlarsa, o zaman gerçekten güzel bir çözümdür.
Codo

Evet, sanırım sıfıra yuvarlıyor. Çünkü onu birçok kez kullandım ama çizimlerde bulanıklık bulamadım.
Nitesh Borad

TableHeaderView ve Section Header görünümü? fark nedir,
AsifHabib

Veya biraz daha kısa: _tableView.tableHeaderView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 1)].
mojuba

@AsifHabib: tableHeaderView, tüm tablo öğelerinin en üstünde yer alır. Tablonun kendisi için başlık görünümüdür. Ve bölüm başlığı görünümü, her bölüme yerleştirilecek görünümdür. Tabloda belirtilen bölüm sayısına göre birçok bölüm başlığı görünümü olabilir. Ancak, yalnızca bir tablo başlığı görünümü olacaktır.
Nitesh Borad

21

bu yol tamam.

override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    if section == 0 {
        return CGFloat.min
    }
    return 25
}

override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    if section == 0 {
        return nil
    }else {
        ...
    }
}

2
Bu, kesirli değerler kullanması dışında çözümümün güzel bir varyasyonudur. Bu şekilde, metin ve resimler artık piksellerle hizalanmaz, çizim yavaşlar ve sonuç bulanıklaşabilir. Simülatör, bu sorunu ortaya çıkarmak için "Yanlış hizalanmış görüntüler" seçeneğine sahiptir.
Codo

ContainerView ile statik hücreler kullanan benim gibi insanlar için gayet iyi çalışıyor
thibaut noah

3
Swift 3> 'CGFloat.min', 'CGFloat.leastNormalMagnitude' olarak yeniden adlandırıldı
rjobidon

6

Kodunuzu kopyaladım ve denedim. Normal çalışır (simülatörde denenmiştir). Sonuç görünümünü ekledim. Böyle bir manzara istiyorsun, değil mi? Yoksa problemini yanlış mı anladım?

görüntü açıklamasını buraya girin


1
Evet, temelde istediğim bu, ancak tablo görünümümün bir gezinti denetleyicisinde olması. Bu fark yaratabilir mi?
Codo

2
Gezinme denetleyicisine tableView ekledim ve durumunuz görünüyor :) Sanırım iOS 7'de gruplanmış stil tablo görünümünde bu başlık yüksekliği varsayılan olarak düzeltildi. TableView çerçevesini değiştirerek, ilk başlık görünümü gizlenebilir. (Set x = 0 y = -40 gibi). Ancak bu çözümün iyi bir çözüm olmadığını biliyorum.
caglar

1
Çalışmanız için çok teşekkür ederim. Bu nedenle, sorun yalnızca tablo görünümü gruplanmış stili kullanıyorsa ve bir gezinme denetleyicisi içinde yer alıyorsa ortaya çıkıyor.
Codo

Viewcontroller'dan tableviewcontroller'a geçmeye çalışırken, başlık ile ilgili sorunu çözemedim. Belki onu dönüştürmeye çalışan bir şeyi kaçırıyorum. (iOS 7.0.3 sim)
Evgeni Petrov

1
Bu sorun, bu anlık görüntüde de görülüyor! 0. hücre x: 0.0f & y: 0.0f'den başlamıyor.
Burhanuddin Sunelwala

6

Swift3: heightForHeaderInSection 0 ile çalışır, sadece başlığın clipsToBounds olarak ayarlandığından emin olmanız gerekir.

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

ClipsToBounds'u ayarlamazsanız, kaydırma sırasında gizli başlık görünür olacaktır.

func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int) {
    guard let header = view as? UITableViewHeaderFooterView else { return }

    header.clipsToBounds = true
}

1
clipsToBound = true, bölüm başlığı görünümünü tamamen gizlemeyi planlıyorsanız çok önemlidir. Yüksekliğinin 0 / CGFLOAT_MIN olarak ayarlanması yeterli değildir.
Altimac

5

Güncelleme [9/19/17]: Eski yanıt artık iOS 11'de benim için çalışmıyor. Teşekkürler Apple. Aşağıdakiler yaptı:

self.tableView.sectionHeaderHeight = UITableViewAutomaticDimension;
self.tableView.estimatedSectionHeaderHeight = 20.0f;
self.tableView.contentInset = UIEdgeInsetsMake(-18.0, 0.0f, 0.0f, 0.0);

Önceki Cevap:

Chris Ostomo'nun yorumlarında yayınlandığı gibi , aşağıdakiler benim için çalıştı:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    return CGFLOAT_MIN; // to get rid of empty section header
}

Tablo görünümünüzün içeriğinin artık piksellerle hizalanmadığından, bulanıklığa neden olduğundan ve performansı düşürdüğünden şüpheleniyorum. Simülatör bunu ortaya çıkarabilir: sorunlu hizalamayı vurgulama seçeneğine sahiptir. Bununla birlikte, 0'a yuvarlarsa, o zaman gerçekten güzel bir çözümdür.
Codo

Hayır, herhangi bir içerik sorunu fark etmedim. Kısıtlamalar iyi görünüyordu.
Manindra Moharana

1
Welp! Artık iOS 11'de çalışmıyor! Düzeltmem bir haftadan az sürdü .. 😞
Manindra Moharana

4

Swift'de gruplanmış bir UITableView'da üst bölüm başlığından nasıl kurtulacağınız aşağıda açıklanmıştır:

tableView.tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: CGFloat.leastNormalMagnitude))

3

Swift 4.2 ve önceki birçok sürümde, diğer cevaplarda olduğu gibi ilk başlığın yüksekliğini 0 olarak ayarlamak yerine, diğer başlıkları olarak ayarlayabilirsiniz nil. Diyelim ki iki bölümünüz var ve sadece ikincisinin (yani 1) bir başlığa sahip olmasını istiyorsunuz . Bu başlıkta Foobar metni olacak :

override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
    return section == 1 ? "Foobar" : nil
}

3

Tüm bölüm başlığını tamamen kaldırmak istiyorsanız bunu deneyin

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

func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
    return CGFloat.leastNormalMagnitude
}

Sadece ihtiyacım olan bu. Basit ve kolay bir çözüm. 1+
iGhost

0

Henüz yorum ama bir varsa o eklemek düşündüm olamaz UISearchControllerile Kumandanızda UISearchBarolarak sizin tableHeaderView, 0 olarak birinci bölümün yüksekliğini ayarlama heightForHeaderInSectiongerçekten çalışır.

Kullandığım self.tableView.contentOffset = CGPointMake(0, self.searchController.searchBar.frame.size.height);arama çubuğu varsayılan olarak gizlidir böylece.

Sonuç, ilk bölüm için başlık olmaması ve aşağı kaydırmanın ilk satırın hemen üzerindeki arama çubuğunu göstermesidir.


0

Bugüne kadar en kolay döndürmektir nil, ya ""içinde func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?sen başlığı gösterecektir istemeyen bir bölüm için.


0

Swift Sürümü: Swift 5.1
Çoğunlukla, tableView temsilcisindeki yüksekliği şu şekilde ayarlayabilirsiniz:

func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
   return UIView(frame: CGRect(x: 0, y: 0, width: view.width, height: CGFloat.leastNormalMagnitude))
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
   return CGFloat.leastNormalMagnitude
}

Bazen Xib veya Storyboard ile UITableView oluşturduğunuzda, up cevabı çalışmaz. ikinci çözümü deneyebilirsiniz:

let headerView = UIView(frame: CGRect(x: 0, y: 0, width: 0, height: CGFloat.leastNormalMagnitude))
self.tableView.tableHeaderView = headerView

Umarım sizin için çalışır!

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.