Soru UITableView heightForHeaderInSection / heightForFooterInSection Saygısız mı?


Bazı durumlarda, bazı bölümlerin sıfır satırının bulunduğu bir UITableView var. Amacım, bu doğru olduğunda, tablo görünümünde boş alan istemiyorum, veri yok gibi görünmelidir.

Sorun şu ki, herhangi bir satır bile olsa ve delegate yöntemi 0.0f dönmek için beni geçersiz kılmasa bile gösteren bölümler için üstbilgi ve altbilgidir.

İşte göründüğü gibi - üstteki gri alanın ~ 20p'sini, 0 satırlı bir bölüm için her birinin yaklaşık 10p üstbilgisini ve altbilgisini görebilirsiniz.

alt metin http://www.hanchorllc.com/table_cells.png

İşte benim sahte kodum:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
     if ([section hasRow]) {
          return 10.0f;
     } else {
          return 0.0f;
     }
}



- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
     if ([section hasRow]) {
          return 10.0f;
     } else {
          return 0.0f;
     }
}

Bu yöntemlerin çağrıldığını ve doğru yürütme yolunun gerçekleştiğini doğruladım.

Bir kırışıklık - bu görünüm denetleyicisi bir XIB kullanıyor ve UITableView, uygulandığı takdirde temsilci yöntemi tarafından geçersiz kılınmış olsa da, 10.0 (varsayılan) olarak ayarlanmış bölüm üstbilgi ve altbilgi değerlerine sahip.

Bu, 3.0'ı hedefleyen bir uygulama.

Neyi yanlış yapıyorum?


20
2017-09-06 21:50


Menşei




Cevaplar:


İPhone'daki "gruplandırılmış" UITableView'da, üstbilgi ve altbilgi için minimum bir yükseklik oluşturacak ve kodunuzu sıfırlamak için etkin bir şekilde yok sayar. XIB varsayılanına bağlı değildir.

Bunun nedeni sıfır yükseklik bölümü üstbilgisinin veya altbilgisinin çok garip görünmesidir. Bu nedenle Apple, bir üstbilgi yüksekliğinin 0'a ayarlanamayacağını belirtmiştir. Bu nedenle, birden çok "boş" bölüm ekran görüntüsünüze göre garip bir şekilde işlenecektir.

Korkarım, çünkü hiçbir veri satırı olmadığında başlık boyutunu temizlemenin yanlış yoluna gidiyorsunuz; yerine sen yapmalısın boş bölümler için herhangi bir yöntem çağrılmıyor. Kötü bir teknik çünkü temelde iPhone'un gerekenden daha fazla yöntem aramak zorunda kalması ve aynı zamanda istediğinizden daha fazla başlık oluşturması (genellikle - bazen insanlar buradaki boş başlıklarını bırakmak, örneğin sürükle ve bırak için) .

Öyleyse, örneğin, birkaç bölümünüzün olduğunu düşünelim, ancak sadece bazılarının birden fazla satırı var (belki de kullanıcı ayarları / filtrelerine dayanarak).

yanlış uygulama şekli:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
  return totalNumberOfPossibleSections;
}

ve sonra her bölüm için hiçbir sonucun yok:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  if (![section hasRow]) return 0;
}

ve

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
  if (![section hasRow]) return 0.0f;
}

doğru uygulama şekli:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
  return numberOfSectionsWhichHaveAtLeastOneRowInThem;
}

ve sonra her bölümün en az bir sonucu olacaktır. Böylelikle, hiç veri içermeyen bölümler bile oluşturulmuyor, yöntemler onlar için bile çağrılmıyor. Not: İki değişken ismim içeriklerini içerecek şekilde yazılır! Onlar özel Apple değişkenleri değil ...

Umarım yardımcı olur!


24
2017-09-06 23:42



Evet, bu mantıklı geliyor. Tablo bölüm düzenlerim için enum sabitlerini bildirme alışkanlığına girdim ve bu özel denetleyiciyi, bölümlerdeki bilinmeyen sayıda satırla çok iyi çalışmayan bu tasarıma zorlamak için uğraşıyordum. Apple'ın belgelerinin hiçbir yerde (bunu bulabildiğim) belirtmemesi, özellikle sizden beri 0,0 değerini kabul etmeyeceğini kutu XIB'de 0.0 ayarlayın (ve evet, gerçekten garip görünüyor). En azından, değerin 0.0f'den büyük olması gerektiğine dikkat edilmelidir. Şerefe. - Hunter
Gerçekten de garip görünüyor - Ben de hiçbir döküman olarak görmedim bu yüzden bir hata olarak dosyalamaya değer. - h4xxr
Bu iyi bir fikir ama bunu uygularken sıkıntılarım vardı. Tablo görünümü yöntemlerimin bir bölümünde bölüm için anahtar tablolarım var. Veri içeriğine bağlı olarak değişken sayıda bölüm döndürmek bu haritalamayı gerçekten karıştırıyor ve bununla başa çıkmak için zarif (hatta kolay) bir yol düşünemiyorum. - blindjesse
@blindJesse İki geçişli bir yaklaşım almanızı öneririm: ilk geçiş, içindeki bölümleri ve satırları tanımlayan iki seviyeli bir ağaç oluşturur. Tüm UITableView delege çağrılarınız daha sonra ne yapılacağına (hücre yönetimi, seçim, vb.) Karar vermek için NSIndexPath'i temel alarak bu ağacı sorgula. Mutlaka kolay değil, ama kesinlikle çekilebilir hale getirir. - jpap


Bu 0.0 t değeri kabul edilmediği için biraz zor. ama sıfıra yeterince yakın olan her şey hile yapacak. Eğer piksel mükemmel olmayacağınıza ve yuvarlak sayıları seçmeye karar verirseniz, 1.0f hemen hemen aynı şeyi yapacaktır, çünkü yükseklikteki 1px farkı oldukça dikkat çekecektir.

-(CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section{
    if(section == 1 )
        return 0.000001f;
    else return 44.0f; // put 22 in case of plain one..
}

-(CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section{
    return 0.000001f; //removing section footers
}

32
2017-11-16 15:53



Vay. Bu çok zor ama işe yarıyor. - nonamelive
Bu hack, iOS 7'de çalışmıyor gibi görünüyor. - crishoj
Bir hile cehennem.Yeni bir gün bir gün geçirdikten sonra heightForHeaderInSection ve heightForFooterInSection bu benim için çalıştı.Ve 7 de çalışır :) - ihy
bence CGFLOAT_MIN daha iyi 0.000001f - Piotr Wasilewicz


Tabloya saygı duyuyor gibi görünüyor tableView:heightForHeaderInSection: Yalnızca tableView:viewForHeaderInSection: değil nil, ya da eğer tableView:titleForHeaderInSection: değil nil veya @"". Aynı, altbilgi yüksekliği için de geçerlidir.

Bu nedenle, herhangi bir bölüm üstbilgisi görünümünün veya başlığınızın olmadığını varsayarak, bunu yalnızca tablonuza ekleyin:

- (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
  return [[[UIView alloc] initWithFrame:CGRectZero] autorelease];
}

9
2018-02-26 03:07



Bu doğru değil. Eğer tablo 0'da dönerseniz: heightForHeaderInSection :, 10 puanlık bir altbilgi elde edersiniz. Cevabında @Juris'den bahsedildiği için 0.00001f gibi biraz daha büyük bir sayı belirtmeniz gerekecek. - Klaas


Benzer bir sorunum vardı:  Yükleniyordum UITableView bir XIB'den (sizinle aynı) ve bazı bölüm altbilgileri için 0 yükseklik sağladı. tableView:heightForFooterInSection (seninle aynı), ama değer göz ardı edildi.

Düzeltme basitti: ayrıca XIB'de footer yüksekliğini 0,0'a ayarlayın. (Interface Builder'da Tablo Görünümü'nü seçin, Boyut Denetçisini görüntülemek için Command-3'e basın, üst kısımdaki altbilgi yüksekliği alanını arayın)

Bu yapıldıktan sonra beklendiği gibi özel altbilgi yüksekliğine uyuldu. (Belki de XIB altbilgi yüksekliğini minimum olarak ele alır?)


3
2018-01-15 20:37



IB'de, gruplandırılmış bir tablo görünümü için belirleyebileceğiniz minimum bölüm yüksekliği 1'dir. Bu, hiçbir şeyi değiştirmez. - Michael Pirotte


Benim durumumda, hayalet altbilgisini öldürmek için 2 şey gerektiğine karar verdim:

1) tablo görünümünü ayarlama sectionFooterHeight için 0yani viewDidLoad ekleme:

tableView.sectionFooterHeight = 0

2) temsilci yöntemini ekleme:

override func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
    return UIView(frame: CGRect.zero)
}

(Swift 2.2 kullanarak)


3
2017-09-27 22:33



'TableView.sectionFooterHeight = 0' eklemek benim için çalıştı ... teşekkürler - Itachi Uchiha


Benim için çalışıyor:

- (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
    tableView.sectionHeaderHeight = (section == 0 ? 10 : 0);
    return tableView.sectionHeaderHeight;
}

- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section
{
    tableView.sectionFooterHeight = (section == 0 ? 20 : 4);
    return tableView.sectionFooterHeight;
}

1
2018-02-16 11:11





Aslında, benimle başka şekilde gerçekleşiyor. Ben xib olarak 10 olmak için bölüm üstbilgisi atadım, ancak ilk bölüm için bir başlık üstbilgisi istiyorum. Bu yöntemi UITableViewCotroller'ımda kullanıyorum

- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if(indexPath.section==0)
        return 125;
    return tableView.rowHeight;
}

Ancak, yöntem çağrılsa bile bölüm üstbilgisi yüksekliği değiştirilmez.


0
2017-11-23 02:26





Bu soruna olan çözümüm, h4xxr'nin nasıl tanımlandığını açık ve kapalı tutuyor, ancak dinamik bir bölüm sayısı oluşturmak için biraz farklı bir yaklaşımım var.

Öncelikle, veri yapımı yürütebilmem için bir metot tanımladım ve veriler masaya gösterilsin ya da vermesin. Bu bayrak bir dizide saklanır, böylece istediğim kadar az veya çok bölüm ekleyebilirim. Her bölüm için sadece hücre sayısına odaklanırsak bu uygulamayı biraz daha iyi anlatabilirim:

İlk bölümümün ad, soyadı ve yaş ile iletişim bilgileri olduğunu varsayalım. Bu bölümü '1' ile tanımlayacağım (daha sonra açıklayacağım gibi teknik olarak herhangi bir rakam olabilir). Şimdi, yöntemim bu bölümün görünür olması gerektiğini belirlerse, '1' değerini bir diziye doğru itiyorum.

Bir sonraki bölüm göstermek istediğim adres ve 3-4 satır / hücre olabilir. Yukardaki gibi, metodumdaki mantık, adresin '2' üzerine basılarak adresin görünür olması gerekip gerekmediğini belirler.

Şimdi her iki bölümün de görünmesini istediğimizde, 2 ve iki parça uzunluğunda bir diziye sahip olacağız [1,2]. Yalnızca iletişim ayrıntılarının görünür olmasını istediğimizde, dizimiz sadece 1 için [1] ve [2] numaralı bir uzunluğa sahip olacaktır.

Şimdi dizimizin uzunluğunu istediğimiz bölümlerin sayısını tanımlamak için geri verebiliriz.

Anahtar ifademiz şimdi böyle bir şeye benzeyecek:

switch(ourArray[indexPath.section]){
    case 1:
        <Return the number of rows for the contact details which we said would be 3>
        break;
    case 2:
        <Return the number of rows for the address details which we said would be 4>
        break;
    case 3:
        <Return another number for some section that is referenced by the id '3'>
        break; 
}

Anahtarımı 3 numaralı duruma soktum. Örneğimizdeki dizi '1' ve '2' değerlerini içerdiğinden, bu durumda diziye ekleyerek bu durumu eklemeye / etkinleştirmeye karar vermedikçe, 3. durum asla eşleşmeyecek ve dolayısıyla göz ardı edilmeyecektir.

Ayrıca, hangi bölümlerin görülebilir olduğu mantığını tanımlayan yöntemimizde, dizideki farklı konumlara yerleştirerek / onları iterek bölümlerin sırasını değiştirebileceğimizi unutmayın.

Yukarıdaki bölümleri, indekslemeyi ve bölümlerin inşasını çözmeme izin verdiği için kullanıyorum.

Son olarak, tablomu 'reloadData' kullanarak güncellemeden önce, diziyi oluşturacak ve tablonun kendisinin nasıl oluşturulacağını bilmesine izin verecek doğru uzunluk ve dizi id'lerinin sırasını sağlayacak metodumu çağıracağım. Verilerim bir şekilde değişiyor veya filtreleniyorsa, bu yöntemi tekrar arayacağım ve diziyi yeniden yapılandıracağım.


0
2018-06-01 17:56