Показать фото/видео из массива в collectionview, scrollview?


#1

Ребята, подскажите

  1. Есть массив, где в перемешку фото и видео. Как лучше идентифицировать URL какой с чем. Поскольку фото и видео идут в разнобой

  2. Требуется горизонтальный скрол. Как лучше отобразить это? В collectionview, scrollview или другие варианты?

  3. Пока фото либо видео делать через enum и switch или есть другие адекватные варианты?

  4. Буду благодарен за любую подсказку, поскольку в сети есть варианты только под видео либо только под фото

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
         guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "DefaultCell", for: indexPath) as? SlideShowCollectionViewCell else { fatalError("\nSlide Show Error Cell\n") }
         
         var urlType = [CellType]()
         let urlArray = urlType[indexPath.row]
         
         switch urlArray {
         case .image(var url):
             url = images[indexPath.row]
             cell.imageView.sd_setImage(with: url)
             
         case .video(let url):
             cell.videoView.addSubview(playerView)
             addPlayer(for: url)
         }
    }

#2
  1. Создать метод который будет по расширению определять тип контента
  2. CollectionView
  3. Enum, Switch

#3

Понял
Так и сделал

    enum CellType {
       case image(URL)
      case video(URL)
  }

Тогда делаю метод который определяет тип контента. Как то костыльно просто в коллекшене через свитч выглядит. Поэтому и спросил. Ок как всегда спасибо за Ваши ответы :raised_hands:t2:


#4

Можете это все вынести в класс ячейки. Так будет даже лучше.

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
     guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "DefaultCell", for: indexPath) as? SlideShowCollectionViewCell else { fatalError("\nSlide Show Error Cell\n") }
     
     var urlType = [CellType]()
     let item = urlType[indexPath.row]

     cell.configure(item)
     
     return cell
}

#5

Ухххххх вот это красота. Класс. Благодарю


#6

а вот вам еще хорошая статейка на полезные расширения для таблиц и коллекции


#7

Супер. Сейчас буду читать, спасибо


#8

Боже как я хотел Kotlin style

let view = UIView().apply {
    $0.backgroundColor = .red
    $0.frame = .init(x: 0, y: 0, width: 200, height: 200)
}

жаль что $0 нужно писать

еще бы if, switch для присвоения в Swift сделать…


#9

100% $0 выглядит как из прошлого века. А так красота :raised_hands:t2::raised_hands:t2:


#10

не понял на счет свитча :slightly_smiling_face:


#11

В котлине можно так

val a: String = switch someType {
    case condition1:
        "String1"
    case condition2:
        "String2"
    default:
        "Empty"
}

аналогично с if


#12

пардон, там даже проще вместо switch используется when

val a: String = when someInt {
       1 ->  "String1"
       2 ->  "String2"
       else -> "Empty"
}

#13

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


#14

Swift:

let a: String = {
switch someType {
case .condition1:
    return "String1"
case .condition2:
    return "String2"
default:
    return "Empty"
}
}()

#15

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


#16

Нет, вычисляемые переменные объявляются с var.

Больше, но присвоение можно сделать через switch/if.


#17

Я писал именно про Kotlin style. В данном случае он мне больше нравится.


#18

Пардон еще вопрос, подскажите где можно оптимизировать код? Что бы убрать не правильные решения

   enum MediaType: String {
        case image = "image"
        case video = "video"
    }

    var multiplyArray = Array<AnyObject>() // Передается Dictionary

                 for allSources in jsonMultiplyArray {
                    if allSources.nd?.isVideo == true {
                        let videoArray = allSources.nd?.videoURL
                        self.multiplyDictionary[.video] = videoArray
                  } else {
                        guard let imgArray = allSources.nd?.dsplayResources?[2] else { return }
                        self.multiplyDictionary[.image] = imgArray.src
                    }
                    self.multiplyArray.append(self.multiplyDictionary as AnyObject)
                }


func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "DefaultCell", for: indexPath) as? SlideShowCollectionViewCell else {fatalError("\nError")}

    if indexPath.row < images.count {
        
        var urlType = images as? [[MediaType: String]]
        let item = urlType?[indexPath.item]

        for items in item! {
                
        }
        }
    return cell
}

#19

Что-то тут совсем все плохо.
Для начала лучше создать модель, которая будет хранить URL и тип, дополнительно по желанию делаете другие свойства.
В контроллере создаете пустой массив из вашей модели.
Заполняете массив вашими данными.
В методе cellForItemAt по индексу вытаскиваете из массива модель и передаете в ячейку.
Примерно так, код упрощенный

class Model {
    var type: MediaType!
    var url: URL?
}

class Controller {
    var modelList: [Model] = []

    // где-то заполняете модель

    func collectionView(:cellForItemAt) {
        ...
        let item = modelList[indexPath.row]
        cell.configure(item)
        return cell
    }
}

#20

Перфекто маэстро. Идеально. Благодарен