изображение не отображается в UIImageView, даже если оно установлено - PullRequest
0 голосов
/ 13 февраля 2019

У меня есть collectionViewHeader с UIImageView, для которого задан серый backgroundColor.Есть addPhotoButton, и он переносит пользователя на другой контроллер.Когда они выбирают изображение, оно возвращается к исходному контроллеру, и это должно быть изображение в UIImageView.

Вот код из collectionViewHeader:

var selectedImage: UIImage? {
    didSet {
        self.imageView.image = selectedImage!
        print("This is the selectedImage:", selectedImage!)
    }
}


let imageView: UIImageView = {
    let iv = UIImageView()
    iv.backgroundColor = UIColor.rgb(red: 234, green: 246, blue: 246)
    iv.contentMode = .scaleAspectFill
    iv.clipsToBounds = true
    return iv
}()

Это то, что каждый учебникили StackOverflow сообщение, которое я наткнулся, сказал, чтобы сделать.И оператор print:

print("This is the selectedImage:", selectedImage!)

распечатывает:

This is the selectedImage: <UIImage: 0x600001000380>, {485, 482}

Итак, изображение есть, но оно не помещается в UIImageView.

ImageViewдобавляется в подпредставление и привязывается для установки размера в заголовке init:

override init(frame: CGRect) {
    super.init(frame: frame)

    addSubview(imageView)
    addSubview(addimageButton)
    addSubview(addimageText)

    if #available(iOS 11.0, *){
        eventImageView.anchor(top: safeAreaLayoutGuide.topAnchor, left: leftAnchor, bottom: nil, right: rightAnchor, paddingTop: 0, paddingLeft: 0, paddingBottom: 0, paddingRight: 0, width: frame.width, height: 175)
    } else {
        // Fallback on earlier OS?
    }
    addimageButton.anchor(top: eventImageView.topAnchor, left: eventImageView.leftAnchor, bottom: nil, right: imageView.rightAnchor, paddingTop: 25, paddingLeft: (imageView.bounds.size.width - addimageButton.bounds.size.width) / 2, paddingBottom: 0, paddingRight: 0, width: 0, height: 0)
    addimageText.anchor(top: nil, left: imageView.leftAnchor, bottom: imageView.bottomAnchor, right: imageView.rightAnchor, paddingTop: 0, paddingLeft: (imageView.bounds.size.width - addimageButton.bounds.size.width) / 2, paddingBottom: 25, paddingRight: 0, width: 0, height: 0)
}

selectedImage устанавливается в заголовке другого контроллера здесь:

override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
    let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: headerId, for: indexPath) as! PhotoSelectorHeader

    self.header = header

    header.photoImageView.image = selectedImage

    if let selectedImage = selectedImage {
        if let index = self.images.index(of: selectedImage) {
            let selectedAsset = self.assets[index]

            let imageManager = PHImageManager.default()
            let targetSize = CGSize(width: 600, height: 600)
            imageManager.requestImage(for: selectedAsset, targetSize: targetSize, contentMode: .default, options: nil, resultHandler: { (image, info) in

                header.photoImageView.image = image

            })

        }
    }

    return header
}

fileprivate func setupNavigationButtons() {
    navigationController?.navigationBar.tintColor = .black
    navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Cancel", style: .plain, target: self, action: #selector(handleCancel))

    navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Select", style: .plain, target: self, action: #selector(handleNext))
}

@objc func handleNext() {
    let addPhotoHeader = AddPhotoHeader()
    addPhotoHeader.selectedImage = header?.photoImageView.image
    navigationController?.popViewController(animated: true)
}

Я уверен, что здесь есть быстрый шаг, который я пропускаю, но я застрял на пару дней сейчас!

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

Заранее спасибо за помощь !!

1 Ответ

0 голосов
/ 13 февраля 2019

Две проблемы:

  1. Вы не вызываете это в главном потоке (который может работать, если он установлен из основного потока, но я 'Я предполагаю, что это не так, поскольку UIImageView не обновляется надлежащим образом.

  2. (необязательно исправить) Вы запрашиваете сбой принудительным приведением этого необязательного selectedImage.

var selectedImage: UIImage? {
    didSet {
        DispatchQueue.main.async { [weak self] in
            // Don't force-cast (!) the optional selectedImage.
            // Since you can assign a nil image to self?.imageView.image, do that instead
            // Other option is adding a guard-statement here:
            // guard selectedImage != nil else { return }
            self?.imageView.image = selectedImage
            print("This is the selectedImage:", selectedImage)
        }
    }
}

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

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

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

@ twostraws (Twitter)проделывает большую работу, объясняя основную тему здесь: https://www.hackingwithswift.com/read/9/4/back-to-the-main-thread-dispatchqueuemain

Он упоминает об этом, и я не могу согласиться больше:

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

Надеюсь, это поможет!

...