Установка высоты заголовка таблицы в Swift

Я пытаюсь установить высоту представления, которое находится поверх моей ячейки прототипа в контроллере табличного представления. Я использую IB, чтобы установить его высоту (инспектор размера) и установить его равным 61 (зеленый вид - это "заголовок" ):

вид заголовка

Но всякий раз, когда я запускаю приложение, его высота заканчивается 568.0. У меня есть IBOutlet, называемый testUIView для представления в моем контроллере представления таблицы, и я делаю: println("testUIView Height->\(testUIView.frame.height)") и действительно заканчивается 568.0 во время выполнения.

Вот скриншот, показывающий его высоту во время выполнения:

введите описание изображения здесь

Итак, мой вопрос: как я могу установить высоту представления, так что во время выполнения он равен 61, поэтому он действительно выглядит как мой первый скриншот (размер)?

Я попытался установить его свойство height внутри override func viewWillLayoutSubviews(), но не дал мне присваивать значение высоте testUIView.frame.height = CGFloat(61.0).

Любая помощь приветствуется! Спасибо заранее!

Ура!

Ответы

Ответ 1

Вот решение, которое использует представления заголовка раздела, а не фактическое представление заголовка таблицы:


Если вы хотите использовать для UITableView заголовок, вместо этого вы можете создать другую ячейку прототипа в Интерфейсном Разработчике, создать собственный класс на основе UITableViewCell и назначить его ячейке прототипа в конструкторе интерфейсов в Инспекторе классов.

Тогда в вашем контроллере вы будете использовать

func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView?

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

return cell.contentView

Другой метод, который вы собираетесь использовать, это

func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 61.0
}

Этот довольно понятен.

Swift 3.0.1

public override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return 61.0
}

Ответ 2

Swift 3/Xcode 8:

Добавьте это в viewDidLoad():

let HEADER_HEIGHT = 100
tableView.tableHeaderView?.frame.size = CGSize(width: tableView.frame.width, height: CGFloat(HEADER_HEIGHT))

Наслаждайтесь!

Ответ 3

В swift 4.1 и Xcode 9.4.1

func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
     if UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.pad {
        return 75.0
      } else {
        return 50.0
      }
}

Ответ 4

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


Загрузка представления

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

Сначала нам нужно загрузить заголовок и вручную установить его высоту. В противном случае вид займет больше высоты, чем нужно. Мы делаем это с помощью обратного вызова viewDidLayoutSubviews:

lazy var profileHeaderView: ProfileHeaderView = {
    let headerView = ProfileHeaderView()
    return headerView
}()

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    sizeHeaderToFit()
}

private func sizeHeaderToFit() {
    profileHeaderView.setNeedsLayout()
    profileHeaderView.layoutIfNeeded()

    var frame = profileHeaderView.frame
    frame.size.height = profileHeaderView.calculateHeight()
    profileHeaderView.frame = frame

    tableView.tableHeaderView = profileHeaderView
}

Как видите, мне нравится размещать свои взгляды внутри ленивых переменных. Это гарантирует, что они всегда создаются, но только когда я начинаю их использовать.

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


Установите некоторые приоритеты

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

Чтобы очистить их, мы просто устанавливаем приоритеты ограничений. Сначала вы должны обернуть компоненты представления заголовка в другое представление (я обычно всегда делаю это для представлений заголовка). Это значительно облегчит управление ограничениями в представлении заголовка.

Затем нам нужно установить высокие приоритеты нижнего ограничения:

containerView.setContentCompressionResistancePriority(.defaultHigh, for: .vertical)
containerView.setContentHuggingPriority(.defaultHigh, for: .vertical)

Вот более полный пример:

ПРЕДУПРЕЖДЕНИЕ. Хотя оно по-прежнему полезно в качестве руководства для разметки ваших представлений, не используйте этот код, если вы создаете свои представления с помощью перьев или раскадровок.

class ProfileHeaderView: UIView {
    lazy var containerView: UIView = {
        let view = UIView()
        return view
    }()

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

    required init?(coder aDecoder: NSCoder) {
        // We do this because the view is not created using storyboards or nibs.
        fatalError("init(coder:) has not been implemented")
    }

    private func setupLayout() {
        self.addSubview(containerView)

        containerView.translatesAutoresizingMaskIntoConstraints = false
        containerView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
        containerView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
        containerView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
        containerView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
        containerView.setContentCompressionResistancePriority(.defaultHigh, for: .vertical)
        containerView.setContentHuggingPriority(.defaultHigh, for: .vertical)

        // Set the rest of your constraints against your containerView not self and add your subviews to your containerView not self
    }
}

Вот пример ограничений, установленных с помощью Snap-Kit:

containerView.snp.makeConstraints() { make in
    make.top.equalTo(self.snp.top)
    make.leading.equalTo(self.snp.leading)
    make.trailing.equalTo(self.snp.trailing)
    make.bottom.equalTo(self.snp.bottom).priority(.high)
}

Убедитесь, что вы добавляете свои ограничения в containerView, а не в self, и используете containerView для добавления ваших подпредставлений и остальных ваших ограничений.

Ответ 5

Это должно быть одной из самых странных проблем в iOS.

Если вы просто хотите иметь фиксированную высоту, то с 2019 года вы можете:

public override func viewDidLayoutSubviews() {
    var frame = tableView.tableHeaderView!.frame
    frame.size.height = 68
    tableView.tableHeaderView!.frame = frame
}

Странные вещи.