Развернуть UITableView, чтобы отобразить все ячейки в представлении стека?

У меня возникли проблемы с отображением моего UITableView в полную высоту в моем представлении стека.

Мое дерево просмотра выглядит следующим образом:

- View
  - Scroll View
    - Stack View
      - Table View
      - Image View
      - Map View

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

Я попытался отрегулировать высоту таблицы следующим образом, но это просто закончилось тем, что таблица больше не прокручивается, хотя даже если бы это сработало, я бы предпочел что-то более динамичное:

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)        
    self.detailsTableView.frame.size.height = 200
}

Я подозреваю, что это, вероятно, аспект «представления стека», который нуждается в настройке, но я не уверен на данный момент. Может ли кто-нибудь предложить подходящий способ?


person Andre M    schedule 08.03.2016    source источник


Ответы (2)


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

Расширение для создания экземпляра и централизованного позиционирования UIStackView.

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

extension UIStackView {
    
    convenience init(axis:UILayoutConstraintAxis, spacing:CGFloat) {
        self.init()
        self.axis = axis
        self.spacing = spacing
        self.translatesAutoresizingMaskIntoConstraints = false
    }
    
    func anchorStackView(toView view:UIView, anchorX:NSLayoutXAxisAnchor, equalAnchorX:NSLayoutXAxisAnchor, anchorY:NSLayoutYAxisAnchor, equalAnchorY:NSLayoutYAxisAnchor) {
        view.addSubview(self)
        anchorX.constraintEqualToAnchor(equalAnchorX).active = true
        anchorY.constraintEqualToAnchor(equalAnchorY).active = true
        
    }
    
}

Мы не устанавливаем размер для UIStackView только для позиции, это вещи, содержащиеся в нем, которые определяют его размер. Также обратите внимание на установку translatesAutoresizingMaskIntoConstraints в false в расширении UIStackView. (Требуется только, чтобы мы установили это свойство для представления стека, его подпредставления просто наследуют поведение.)

Класс UITableView с исходным кодом данных

Затем я создал базовый класс таблицы для демонстрационных целей.

class MyTable: UITableView, UITableViewDataSource {
    let data = ["January","February","March","April","May","June","July","August","September","October","November","December"]
    func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return data.count
    }
    func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("SauceCell", forIndexPath: indexPath)
        cell.textLabel?.text = data[indexPath.row]
        return cell
    }
}

Настройка представления стека и таблицы в контроллере представления

Наконец, важные вещи. Как только мы добавляем нашу таблицу в представление стека, вся информация о фрейме игнорируется. Поэтому нам нужны последние две строки кода, чтобы установить ширину и высоту таблицы в терминах, понятных Auto Layout.

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        let table = MyTable(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height))
        table.registerClass(UITableViewCell.self, forCellReuseIdentifier: "SauceCell")
        table.dataSource = table

      
        let stack = UIStackView(axis: .Vertical, spacing: 10)
        stack.anchorStackView(toView: view, anchorX: stack.centerXAnchor, equalAnchorX: view.centerXAnchor, anchorY: stack.centerYAnchor, equalAnchorY: view.centerYAnchor)
        
        stack.addArrangedSubview(table)

        
        table.widthAnchor.constraintEqualToAnchor(view.widthAnchor, multiplier: 1).active = true
        table.heightAnchor.constraintEqualToAnchor(view.heightAnchor, multiplier: 0.5).active = true
        
    }
    
    
}

Обратите внимание, что мы используем addArrangedSubview: а не addSubview: при добавлении представлений в представление стека.

(Я написал сообщения в блоге об UIStackView, а также другие сведения об автоматическом макете в вообще это тоже может помочь.)

person sketchyTech    schedule 08.03.2016

Я столкнулся с той же проблемой и понял, что вам нужно табличное представление с собственным размером. Я наткнулся на этот ответ и создал подкласс, предложенный @MuHAOS. Я не сталкивался с какими-либо проблемами.

final class IntrinsicTableView: UITableView {

    override var contentSize: CGSize {
        didSet {
            invalidateIntrinsicContentSize()
        }
    }


    override var intrinsicContentSize: CGSize {
        layoutIfNeeded()
        return CGSize(width: UIView.noIntrinsicMetric, height: contentSize.height)
    }

}
person Maria    schedule 14.09.2016
comment
Именно то, что мне было нужно, спасибо. У вас все получится! - person jowie; 12.12.2018
comment
Это должен быть принятый ответ. Спасибо @Мария - person joe; 31.07.2019
comment
Ты святой - person Henry; 22.10.2019
comment
Может кто-нибудь объяснить ответ? - person Aleksandr Maybach; 17.03.2020