2012-07-17 15 views
5

Tıklanabilir bölümlere sahip bir UITableview oluşturdum. Eğer, onlarainsertRowsAtIndexPaths: scrollToRowAtIndexPath: UITableView bölümlerinin yanlış gizlenmesine neden olur

  1. tıkladığında onlar görünümünün en onlarla
  2. tıklandığına bölüm parşömenlerini hücrelerini ortaya çıkarmak için "genişletmek".

Ben indexpaths/tümüne eklemek gerekli hücreleri silin ve sonra aşağıdaki kodla bunları eklemek hesaplamak: Seçilen bölümün Aşağıdaki bölümlerde gizli tek bir sorun var

[self.tableView beginUpdates]; 
[self.tableView insertRowsAtIndexPaths:pathsToOpen withRowAnimation:insertAnimation]; 
[self.tableView deleteRowsAtIndexPaths:pathsToClose withRowAnimation:deleteAnimation]; 
[self.tableView endUpdates]; 
[self.tableView scrollToRowAtIndexPath:[pathsToOpen objectAtIndex:0] atScrollPosition:UITableViewScrollPositionTop animated:YES]; 

. İlk ekran görüntüsü, tablo görünümünün nasıl görüneceğini gösterir. İkinci ekran görüntüsü, gerçekte nasıl göründüğünü gösterir. Eğer yukarı (böylece gizli bölümler ekran dışında) ve sonra tekrar aşağı kaydırarak

Sections Disappear

, gizli bölümler (bir kez daha görünür) geri getirilir. Bunun neden olduğu hakkındaki tahminim şudur:

Ekleme/silme animasyonları scrollToRowAtIndexPath ile aynı anda gerçekleşiyor ve Tablo Görünümü'nü karıştırıyor. Eğer scrollToRowAtIndexPath bölüm 3 & bölümlerini tamamlamamış olsaydım, ekran dışına çıkacaktı - ve böylece tablo bir şekilde ekran dışında olduklarını düşünüyor. UITableview, optimizasyon olarak ekran dışı olan hücreleri/bölümleri gizler. dispatch_after ile scrollToRowAtIndexPath'u 2 saniye olarak çağırırsam, 3 & 4 bölümleri doğru şekilde görüntülenir.

Sanırım bunun neden olduğunu biliyorum, ancak bu UITableview optimizasyonunu nasıl düzeltebileceğimi/geçersiz kılacağımı bilmiyorum. Aslında, scrollViewDidEndScrollingAnimation uygular ve bu işlevde bir kesme noktası eklerseniz, uygulama 3 & 4 bölümlerini doğru görüntüler (ilk ekran görüntüsünü bu şekilde aldım). Ama bu fonksiyondan devam edince, hücreler kaybolur. Bölümler meşru UITableView bölümleri şunlardır:

tam proje here


ek uygulama ayrıntılarına indirilebilir. Tablo görünümüne bir temsilci geri çağrısı tetikleyen bir tapGestureRecognizer ekledim. Aşağıda, bölümleri açan tüm yöntem yer almaktadır.

- (void)sectionHeaderView:(SectionHeaderView *)sectionHeaderView sectionOpened:(NSInteger)sectionOpened 
{ 
    // Open 
    sectionHeaderView.numRows = DefaultNumRows; 
    sectionHeaderView.selected = YES; 
    NSMutableArray *pathsToOpen = [[NSMutableArray alloc] init]; 
    for (int i = 0; i < sectionHeaderView.numRows; i++) 
    { 
     NSIndexPath *pathToOpen = [NSIndexPath indexPathForRow:i inSection:sectionOpened]; 
     [pathsToOpen addObject:pathToOpen]; 
    } 

    // Close 
    NSMutableArray *pathsToClose = [[NSMutableArray alloc] init]; 
    if (openSectionHeader) 
    { 
     for (int i = 0; i < openSectionHeader.numRows; i++) 
     { 
      NSIndexPath *pathToClose = [NSIndexPath indexPathForRow:i inSection:openSectionHeader.section]; 
      [pathsToClose addObject:pathToClose]; 
     } 
    } 

    // Set Correct Animation if section's already open 
    UITableViewRowAnimation insertAnimation = UITableViewRowAnimationBottom; 
    UITableViewRowAnimation deleteAnimation = UITableViewRowAnimationTop; 
    if (!openSectionHeader || sectionOpened < openSectionHeader.section) 
    { 
     insertAnimation = UITableViewRowAnimationTop; 
     deleteAnimation = UITableViewRowAnimationBottom; 
    } 

    openSectionHeader.numRows = 0; 
    openSectionHeader.selected = NO; 
    openSectionHeader = sectionHeaderView; 


    [self.tableView beginUpdates]; 
    [self.tableView insertRowsAtIndexPaths:pathsToOpen withRowAnimation:insertAnimation]; 
    [self.tableView deleteRowsAtIndexPaths:pathsToClose withRowAnimation:deleteAnimation]; 
    [self.tableView endUpdates]; 
    [self.tableView scrollToRowAtIndexPath:[pathsToOpen objectAtIndex:0] atScrollPosition:UITableViewScrollPositionTop animated:YES]; 
} 
+0

Sanırım Apple tarafından sağlanan MVC'yi daha iyi kullanacaksınız. Yapmanız gereken tek şey veri kaynağınıza veri eklemek/çıkarmak ve tablo görünümü satırına dokunmamanızdır. – divol

+0

Lütfen, bir indirme beklemekten ziyade, projenizde biraz daha fazla soru bulunmasını isteyin - örneğin, dizin yollarını nasıl hesaplarsınız? eklemek/kaldırmak ve "Bölüm X" şeyler bölüm üstbilgileri mi yoksa sadece hücreler mi? Projenizi indirmeye çok bağımlı olmasaydı, daha iyi bir bağımsız soruya yönelirdi. – jrturton

+0

Sanırım senin de doğru. Satır sonundaki delege yönteminde satırları yeniden yüklemeyi deneyebilir misiniz? – jrturton

cevap

6

Anlatabildiğim kadarıyla, zaten kullanılmış olan bir bölüm görünümünü döndürürken sorun oluşuyor. Onun yerine:

- (UIView *)tableView:(UITableView*)tableView viewForHeaderInSection:(NSInteger)section 
{ 
    return [self.sectionHeaderViews objectAtIndex:section]; 
} 

Ben yeni bir görünüm her zaman yaratmak eğer sorun olsun:

- (UIView *)tableView:(UITableView*)tableView viewForHeaderInSection:(NSInteger)section{ 
    SectionHeaderView *sectionHeaderView = [self.tableView dequeueReusableCellWithIdentifier:SectionHeaderView_NibName]; 
    sectionHeaderView.textLabel.text = [NSString stringWithFormat:@"Section %d", section]; 

    UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:sectionHeaderView action:@selector(handleTap:)]; 
    [sectionHeaderView addGestureRecognizer:tapRecognizer]; 
    sectionHeaderView.section = section; 
    sectionHeaderView.delegate = self; 
    return sectionHeaderView; 
} 

Bunun olması durumunda bölüm başlıkları oluşturmak ve onlara tutunmaya [self.tableView dequeueReusableCellWithIdentifier:SectionHeaderView_NibName]; kullandığınız için gerçekleşiyor mümkündür UITableViewCell için yaratıldığını düşünmüyorum bir dizide, ama emin değilim. Bölüm görünümleri için yukarıdaki UITableViewCell'i düşünmek ve bunun yerine başka bir şey (belki de UILabel ile bir UIImageView) kullanmak isteyebilirsiniz. Ya da Bölüm Görünümlerini bir dizide saklayamazsınız ... halihazırda kodunuzu oluşturduğunuz şekilde, diziye ihtiyacınız yoktur ve yeni bir görünüm oluşturmak, bunun için endişelenmenize gerek kalmayacak kadar önemsizdir.

4

@ AaronHayman'ın yanıtı (ve IMO'nun kabul ettiği ve ödül alması gerektiği gibi ona gitmeli - bu sadece bir yoruma uymadı!), ancak daha ileriye gideceğim - kullanmamalısınız Bölüm üstbilgisi için bir hücre, ve bir takozu esasen yüklemek için dequeue mekanizmasını kullanmamalısınız.

Bölüm üstbilgisi görünümünün hücreler olmaması ve özellikle de deegerlendirildiyse, düzenli görünümler yerine bunları kullanarak beklenmedik efektler elde edersiniz - tablo bunu yaptığınızda bu yeniden kullanılabilir hücrelerin listesini tutuyor ve ekrandan çıktıklarında onları geri dönüştürür, ancak bölüm başlığınız yeniden kullanılamaz, bölüm başına bir tane var. senin örnek projede

, sade bir UIView olmak SectionHeaderView ait üst sınıf değişti ve orada hazretleri doğrudan yüklemek için createSectionHeaderViews yöntemini değiştirdi: Ben de yeniden hattı için kayıt dışarı yorumladı

NSMutableArray *sectionHeaderViews = [[NSMutableArray alloc] init]; 
    UINib *headerNib = [UINib nibWithNibName:SectionHeaderView_NibName bundle:nil]; 
    for (int i = 0; i < 5; i++) 
    { 
     SectionHeaderView *sectionHeaderView = [[headerNib instantiateWithOwner:nil options:nil] objectAtIndex:0]; 
     sectionHeaderView.textLabel.text = [NSString stringWithFormat:@"Section %d", i]; 

     UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:sectionHeaderView action:@selector(handleTap:)]; 
     [sectionHeaderView addGestureRecognizer:tapRecognizer]; 
     sectionHeaderView.section = i; 
     sectionHeaderView.delegate = self; 

     [sectionHeaderViews addObject:sectionHeaderView]; 
    } 
    self.sectionHeaderViews = sectionHeaderViews; 

viewDidLoad öğesinden. Bu, bölüm başlıklarının kaybolmasını engeller.

+0

Ona bir Nib'den görünümü nasıl örneklendireceğinizi gösteren iyi bir fikir. Genelde tüm görüşlerimi kodda oluşturuyorum, böylece bunu düşünmedim bile. –

İlgili konular