如何使具有多个UITableViewCell的tableView(cellForRowAtIndexPath)可读?

时间:2016-08-03 08:03:29

标签: ios swift uitableview

我有UITableView多个UITableViewCell,每个单元格都有不同的设计和高,我现在的问题是方法tableView(cellForRowAtIndexPath)看起来很奇怪且不可读我不知道这是否是案件的真实和良好实践。

我的方法:

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

    }

3 个答案:

答案 0 :(得分:2)

在使用代码之后,在代码看起来更好之前,您需要解决一些问题:

1。您需要一个反映您的tableView数据源的模型,它应该类似于:

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

然后你可以使用更通用的单元格来设置模型对象:

cell.setRowModel(currentRowModel)

2。你决定女巫部分出现的if语句非常复杂,

for example this line:

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

你必须为此找到更好的逻辑。一旦你对模型进行了特定化,就像我在第1部分中感到悲伤一样,这应该看起来更清晰,你可以将它改为switch语句,它会对枚举产生疑问。

3。所有单元格逻辑,我更喜欢在单元格内部进行,为了更清晰的viewController,我最后在示例代码中这样做了。

4. 不要将字符串用于标识符,它可能会导致错误。这就是我更喜欢在UITableViewCell上使用扩展名的原因,它会返回类名作为标识符。

5. 不要使用半列快速。

6. 所有细胞都应该有一个基类,这样你就可以在返回细胞时使用多态性。

7. 一旦有了代表数据源的模型,就可以使用Switch语句而不是if语句。

这是我编写的示例代码,您必须在编译之前对代码进行一些处理。我只是一个更好的练习例子。 (我之所以没有使用switch语句,只是因为你的案例过于复杂而无法使用简单的枚举。就像我很伤心,我必须要做的事情,让它变得更简单)

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
}

答案 1 :(得分:1)

试试这个

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
    }

答案 2 :(得分:0)

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

我希望我帮助你。