Задать вопрос
Контакты
Местоположение
Россия, Москва и Московская обл., Москва

Наибольший вклад в теги

Все теги (2)

Лучшие ответы пользователя

Все ответы (8)
  • CollectionView как создать/отредактировать ячейки в storyboard?

    Невозможно установить проблему не видя ваш код, но могу предположить, с чем может быть проблема.

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

    То есть Вы в сториборде располагаете элементы так, как вам нужно, и обязательно присваиваете ячейке идентификатор, например "item", и, желательно, указываете кастомный класс.

    После этого, у вас в вашем CollectionViewController есть метод
    func collectionView(_ collectionView: UICollectionView,  cellForItemAt indexPath: IndexPath) -> UICollectionViewCell


    Этот метод будет конфигурировать ячейки, как мы видим из метода, он должен вернуть объект "UICollectionViewCell"
    В нем нам необходимо создать ячейку с указанным в сториборде идентификатором, и прокастить до нужного класса, если мы его создавали.
    К примеру мы поставили идентификатор "item" и класс "CustomCell"
    func collectionView(_ collectionView: UICollectionView,  cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
         let cell = collectionView.dequeueReusableCell(withReuseIdentifier "item",  for: IndexPath) as! CustomCell
    
         // теперь cell у нас нужная нам ячейка, настройки IBOutlets и IBActions у нас в ее кастомном классе, если 
             необходимо можем тут настроить какую нибудь логику. После настройки логики, нам нужно вернуть из 
             метода эту ячейку
    
         return cell
    }


    Теперь коллекция при запуске будет конфигурировать наши ячейки по указанному идентификатору, с указанным классом. Если вы все настроили правильно, то у вас должны отобразиться необходимые ячейки.
    Ответ написан
    1 комментарий
  • Почему сменяются ячейки в UICollectionView?

    Если я правильно понял, вы передаете в ячейку ссылку на изображение, и дальше асинхронно загружаете изображение с этого адреса.

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

    Например, мы увидели ячейку №1, сработал метод загрузки изображения, пошел запрос на адрес, в этом время ячейка ушла из области, и мы увидели другую, она тоже посылает запрос на сервер, но в этом время у нас приходит ответ с первого запроса, и ячейка №2 уже получит по своему запросу, но данные будут от первого запроса, и соответственно подставится неправильное изображение.

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

    Я предлагаю следующее решение:
    Ставим наблюдателя, при получении строки с адресом изображения будет проверять, можно ли сформировать ссылку из указанного адреса, если не получится - тогда поставит дефолтное изображение

    var imageURLString:   String? {
            
            didSet {
                
                DispatchQueue.global(qos: .utility).async { [unowned self] in
                    
                    guard imageURLString    != "",
                          let imageURLString = self.imageURLString,
                          let imageURL       = URL(string: imageURLString) else {
                              
                              DispatchQueue.main.async {
                                  
                                  self.ImageView.image = UIImage(named: "default")
                                  
                              }
                              
                              return
                              
                          }
                    
                    loadImage(imageURL: imageURL)
                    
                }
                
                
            }
            
        }


    Если ссылка получена, вызывается этот метод, который получит данные и подставит в изображение, либо поставит дефолтную картинку, если данные не пришли по тем или иным причинам

    fileprivate func loadImage(imageURL: URL)  {
            
            dataTask = URLSession.shared.dataTask(with: imageURL, completionHandler: { data, response, error in
                
                if let data = data,
                   let image = UIImage(data: data) {
                    
                    DispatchQueue.main.async { [unowned self] in
                        
                        self.ImageView.image = image
                        
                    }
                    
                } else {
                    
                    DispatchQueue.main.async { [unowned self] in
                        
                        self.ImageView.image = UIImage(named: "default")
                        
                    }
                    
                }
                
            })
            
            dataTask?.resume()
            
        }


    Самое главное. Метод остановит загрузку если ячейка была удалена из области видимости.

    override func prepareForReuse()            {
            super.prepareForReuse()
            
            dataTask?.cancel()
            
            ImageView.image = UIImage(named: "default")
        }


    Код выше - прописан в классе ячейки коллекции.
    Ответ написан
    1 комментарий