Как сделать, чтобы выводилось 5 разных картинок с рандомного url?

Рейтинг: 0Ответов: 1Опубликовано: 14.01.2023

Подскажите, что не хватает в коде, чтобы выводилось 5 разных фотографий? И кто знает, как можно ещё упростить код, при создании 5 viewImage? А то, как-то грубо смотрится)

Выводятся одинаковые картинки

import SnapKit
import UIKit

class ViewController: UIViewController {
// Массив с данными(картинки)
private var images: [UIImage] = []

private lazy var stackView: UIStackView = {
    let view = UIStackView()
    view.axis = .vertical
    view.distribution = .fillEqually
    view.spacing = 10
    return view
}()

private lazy var activityIndicator: UIActivityIndicatorView = {
    let view = UIActivityIndicatorView(frame: CGRect(x: 220, y: 220, width: 140, height: 140))
    return view
}()

let service = Service()

private lazy var imageView: UIImageView = {
    let view = UIImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
    view.contentMode = .scaleAspectFit
    return view
}()

private lazy var imageView1: UIImageView = {
    let view = UIImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
    view.contentMode = .scaleAspectFit
    return view
}()

private lazy var imageView2: UIImageView = {
    let view = UIImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
    view.contentMode = .scaleAspectFit
    return view
}()

private lazy var imageView3: UIImageView = {
    let view = UIImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
    view.contentMode = .scaleAspectFit
    return view
}()

private lazy var imageView4: UIImageView = {
    let view = UIImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
    view.contentMode = .scaleAspectFit
    return view
}()

override func viewDidLoad() {
    super.viewDidLoad()
    
    view.addSubview(imageView)
    view.addSubview(activityIndicator)
    activityIndicator.startAnimating()
    
    onLoad()
    setupViews()
}

private func onLoad() {

    let dispatchGroup = DispatchGroup()
    // Формируем группу асинхронных операций
    for _ in 0...4 {
        dispatchGroup.enter()
        service.getImageURL { urlString, error in
            guard let urlString = urlString else { return }
            guard let image = self.service.loadImage(urlString: urlString) else { return }
            self.images.append(image)
            dispatchGroup.leave()
        }
    }
        // Обратный вызов на всю группу
        dispatchGroup.notify(queue: .main) { [ weak self ] in
            print(self!.images.count)
            print("images count")
            print(Thread.current)
            print("Thread current")
            guard let self = self else { return }
            self.activityIndicator.stopAnimating()
            self.stackView.removeArrangedSubview(self.activityIndicator)
            for i in 0...4 {
                self.imageView.image = self.images[i]
                self.imageView1.image = self.images[i]
                self.imageView2.image = self.images[i]
                self.imageView3.image = self.images[i]
                self.imageView4.image = self.images[i]
                self.stackView.addArrangedSubview(self.imageView)
                self.stackView.addArrangedSubview(self.imageView1)
                self.stackView.addArrangedSubview(self.imageView2)
                self.stackView.addArrangedSubview(self.imageView3)
                self.stackView.addArrangedSubview(self.imageView4)
                print(self.images[i])
            }
        }
}

private func setupViews() {
    view.addSubview(stackView)
    stackView.snp.makeConstraints { make in
        make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottomMargin)
        make.top.equalTo(view.safeAreaLayoutGuide.snp.topMargin)
        make.left.right.equalToSuperview()
    }
    stackView.addArrangedSubview(activityIndicator)
    activityIndicator.startAnimating()
}

}

import UIKit

struct Service {

func loadImage(urlString: String) -> UIImage? {
    guard
        let url = URL(string: urlString),
        let data = try? Data(contentsOf: url)
    else {
        print("Ошибка, не удалось загрузить изображение")
        return nil
    }
    
    return UIImage(data: data)
}

func getImageURL(completion: @escaping (String?, Error?) -> Void) {
    let url = URL(string: "https://dog.ceo/api/breeds/image/random")
    let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
        guard let data = data else {
            completion(nil, error)
            return
        }
        let someDictionaryFromJSON = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any]
        let imageUrl = someDictionaryFromJSON?["message"] as? String
        completion(imageUrl, error)
    }
    task.resume()
}

}

Ответы

▲ 0Принят

Вот здесь в цикле вы всем imageView.image присваиваете одну и ту же картинку, поэтому картинки одинаковые на всех imageView:

self.imageView.image = self.images[i]

Можно вот так, например, переписать ViewController:

import SnapKit
import UIKit

final class ViewController: UIViewController {
    
    private lazy var stackView: UIStackView = {
        let view = UIStackView()
        view.axis = .vertical
        view.distribution = .fillEqually
        view.spacing = 10
        return view
    }()
    
    private lazy var service = Service()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        onLoad()
        setupViews()
    }
    
    private func onLoad() {
        for _ in 0...4 {
            let activityIndicator = UIActivityIndicatorView(frame: CGRect(x: 220, y: 220, width: 140, height: 140))
            activityIndicator.startAnimating()
            stackView.addArrangedSubview(activityIndicator)
            
            service.getImageURL { [weak self] urlString, _ in
                guard let urlString, let image = self?.service.loadImage(urlString: urlString) else { return }
                
                DispatchQueue.main.async {
                    let view = UIImageView(frame: CGRect(x: 0, y: 0, width: 200, height: 200))
                    view.contentMode = .scaleAspectFit
                    view.image = image
                    
                    activityIndicator.stopAnimating()
                    self?.stackView.addArrangedSubview(view)
                }
            }
        }
    }
    
    private func setupViews() {
        view.addSubview(stackView)
        stackView.snp.makeConstraints { make in
            make.bottom.equalTo(view.safeAreaLayoutGuide.snp.bottomMargin)
            make.top.equalTo(view.safeAreaLayoutGuide.snp.topMargin)
            make.left.right.equalToSuperview()
        }
    }
}