отображать разные настраиваемые ячейки представления таблицы в зависимости от того, если int> 0 - PullRequest
1 голос
/ 13 июля 2020

У меня есть таблица в моей базе данных sql, которая показывает исполнителей, песни и альбомы. У каждого из них есть идентификатор. У меня также есть 3 пользовательских ячейки. введите описание изображения здесь

Если идентификатор больше 0, я бы хотел, чтобы эта песня, исполнитель или альбомы отображались в виде таблицы. Я получаю эти данные с помощью массивов.

Каждый раз, когда запускается этот код, я получаю Поток 1: Неустранимая ошибка: Индекс выходит за пределы диапазона cra sh. Это может иметь какое-то отношение к logi c моего оператора if. Мы будем благодарны за любые предложения.

var searchActive: Bool = false
var search = [Search]()
var songs = [Songs]()
var artists = [Artist]()
var album = [Album]()
var cleanSong = ""
var artistName = ""
var albumName = ""
var songCover = UIImage()
var artistPic = UIImage()
var albumCover = UIImage()

override func viewDidLoad() {
    super.viewDidLoad()

    
    tableView.register(SongTableViewCell.nib(), forCellReuseIdentifier: SongTableViewCell.songCell)
    tableView.register(ArtistTableViewCell.nib(), forCellReuseIdentifier: ArtistTableViewCell.artistCell)
    tableView.register(AlbumTableViewCell.nib(), forCellReuseIdentifier: AlbumTableViewCell.AlbumCell)
    tableView.delegate = self
    tableView.dataSource = self
    searchesBar.delegate = self
    
    print(search)
}

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
       
        if (search[indexPath.row].songid > 0) { //CRASH: Thread 1: Fatal error: Index out of range
        
        let cell = tableView.dequeueReusableCell(withIdentifier: "SongTableViewCell", for:  indexPath) as! SongTableViewCell
        
            cell.mainLabel!.text = songs[indexPath.row].cleanName
        cell.secondLabel!.text = songs[indexPath.row].artistName
        cell.cellImage!.image = UIImage(named: songs[indexPath.row].cover)
        return cell
        } else if (search[indexPath.row].artistid > 0) {
            let cell = tableView.dequeueReusableCell(withIdentifier: "ArtistTableViewCell", for: indexPath) as! ArtistTableViewCell
            cell.artistLabel.text = artists[indexPath.row].artistName
            cell.artiistImage.image = UIImage(named: artists[indexPath.row].picture)
            return cell
        } else {
            let cell = tableView.dequeueReusableCell(withIdentifier: "AlbumTableViewCell", for: indexPath) as! AlbumTableViewCell
            cell.albumLabel!.text = search[indexPath.row].cleanSong
            cell.albumCover.image = UIImage(named: album[indexPath.row].cover)
            return cell
        }
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        
        if (searchActive) {
            return search.count
        } else {
            return 1
        }
      
    }

Ответы [ 2 ]

0 голосов
/ 13 июля 2020

Мне лично не нравится, как вы справляетесь с текущим сценарием. Мы скорее можем построить это с помощью лучшего шаблона проектирования, чем использовать Int и иметь три разных класса UITableViewcell. Я бы предпочел сделать это через Bride Pattern. Я попытался сделать это с помощью кода ниже:

//Resource protocol is used to display for cell used in table view cell
//we can use model also in place of different functions to return cell data
protocol ResourceProtocol {
    func snippet()
    func title()
    func image()
    func url()
}

class ArtistResource: ResourceProtocol {
    func snippet() {
        //return snippet
    }
    
    func title() {
        //return title
    }
    
    func image() {
        //return image
    }
    
    func url() {
        //return url
    }
}

class SongResource: ResourceProtocol {
    func snippet() {
        //return snippet
    }
    
    func title() {
        //return title
    }
    
    func image() {
        //return image
    }
    
    func url() {
        //return url
    }
}

class AlbumResource: ResourceProtocol {
    func snippet() {
        //return snippet
    }
    
    func title() {
        //return title
    }
    
    func image() {
        //return image
    }
    
    func url() {
        //return url
    }
}

protocol IViewProtocol {
    var resource: ResourceProtocol { get set }
    func show()
}


class TableViewCellView: IViewProtocol {
    var resource: ResourceProtocol
    
    init(source: ResourceProtocol) {
        resource = source
    }
    
    func show() {
        //show snippet
        //show title
        //show url
        //show image
    }
    
    
}

class ListView {
    var dataSource: [ResourceProtocol]?
    
    func fetchData() {
        //return data source
    }
    //show data in cell from UITableViewDataSource functions
}

class DetailView: IViewProtocol {
    var resource: ResourceProtocol
    
    init(source: ResourceProtocol) {
        resource = source
    }
    
    func show() {
        //show detail
        //show title
        //show url
        //show image
    }
    
}

Вы можете настроить этот код, я только что дал прототип, как он должен быть реализован.

0 голосов
/ 13 июля 2020

это потому, что у вас есть условие в numberOfRowsInSection, вам нужно проверить то же условие в cellForRowAt

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
   if searchActive {
        if (search[indexPath.row].songid > 0) {
        
        let cell = tableView.dequeueReusableCell(withIdentifier: "SongTableViewCell", for:  indexPath) as! SongTableViewCell
        
            cell.mainLabel!.text = songs[indexPath.row].cleanName
        cell.secondLabel!.text = songs[indexPath.row].artistName
        cell.cellImage!.image = UIImage(named: songs[indexPath.row].cover)
        return cell
        } else if (search[indexPath.row].artistid > 0) {
            let cell = tableView.dequeueReusableCell(withIdentifier: "ArtistTableViewCell", for: indexPath) as! ArtistTableViewCell
            cell.artistLabel.text = artists[indexPath.row].artistName
            cell.artiistImage.image = UIImage(named: artists[indexPath.row].picture)
            return cell
        } else {
            let cell = tableView.dequeueReusableCell(withIdentifier: "AlbumTableViewCell", for: indexPath) as! AlbumTableViewCell
            cell.albumLabel!.text = search[indexPath.row].cleanSong
            cell.albumCover.image = UIImage(named: album[indexPath.row].cover)
            return cell
        }
    } else {
      // return cell for searchActive == false, I don't know what you want to show, so I return empty UITableViewCell
      return UITableViewCell()
    }
}
...