AlamofireImage af_setImageWithURL em um UITableViewCell sem imagem de espaço reservado

9

Estou usando o AlamofireImage para definir uma imagem em um UIImageView em um UITableViewCell da seguinte forma:

cell.imageView.af_setImageWithURL(url)

A imagem não aparece após o download. Ele mostrará a imagem pela segunda vez quando for carregada do cache de memória.

Parece que usar uma imagem de espaço reservado faz toda a diferença.

Isso funciona e imprime o endereço da imagem (baixada):

cell.imageView.af_setImageWithURL(URL, placeholderImage: UIImage(named: "placeholder"), filter: nil, imageTransition: .None, completion: { (response) -> Void in
                    print("image: \(cell.imageView.image)")
                })

Isso não funciona e imprime "image: nil"

cell.imageView.af_setImageWithURL(URL, placeholderImage: nil, filter: nil, imageTransition: .None, completion: { (response) -> Void in
                    print("image: \(self.image)")
                })

Também funciona ao definir as células imageView para uma imagem vazia antes de fazer af_setImageWithURL:

cell.imageView.image = UIImage()

Isso é um bug no UITableViewCell, AlamofireImage ou estou fazendo algo errado?

    
por Jorn van Dijk 02.12.2015 в 04:08
fonte

2 respostas

3

Esta pergunta tem dois anos, mas talvez essa resposta possa ser útil para alguém com um problema semelhante, como eu antes, para encontrar a solução certa.

Como as imagens são carregadas de forma assíncrona, se não fornecermos uma altura fixa para o UIIMageView , precisaremos forçar uma atualização da célula quando o download for concluído . Isso porque a atualização da célula (isto é, o recálculo das Restrições de AutoLayout) é feita automaticamente somente após o método cellForRowAt , que é chamado quando uma célula é exibida pela primeira vez ou quando a tabela é rolada para mostrar outras células. Em ambos os casos, provavelmente, as imagens ainda não foram baixadas pelo método af_setImage() , então nada, a não ser o espaço reservado, será exibido, pois seus tamanhos são desconhecidos no momento.

Para forçar uma atualização de célula, precisamos usar os métodos beginUpdates() e endUpdates() , colocando-os dentro do manipulador de conclusão de .af_setImage() . Dessa forma, toda vez que o download for concluído, a célula será atualizada.

Mas, para evitar um loop , antes de chamar beginUpdates() / endUpdates() , temos que verificar se já atualizamos a célula antes, porque chamando esses métodos, o cellForRowAt O método é chamado novamente e, consequentemente, o af_setImage() e seu fechamento de conclusão com beginUpdates() / endUpdates() dentro dele.

Isso significa que temos que atualizar a célula somente quando o download acaba de ser concluído, e não quando a imagem já é retirada (porque, se for descontado, significa que já atualizamos a célula). Isso pode ser feito verificando a resposta do manipulador de conclusão: se não for nil , a imagem foi apenas downoladed, se for nil , a imagem foi retirada.

Como benefício secundário, a altura da célula será ajustada automaticamente (lembre-se de colocar tableView.estimatedRowHeight = 400 e tableView.rowHeight = UITableViewAutomaticDimension no método viewDidLoad() )

Finalmente, aqui está o código:

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        // Dequeue your cell
        let cell = self.tableView.dequeueReusableCell(withIdentifier: "YourCustomCellIdentifier") as! YourCustomTableViewCell

        // get picture url from the data array
        let pictureUrl = self.yourCellsData[indexPath.row].pictureUrl

        // async download
        cell.pictureView.af_setImage(
                withURL:  URL(string: pictureUrl)!,
                placeholderImage: UIImage(named: "YourPlaceholder.png"),
                filter: nil,
                imageTransition: UIImageView.ImageTransition.crossDissolve(0.5),
                runImageTransitionIfCached: false) {
                    // Completion closure
                    response in
                        // Check if the image isn't already cached
                        if response.response != nil {
                            // Force the cell update
                            self.tableView.beginUpdates()
                            self.tableView.endUpdates()
                        }
                }

        return cell
        }

Isso é tudo pessoal! ; -)

    
por Guido 09.06.2017 / 11:58
fonte
1

Você pode imprimir o erro adicionando 2 linhas de código para ter mais ideias sobre o problema.

cell.imageView.af_setImageWithURL(URL, placeholderImage: UIImage(named: "placeholder"), filter: nil, imageTransition: .None, completion: { (response) -> Void in
                    print("image: \(cell.imageView.image)")
                    print(response.result.value) //# UIImage
                    print(response.result.error) //# NSError

                })

No meu caso, houve um problema com o URL da imagem. Estava baixando a imagem quando a abri no navegador.

    
por Sujal 18.03.2016 / 14:35
fonte