2017-01-06 6 views
1

Код следует после этого объяснения проблемы.Как установить ограничения для изменяемых высот на UITableViewCells, которые имеют от 0 до 2 изображений?

У меня есть UIViewController, содержащий UITableView, в UITableViewCell «ы которых показывают либо один, два, или ноль изображений. С одним и двумя изображениями высота ячейки всегда равна 72, но без каких-либо изображений она должна быть равна нулю. У меня есть две UIView в моей ячейке таблицы, первая из которых содержит одну UIImageView, а вторая из них содержит два из них. Я либо скрываю, либо показываю соответствующий, в зависимости от того, имеет ли эта ячейка одно или два изображения. Если ячейка имеет нулевые образы, то оба UIView скрыты, но, конечно, они все еще составляют часть установленных ограничений, и поэтому результирующая ячейка по-прежнему высотой 72 пикселя, тогда как мне нужно ее свернуть.

Мне сказали, что только способ создания высоты-изменяемыми UITableViewCell «S является установка ограничений в раскадровке, и что возиться со значениями ограничений программно на лету вызовет проблемы компоновки. Я не знаю, является ли каким-либо из этой консультации верно или нет, поэтому я попробовал следующего (без успеха):

  1. установки явных ссылок на мои UIViewNSLayoutConstraint-х, которые контролируют высоту в моих ResizableImageCell вызов, вызывающий ошибки Unable to simultaneously satisfy constraints; и

  2. установка прямых ссылок на всеNSLayoutConstraint «S, которые контролируют высоту в моем ResizableImageCell вызова; и/или

  3. добавление и удаление UIView, оба из которых работают нормально, пока вы не начнете прокручивать стол, после чего стол начинает прыгать вверх и вниз после того, как вы поднимаете палец с экрана.

Это текущий код, который управляет ViewController:

import UIKit 

class ViewController: UIViewController 
{ 
    @IBOutlet weak var tableView: UITableView! 

    let imageNames = [ "room", "street", "tree" ] 



    override func viewDidLoad() 
    { 
     super.viewDidLoad() 

     tableView.delegate = self 
     tableView.dataSource = self 
     tableView.rowHeight = UITableViewAutomaticDimension 
     tableView.estimatedRowHeight = 44.0 
    } 



    func getRandomInt (from start: Int, to end: Int) -> Int 
    { 
     return Int(arc4random_uniform(UInt32((end + 1) - start))) + start 
    } 
} 



extension ViewController: UITableViewDataSource 
{ 
    @available(iOS 2.0, *) 
    public func tableView (_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "ResizableImageCell") as! ResizableImageCell 
     let numImages = getRandomInt(from: 0, to: 2) 

     cell.view1.isHidden = numImages != 1 
     cell.view2.isHidden = numImages != 2 

     var rand = getRandomInt(from: 0, to: imageNames.count - 1) 

     switch numImages 
     { 
     case 1:  cell.image1.image = UIImage(named: imageNames[ rand ]) 
     case 2:  cell.image2.image = UIImage(named: imageNames[ rand ]) 
     default: () 
     } 

     guard numImages == 2 else { return cell } 

     rand = getRandomInt(from: 0, to: imageNames.count - 1) 

     cell.image3.image = UIImage(named: imageNames[ rand ]) 

     return cell 
    } 



    func tableView (_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    { 
     return 64 
    } 
} 

Это текущий код, который управляет мой заказ ResizableImageCell клетки

import UIKit 

class ResizableImageCell: UITableViewCell 
{ 
    @IBOutlet weak var view1: UIView! 
    @IBOutlet weak var view2: UIView! 

    @IBOutlet weak var image1: UIImageView! 
    @IBOutlet weak var image2: UIImageView! 
    @IBOutlet weak var image3: UIImageView! 



    override func awakeFromNib() 
    { 
     super.awakeFromNib() 
    } 
} 

А вот скриншот из существующих раскадровка:

screenshot of a storyboard from XCode

Благодарим за внимание.

ответ

1

Я решил эту проблему в своем проекте, используя функцию heighForRow.

В ViewController:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 

    //Check if you have to display images or not 

    //return 75 or CGFloat.ulpOfOne 
} 

Может быть, с этим решением, которое вы должны сделать свой let numImages = getRandomInt(from: 0, to: 2) до функции cellForRowAtIndexPath и хранить 64 результатов в виде массива.

EDIT: Важное примечание от Josh Homann:

Не возвращать 0 для высоты или вы можете получить некоторые ошибки автоматической компоновки в консоли, потому что ваш прямоугольник является вырожденным. return CGFloat.ulpOfOne, который бесконечно мал, но все же не равен нулю.

+0

Спасибо @ Chief-Lutz, я попробую это и дам вам знать результаты. –

+0

Итак, @ Chief-Lutz: пока ничего не закончилось, но это выглядит так: * ваше предложение будет работать, спасибо. –

+0

@ TheMotherofJosephBeuys - Надеюсь, это помогло. Добро пожаловать :) –

0

Решив эту проблему, используя @heightForRowAt предложения Шефа-Луца (описанное выше) сразу же, я впоследствии понял, что еще одно решение, которое будет работать одинаково хорошо. Вместо того, чтобы выполнять расчеты высоты внутри heightForRowAt, возможно иметь несколько наконечников, каждый из которых рассчитан на различное количество изображений. Поверхность этого заключается в том, что расчет высоты выполняется под капотом, что делает ваш код более простым и коротким; в то время как недостаток имеет несколько наконечников, возможно, с некоторыми повторяющимися макетами и/или ограничениями внутри них.

Такой подход оказывается особенно полезным, если ваши клетки содержат один или более нулевой линии UILabel «ы, потому что часть расчета необходимого в heightForRowAt в данном случае включает в себя [ре] создание клеток UILabel» S и заселение их с текстом, чтобы они могли изменять размер и сообщать вам, насколько высоко каждый из них будет находиться внутри ячейки при его рендеринге (heightForRowAt называется доcellForRowAt).