• Как решить проблему с потоками при обработке данных?

    Loriens
    @Loriens
    iOS Developer
    Вообще твой вариант должен работать. Когда ты вызываешь `cartCV.reloadData()`, collection view перерисовывается.

    Во-первых, задал ли ты data source и delegate для collection view? В коде этого нет, но может ты сделал это в сториборде. В коде это выглядело бы так:
    override func viewDidLoad() {
        super.viewDidLoad()
        cartCV.dataSource = self
        cartCV.delegate = self
        dataProcessing()
        print(imageArr.count)
    }


    Во-вторых, `cell.cartImageView.image = UIImage(data: try! Data(contentsOf: imageUrl!))` - очень плохо. Это будет выполняться в главном потоке, соответственно, приложение будет заморожено на момент загрузки картинок. Нужно делать это асинхронно. Желательно избегать force unwrapping. Например, так:
    DispatchQueue.global().async {
        if let imageUrl = imageUrl,
            let data = try? Data(contentsOf: imageUrl) {
            DispatchQueue.main.async {
                self.cell.cartImageView.image = UIImage(data: data)
            }
        }
    }

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

    Также есть хорошая либа для асинхронной подгрузки картинок - Kingfisher. C ней подгрузка изображения выглядела бы так:
    cell.cartImageView.kf.setImage(with: imageUrl)
    Ответ написан
    1 комментарий
  • Как создать несколько UIView через цикл?

    ivanvorobei
    @ivanvorobei
    iOS разработчик, канал https://t.me/sparrowcode
    Так как вы написали:

    Пытаюсь разобраться в разработке интерфейсов под Ios

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

    Назовем один товар ячейкой. Если ячейка должна занимать весь экран от края до края по ширине - используйте UITableView (называют таблицей), если ячеек по ширине может быть несколько - используйте UICollectionView (называют коллекцией).

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

    Метод для количества элементов в таблице:
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int

    Как видите, возвращает целое число.

    Метод для возрата вью, для таблицы вернуть объект UITableViewCell:
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell

    Просто UIView вернуть нельзя, она не реализует протокол для переиспользования. Но в UITableViewCell можно положить любые вью, которые вы хотите. Это своего рода контейнер. Перед использованием класса ячейки, нужно зарегистрировать класс.

    На моем канале есть ролик про переиспользование в таблице. На сайте эпл можно почитать про таблицу и коллекцию.

    Это основная концепция. Вам предстоит узнать что такое DataSource, Delegate, размеры, Layout (для коллекции). Не пугайтесь, про это написано много туториалов даже на русском.

    P.S. Автор захотел решить задачу с помощью цикла и кодом, привожу пример:
    Вынесем значение Y за цикл. Можно объявить здесь же параметры высоты и ширины:
    var currentY: CGFloat = 0
    let width: CGFloat = 375
    let height: CGFloat = 100
            
    for i in 0...3 { 
    
    }

    В цикле будем генерировать вью и ее настраивать. Лейаут subviews можно сделать там же:
    for i in 0...3 {
                var view = UIView()
                view.frame = CGRect.init(x: 0, y: currentY, width: width, height: height)
                currentY += view.frame.height + 10
    }

    Я приведу только генерацию вьюхи. Как размещать элементы внутри вы уже знаете. 10 - это отступ между вьюхами.
    Ответ написан
    2 комментария