Установка высоты заголовка таблицы в 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
}
Странные вещи.