У меня есть UITableView
, который загружает изображения из службы. Он извлекает URL-адреса и загружает изображения с NSURLSession.sharedSession().dataTaskWithURL
:UIImageView изначально не отображает изображение в UITableViewCell
NSURLSession.sharedSession().dataTaskWithURL(url, completionHandler: { (data, _, error) -> Void in
guard
let data = data where error == nil,
let image = UIImage(data: data)
else {
print(error?.localizedDescription)
return
}
dispatch_async(dispatch_get_main_queue()) {
[unowned self] in
self.pictureView.image = image
self.pictureView.layoutIfNeeded()
}
}).resume()
UIImageView
является выход на раскадровку сцены. Режим содержимого UIImageView
- это Aspect Fit.
UIImageView
для видимых ячеек первоначально отображается пустым (без изображения), хотя я подтвердил, что изображение было установлено. Пока камера не будет прокручена/на экране, ячейка будет перерисовываться (?) И отображать изображение.
Так что это похоже на какой-то вопрос синхронизации, но я не могу понять это. Я попытался назвать все следующие в dispatch_async
блока после того, как изображение будет установлено:
self.pictureView.setNeedsDisplay()
self.pictureView.setNeedsUpdateConstraints()
self.pictureView.setNeedsLayout()
self.pictureView.reloadInputViews()
Ни один из них не решить эту проблему. Что вызывает отображение этого изображения только после прокрутки ячейки/просмотра?
EDIT: Возможно, важно отметить, что это происходит внутри наконечника и связанного с ним класса. Загружается ниб, затем я запускаю загрузку. Я задаюсь вопросом, выкопал ли ниб, и к моменту загрузки моего изображения и установки на UIImageView
завершение макета завершено. Затем, перемещая ячейку (содержащую ниб) на экране, ячейка снова выполняет макет, и все отображается правильно. Просто догадаться, и я все еще придерживаюсь этого.
EDIT 2: Дальнейшее уточнение процесса:
1) Мои UIViewController
содержит UITableView
.
2) Этот UITableView
загружает ячейки из пользовательского класса UITableViewCell
под названием PostCell.
3) Все содержимое PostCell представляет собой одно представление, загруженное из ножа, называемого PostView (с классом PostView). Это происходит во время загрузки init:style:reuseIdentifier
в PostCell:
postView = NSBundle.mainBundle().loadNibNamed("PostView", owner: self, options: nil).first as? PostView
4) Затем я объект Сообщение от postView
:
postView.post = Post
Обратите внимание, что это происходит после awakeFromNib()
вызывается PostView.
5) Свойство post
на PostView имеет наблюдателя didSet
, который запускает загрузку изображения на основе URL-адреса в объекте post
(код выше). Изображение загружается и устанавливается на UIImageView
по имени pictureView
.
Edit 3:
Вот код для tableView(_:cellForRowAtIndexPath:)
:
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCellWithIdentifier(postCellIdentifier) as? PostCell
if cell == nil {
cell = PostCell()
}
if let postCell = cell,
let postArray = postArray,
let post = postArray[indexPath.row] {
postCell.post = post
return postCell
}
// This section is hit during a refresh.
let emptyCell = UITableViewCell()
emptyCell.contentView.backgroundColor = .whiteColor()
return emptyCell
}
Редактировать 4:
Я обнаружил, что если я "премьер" UIImageView
путем предварительной установки заполнители изображение в норе, затем загрузите мое изображение в это UIImageView
, изображение будет отображаться на высоте заполнителя. Когда я снова вытащил эту ячейку, затем снова включится, UIImageView
будет рисовать изображение с правильным размером, используя установку ограничений в наконечнике.
Таким образом, ограничения и размер UIImageView
были установлены к тому моменту, когда изображение загружается, а снятие его/с экрана вызывает перерисовку, которая изменяет размер изображения должным образом. Если бы я мог программно запускать эту перерисовку, это помогло бы, но см. Выше для того, что я уже пробовал.
Редактировать 6:
Здесь находится в действии. Обратите внимание, что я установил изображение-заполнитель в наконечнике. Это, по-видимому, приводит к тому, что изображение будет отображаться при первоначальной загрузке, но по размерам заполнителя. При прокрутке его на экране кратковременное изменение размера, когда оно отображается правильно.
Edit 7:
Я использую PostView перо в другом месте в моем приложении без проблем. Когда он загружается, размер изображения будет правильно установлен. Кажется, проблема только в том, что nib встроен в UITableViewCell
.
Edit 8:
Я нашел причину этой проблемы, названную в viewDidLoad из моих UIViewController
:
tableView.estimatedRowHeight = 500
tableView.rowHeight = UITableViewAutomaticDimension
Использования автоматического измерения вызывает первоначальную неправильную высоту строки. По какой-то причине прокрутка ячейки/в представлении будет правильно подсчитать высоту строки, и изображение будет отображаться на правильной высоте. Удаление этого кода приведет к отображению изображения, но высота строки не может быть использована для расчета автоматической высоты. Каков наилучший метод автоматического расчета высоты строк и все еще избежать этой проблемы?
когда вы называете dataTaskWithURL? –
@TejaNandamuri Он вызывается в 'tableView: cellForRowAtIndexPath'. Я получаю пользовательский 'UITableViewCell' с' dequeueReusableCellWithIdentifier'. Затем я устанавливаю объект на эту ячейку, у которой есть 'didSet', который извлекает изображение. – Fook
'self.pictureView.image = image' или' cell.pictureView.image = image'? – Proton