Ответы пользователя по тегу Swift
  • Почему не работает протокол?

    Потому что вы не назначили нужный класс делегатом.

    Что-то вроде menuViewController.delegate = self это пишите в классе, который будет делегатом, будет принимать действия
    Ответ написан
  • Почему сменяются ячейки в 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 комментарий
  • Ошибка в Xcode “invalid redeclaration of str, как исправить или в чем причина?

    Все верно, вы создаете переменную "str" в то время, когда у вас уже создана данная переменная.
    Если вы хотите изменить переменную str то нужно убрать "var", потому что это ключевое слово создает переменную
    либо, если вы все же хотите именно создать переменную, то нужно указывать имя, которое ранее в коде не использовалось.
    Ответ написан
    Комментировать
  • Из-за чего появляется предупреждение в консоли xcode и что оно обозначает?

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

    Если у вас все работает, не обращайте внимания на это предупреждение, судя по всему оно не вызывает каких либо проблем.
    Ответ написан
    Комментировать
  • Swift, Kotlin vs C++. Что нативнее для мобильных устройств?

    Практически невозможно.
    Реализовать можно, но так практически никто не делает, потому что это просто неэффективно, гораздо быстрее, и менее трудозатратно написать отдельно
    Ответ написан
    Комментировать
  • 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 комментарий
  • Что означает знак вопроса в классе?

    Вы создаете переменную, и явно указываете, что в этой переменной должен быть объекта Apartment
    var apartment: Apartment

    Но при создании переменной вы указали тип, но не указали что в ней находится. То есть вы просто сделали пустую переменную, в которой должен находиться объект Apartment, а в swift в переменной обязательно должно что-то быть. И тут вопрос, что положить в эту переменную, если объектов Apartment еще не создано в проекте? Swift предлагает следующее решение:

    Указать тип переменной как опциональный, делается это путем установки в конце типа знака вопроса "?".
    var apartment: Apartment?
    Это позволяет сообщить переменной, что в ней значение будет не определено, оно может быть, а может и не быть.

    Интуитивно мы можем понять это так:
    Переменная как шкаф, которая требует, чтобы в него что-то положили, иначе работать он не будет, мы как бы обманываем этот шкаф, и кладем в него пустую коробку, и как бы шкаф уже не пустой, условия работы шкафа выполнены, по факту в нем коробка, но она пустая.
    И в будущем мы сможем в эту самую пустую коробку положить объект Apartment, и в итоге у нас будет шкаф, в котором коробка, в которой находится объект

    Нюанс работы:
    Но тут возникает следующий нюанс, когда мы захотим забрать этот объект из шкафа, мы получим как раз ту самую коробку, в которой будет нужны нам объект, и нам нужно будет соответственно достать этот объект из коробки, это называется "раскрытие опционала".

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

    Указать тип переменной
    Ответ написан
    Комментировать