2016-08-03 7 views
0

Ich habe UITableView mit mehreren UITableViewCell, jede Zelle haben ein anderes Design und hohe, das Problem, das ich jetzt die Methode tableView (cellForRowAtIndexPath) so seltsam und unlesbar aussehen und ich weiß nicht, ob dies die wahre und die gute Praxis ist Umsetzung für den Fall.Wie mache ich tableView (cellForRowAtIndexPath) mit mehreren UITableViewCell lesbar?

Meine Methode:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     if(indexPath.section == 0){ // linked news item 
      let cellIdentifier = "linkedNewsTableViewCell"; 
      let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! LinkedNewsTableViewCell; 
      let linked_news = LinkedNews[indexPath.row]; 
      cell.newTitle.text = linked_news.news_title; 
      return cell; 
     }else if(indexPath.section > 1 && indexPath.row == 0 && indexPath.section != sections.count+2){ // section header item 
      let cellIdentifier = "sectionHeaderTableViewCell"; 
      let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! SectionHeaderTableViewCell; 
      let sec = sections[indexPath.section-2]; 
      cell.lblSectionTitle.text = sec.section_name; 
      cell.backgroundColor = Constants.Colors.lightGray; 
      return cell; 
     }else if(indexPath.section == 2+sections.count){ // all rights reserved item 
      let cellIdentifier = "allRightsReservedTableViewCell"; 
      let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! AllRightsReservedTableViewCell; 
      cell.backgroundColor = Constants.Colors.lightGray; 
      return cell; 
     }else if(indexPath.section == 1){ // slider news item 
      let cellIdentifier = "newsTableViewCell"; 
      let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! NewsTableViewCell; 
      cell.imgVideo.hidden = true; 
      let newsItem = SliderNews[indexPath.row]; 
      cell.txtNews.text = newsItem.news_title; 
      cell.lblTime.text = Utilities.timeAgoSinceDate(NSDate(timeIntervalSince1970:newsItem.createdstamp!), numericDates: false); 
      do{ 
      let isSaved = try DBManger.sharedInstance.isSaved(String(newsItem.news_id!)); 
      cell.isSaved = isSaved; 
      cell.news = newsItem; 
       if(isSaved == true){ 
        cell.btnSave.setImage(UIImage(named: "ic_bookmark_blue"), forState: .Normal); 
       }else{ 
        cell.btnSave.setImage(UIImage(named: "ic_bookmark"), forState: .Normal); 
       } 
      }catch{ 

      } 

      if(SliderNews.count-1 == indexPath.row){ 
       cell.buttomLine.hidden = true; 
      }else{ 
       cell.buttomLine.hidden = false; 
      } 

      let image = cell.imgNews.getImage(newsItem.image!, timestamp: String(newsItem.createdstamp!), size: "228", qualty: "70"); 

      cell.imgNews.loadImage(image,contentMode: .ScaleToFill) 

      cell.lblType.text = newsItem.section_name; 
      cell.backgroundColor = Constants.Colors.lightGray; 
      return cell; 
     }else{ // section news item 
      let sec = sections[indexPath.section-2]; 
      if(indexPath.row == sec.news.count+1){ 
       let cellIdentifier = "moreNewsTableViewCell"; 
       let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! MoreNewsTableViewCell; 
       cell.lblSectionName.text = "المزيد من \(sec.section_name!)"; 
       cell.backgroundColor = Constants.Colors.lightGray; 
       return cell; 
      } 
      let cellIdentifier = "newsTableViewCell"; 
      let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! NewsTableViewCell; 
      cell.imgVideo.hidden = true; 
      let newsItem = sec.news[indexPath.row-1]; 
      cell.txtNews.text = newsItem.news_title; 
      cell.lblTime.text = Utilities.timeAgoSinceDate(NSDate(timeIntervalSince1970:newsItem.createdstamp!), numericDates: false); 
      cell.lblType.text = sec.section_name; 

      if(sec.news.count == indexPath.row){ 
       cell.buttomLine.hidden = true; 
      }else{ 
       cell.buttomLine.hidden = false; 
      } 

      let image = cell.imgNews.getImage(newsItem.image!, timestamp: String(newsItem.createdstamp!), size: "228", qualty: "70"); 

      cell.imgNews.loadImage(image,contentMode: .ScaleToFill) 

      cell.backgroundColor = Constants.Colors.lightGray; 

      do{ 
       let isSaved = try DBManger.sharedInstance.isSaved(String(newsItem.news_id!)); 
       cell.isSaved = isSaved; 
       cell.news = newsItem; 
       if(isSaved == true){ 
        cell.btnSave.setImage(UIImage(named: "ic_bookmark_blue"), forState: .Normal); 
       }else{ 
        cell.btnSave.setImage(UIImage(named: "ic_bookmark"), forState: .Normal); 
       } 
      }catch{ 

      } 

      return cell; 
     } 

    } 
+0

Die gleiche Frage xD –

+2

Verwenden Muster Stoff, übergeben, um es Schnittstelle ' cellIdentifier'und return done cell, oder verwenden Sie das Builder-Muster und implementieren Sie die gleiche Logik, bis zu Ihnen. Ich denke, dass Sie Entwurfsmuster lesen müssen :) – iSashok

+0

machen Zellklasse kümmern sich um die Einrichtung und Verwendung von Schalter anstelle von diesem Chaos –

Antwort

2

Nachdem das Spiel mit Ihrem Code, haben Sie ein paar Probleme, das ist gelöst werden muss, bevor der Code viel besser aussehen:

1. Sie benötigen ein Modell, das Ihre Tableview Datenquelle reflektiert, sollte es in etwa so aussehen:

let currentSectionModel = self.sections[indexPath.section] 
    let currentRowModel = currentSectionModel[] 

und dann können Sie etwas allgemeinere mit Ihren Zellen verwenden, um das Modellobjekt zu setzen:

cell.setRowModel(currentRowModel) 

2. Ihre if-Anweisungen, die Hexe Abschnitt zu präsentieren entscheidet, sind sehr kompliziert,

for example this line: 

    if indexPath.section > 1 && indexPath.row == 0 && indexPath.section != sections.count+2 { 

Sie haben eine bessere Logik für diese zu finden. Sobald Sie das Modell wie ich traurig in Abschnitt 1 orgenize, sollte dies viel klarer und Sie können es zu einer switch-Anweisung ändern, die eine enum in Frage stellt.

3. Alle Zellenlogik, ich bevorzuge tun Innerhalb der Zelle selbst, für eine saubere ViewController, habe ich dies am Beispielcode am Ende getan.

4. Verwenden Sie keine Zeichenfolgen für Bezeichner, es kann Fehler verursachen. Aus diesem Grund bevorzuge ich eine Erweiterung für UITableViewCell, die den Klassennamen als Kennung zurückgibt.

5. Verwenden Sie keine Halbsäulen ist schnell.

6. Alle Ihre Zellen sollten eine Basisklasse haben, auf diese Weise können Sie Polymorphie verwenden, wenn Sie Zellen zurückgeben.

7. Sobald Sie ein Modell haben, das die Datenquelle darstellt, können Sie die Switch-Anweisung anstelle der if-Anweisung verwenden.

Dies ist der Beispielcode, den ich geschrieben habe, Sie müssen an Ihrem Code ein wenig arbeiten, bevor es kompiliert wird. Ich bin nur ein besseres Übungsbeispiel. (Ich habe switch-Anweisungen nur verwendet, weil Ihre Fälle zu komplex sind, um eine einfache enum zu verwenden.Wie ich schon traurig, I'ts etwas, das Sie haben zu arbeiten, und machen es einfacher)

class BaseCellType: UITableViewCell { 
} 

class AllRightsReservedTableViewCell: BaseCellType { 
    // Your implementation 
} 

class LinkedNewsTableViewCell: BaseCellType { 
    func setLinkedNews(linedNews: LinkedNews) { 
     // Your implementation 
    } 
} 

class SectionHeaderTableViewCell: BaseCellType { 
    func setSectionModel(sectionModel: SectionModel) { 
    // Your implementation 
    } 
} 

class MoreNewsTableViewCell: BaseCellType { 
    func setSection(section: SectionModel) { 
    // Your implementation 
    } 
} 

class NewsTableViewCell: BaseCellType { 
    // Your implementation 
} 

class SectionsModel { 
    let rows: [RowModel] 
} 

extension UITableViewCell { 
    static var cellIdentifer: String { 
     get { 
      return String(self.dynamicType).componentsSeparatedByString("__").last! 
     } 
    } 
} 

enum SectionType: Int { 
    case AllRightsReserevedSection = 1, LinkedNewItem = 0 
} 

class ViewController: UIViewController { 
    var sections: [SectionsModel]! 

    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     let cell: BaseCellType 

     switch (section: indexPath.section,row: indexPath.row) { 
     case (SectionType.AllRightsReserevedSection.rawValue, _): 
      cell = tableView.dequeueReusableCellWithIdentifier(AllRightsReservedTableViewCell.cellIdentifer, forIndexPath: indexPath) as! AllRightsReservedTableViewCell; 
     case (SectionType.LinkedNewItem.rawValue, _): 
      cell = tableView.dequeueReusableCellWithIdentifier(LinkedNewsTableViewCell.cellIdentifer, forIndexPath: indexPath) as! LinkedNewsTableViewCell; 
      cell.setLinkedNews(LinkedNews[indexPath.row]) 
     case let index where index.section > 1 , index.row == 0, index.section != secrion+2: 
      cell = tableView.dequeueReusableCellWithIdentifier(SectionHeaderTableViewCell.cellIdentifer, forIndexPath: indexPath) as! SectionHeaderTableViewCell 
      cell.setSectionModel(sections[indexPath.section-2]) 
     case let index where index.section == section.count + 2: 
      cell = tableView.dequeueReusableCellWithIdentifier(AllRightsReservedTableViewCell.cellIdentifer, forIndexPath: indexPath) as! AllRightsReservedTableViewCell; 
     case let index where index.row == (sec.news.count + 1) : 
      cell = tableView.dequeueReusableCellWithIdentifier(MoreNewsTableViewCell.cellIdentifer, forIndexPath: indexPath) as! MoreNewsTableViewCell; 
      cell.setSection(sections[indexPath.section-2]) 
     default: 
       cell = tableView.dequeueReusableCellWithIdentifier(NewsTableViewCell.cellIdentifer, forIndexPath: indexPath) as! NewsTableViewCell; 
       cell.setNewsItem(sec.news[indexPath.row-1]) 
      } 
     } 
    return cell 
} 
0

In Ihrem cellForRowAtIndexPath -> * Objective-C

if(your first condition){ 
      static NSString *cellIdentifier = @"cell"; 
      MANewsCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath]; 
    tableView.rowHeight=30; 
      }else if(second condition){ 
      static NSString *cellIdentifier = @"cell1"; 
      MANewsCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath]; 
    tableView.rowHeight=40; 
      }else 
    { 
      static NSString *cellIdentifier = @"cell2"; 
      MANewsCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier forIndexPath:indexPath]; 
    tableView.rowHeight=50; 
    } 

Ich hoffe, dass ich Ihnen helfen.

1

Versuchen Sie dieses

func makeBasicTableCell(title:String,details:String,indexPath:NSIndexPath) -> CustomHeaderCell{ 
      let cell = tableProfile.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as! CustomHeaderCell 
      cell.titleLable.text = title 
      cell.detLable.text = details 
      return cell 
    } 
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell 
    { 
     var tblCell: UITableViewCell! 
     tableView.registerNib(UINib(nibName: "profile_details", bundle: nil), forCellReuseIdentifier: "cell") 
     if indexPath.section == 0 { 
      switch(indexPath.row) { 
      case 0: 
       return makeBasicTableCell("Text1", details: "TextDetail1", indexPath: indexPath) 
      case 1: 
       return makeBasicTableCell("Text2", details: "TextDetail2", indexPath: indexPath) 
      case 2: 
       return makeBasicTableCell("Text3", details: "TextDetail3", indexPath: indexPath) 
      case 3: 
       return makeBasicTableCell("Text4", details: "TextDetail4", indexPath: indexPath) 
      default: 
       return makeBasicTableCell("", details: "", indexPath: indexPath) 
      } 
     } else if indexPath.section == 1 { 
      switch(indexPath.row) { 
      case 0: 
       return makeBasicTableCell("Text5", details: "TextDetail5", indexPath: indexPath) 
      case 1: 
       return makeBasicTableCell("Text6", details: "TextDetail6", indexPath: indexPath) 
      case 2: 
       return makeBasicTableCell("Text7", details: "TextDetail7", indexPath: indexPath) 
      default: 
       return makeBasicTableCell("", details: "", indexPath: indexPath) 
      } 
     } 
     return tblCell 
    } 
Verwandte Themen