Поскольку я обнаружил, AutoLayout
что использую его везде, теперь я пытаюсь использовать его с tableHeaderView
.
Я сделал subclass
из UIView
добавленных все (этикеток и т.д. ...) Я хотел с их ограничениями, то я добавил это CustomView
к UITableView
' tableHeaderView
.
Все работает отлично , за исключением UITableView
всегда отображается вышеCustomView
, по выше я имею в виду CustomView
это подUITableView
поэтому он не может быть виден!
Кажется , что независимо от того , что я делаю, то height
из UITableView
' tableHeaderView
является всегда 0 (так ширина х и у).
У меня вопрос: а можно ли вообще это сделать без ручной настройки рамки ?
EDIT:CustomView
' , subview
что я использую имеет следующие ограничения:
_title = [[UILabel alloc]init];
_title.text = @"Title";
[self addSubview:_title];
[_title keep:[KeepTopInset rules:@[[KeepEqual must:5]]]]; // title has to stay at least 5 away from the supperview Top
[_title keep:[KeepRightInset rules:@[[KeepMin must:5]]]];
[_title keep:[KeepLeftInset rules:@[[KeepMin must:5]]]];
[_title keep:[KeepBottomInset rules:@[[KeepMin must:5]]]];
Я использую удобную библиотеку KeepLayout, потому что написание ограничений вручную занимает вечность и слишком много строк для одного ограничения, но методы говорят сами за себя.
И у UITableView
него есть следующие ограничения:
_tableView = [[UITableView alloc]init];
_tableView.translatesAutoresizingMaskIntoConstraints = NO;
_tableView.delegate = self;
_tableView.dataSource = self;
_tableView.backgroundColor = [UIColor clearColor];
[self.view addSubview:_tableView];
[_tableView keep:[KeepTopInset rules:@[[KeepEqual must:0]]]];// These 4 constraints make the UITableView stays 0 away from the superview top left right and bottom.
[_tableView keep:[KeepLeftInset rules:@[[KeepEqual must:0]]]];
[_tableView keep:[KeepRightInset rules:@[[KeepEqual must:0]]]];
[_tableView keep:[KeepBottomInset rules:@[[KeepEqual must:0]]]];
_detailsView = [[CustomView alloc]init];
_tableView.tableHeaderView = _detailsView;
Я не знаю, нужно ли мне устанавливать какие-то ограничения непосредственно на CustomView
, я думаю, что высота CustomView определяется ограничениями на UILabel
«заголовок» в нем.
РЕДАКТИРОВАТЬ 2: после другого исследования кажется, что высота и ширина CustomView рассчитаны правильно, но верх CustomView по-прежнему находится на том же уровне, что и верх UITableView, и они перемещаются вместе, когда я прокручиваю.
источник
Ответы:
Я задал и ответил на аналогичный вопрос здесь . Таким образом, я добавляю заголовок один раз и использую его, чтобы найти нужную высоту. Затем эту высоту можно применить к заголовку, и заголовок устанавливается второй раз, чтобы отразить изменение.
Если у вас есть многострочные метки, это также зависит от пользовательского представления, устанавливающего предпочитаемую максимальную ширину каждой метки:
или, возможно, в более общем плане:
Обновление за январь 2015 г.
К сожалению, это все еще кажется необходимым. Вот быстрая версия процесса верстки:
Я счел полезным переместить это в расширение UITableView:
Использование:
источник
preferredMaxLayoutWidth
является добавление ограничения ширины (равной ширине представления таблицы) в представление заголовка перед использованиемsystemLayoutSizeFittingSize:
.self.tableView.tableHeaderView
let height = header.systemLayoutSizeFittingSize(CGSizeMake(CGRectGetWidth(self.bounds), 0), withHorizontalFittingPriority: UILayoutPriorityRequired, verticalFittingPriority: UILayoutPriorityFittingSizeLevel).height
header.setNeedsLayout() header.layoutIfNeeded() header.frame.size = header.systemLayoutSizeFitting(UILayoutFittingCompressedSize) self.tableHeaderView = header
будет работать с iOS 10.2Мне не удалось добавить представление заголовка с использованием ограничений (в коде). Если я даю своему представлению ограничение ширины и / или высоты, я получаю сбой с сообщением:
Когда я добавляю представление в раскадровке в представление таблицы, оно не показывает ограничений и отлично работает как представление заголовка, поэтому я думаю, что размещение представления заголовка не выполняется с использованием ограничений. В этом отношении это не похоже на нормальный взгляд.
Ширина автоматически равна ширине табличного представления, единственное, что вам нужно установить, это высота - исходные значения игнорируются, поэтому не имеет значения, что вы для них вставили. Например, это сработало нормально (как и 0,0,0,80 для прямоугольника):
источник
translatesAutoresizingMaskIntoConstraints = NO
. Включение перевода предотвращает ошибку - я подозреваю,UITableView
что начиная с версии 7.1 не пытается автоматически раскладывать представление заголовка и хочет что-то с предустановленным фреймом.Я видел здесь множество методов, делающих так много ненужного, но вам не нужно так много, чтобы использовать автоматический макет в представлении заголовка. Вам просто нужно создать свой xib-файл, указать свои ограничения и создать его экземпляр следующим образом:
источник
Другое решение - отправить создание представления заголовка следующему вызову основного потока:
Примечание. Исправлена ошибка, когда загруженный вид имел фиксированную высоту. Я не пробовал, когда высота заголовка зависит только от его содержимого.
РЕДАКТИРОВАТЬ :
Вы можете найти более чистое решение этой проблемы, реализовав эту функцию и вызвав ее в
viewDidLayoutSubviews
источник
tableHeaderView
вроде глючит с автопложением. Есть некоторые обходные пути, подобные этому. Но так как я писал это, я нашел лучший и чистый раствор здесь stackoverflow.com/a/21099430/127493 вызывая его- (void)sizeHeaderToFit
инviewDidLayoutSubviews
Код:
источник
Расширено это решение http://collindonnell.com/2015/09/29/dynamically-sized-table-view-header-or-footer-using-auto-layout/ для просмотра нижнего колонтитула таблицы:
источник
self.tableFooterView.transform
часть? Зачем это нужно?Вы можете настроить автоматическое размещение, чтобы указать размер, используя метод systemLayoutSizeFittingSize .
Затем вы можете использовать это для создания фрейма для вашего приложения. Этот метод работает всякий раз, когда вам нужно знать размер представления, в котором используется автоматическое размещение.
Код в swift выглядит так
Или в Objective-C
Следует также отметить, что в этом конкретном случае переопределение requiresConstraintBasedLayout в вашем подклассе действительно приводит к выполнению прохода макета, однако результаты этого прохода макета игнорируются, а системный фрейм устанавливается на ширину tableView и высоту 0.
источник
Следующее сработало для меня.
UIView
заголовка используйте обычное старое .UIView
Основное преимущество, которое я вижу, - это ограничение вычислений кадров. Apple действительно стоит обновить
UITableView
API, чтобы упростить эту задачу.Пример использования SnapKit:
источник
Бывают странные вещи. systemLayoutSizeFittingSize отлично работает для iOS9, но не для iOS 8 в моем случае. Так что эту проблему решить довольно просто. Просто получите ссылку на нижний вид в заголовке и в viewDidLayoutSubviews после границ представления заголовка обновления супервызова, вставив высоту как CGRectGetMaxY (yourview.frame) + padding
UPD: самое простое решение : в заголовке поместите subview и закрепите его слева , справа , сверху . В этом подвиде поместите свои подвиды с ограничениями автоматической высоты. После этого отдайте всю работу автолистке (расчет не требуется)
В результате subview расширяется / сжимается, как и должно, в конце вызывается viewDidLayoutSubviews. В то время мы знаем фактический размер представления, поэтому установите высоту headerView и обновите его, переназначив. Работает как шарм!
Также работает для нижнего колонтитула.
источник
Обновлено для Swift 4.2
источник
вы можете добавить ограничение верхнего + горизонтального расположения между заголовком и табличным представлением, чтобы правильно разместить его (если сам заголовок содержит все необходимые внутренние ограничения макета для правильного фрейма)
в методе viewDidLoad tableViewController
источник
Мое представление заголовка таблицы является подклассом UIView - я создал один contentView UIView в инициализаторе с его границами, такими же, как у кадра представления заголовка таблицы, и добавил все свои объекты в качестве его подпредставления.
Затем добавьте ограничения для ваших объектов в
layoutSubviews
методе представления заголовка таблицы, а не в инициализаторе. Это решило аварию.источник
Мой AutoLayout работает очень хорошо:
источник
В большинстве случаев лучшим решением будет просто не бороться с фреймворком и использовать маски автоизменения размеров:
Используя маски с автоизменением размеров, вы сообщаете фреймворку, как ваше представление должно изменять свой размер, когда супервизор изменяет свой размер. Но это изменение основано на начальном кадре, который вы установили.
источник
Я знаю, что это старый пост, но после того, как я просмотрел все сообщения SO по этому поводу и провел целый день, играя с этим, я наконец придумал чистое и все же очень простое решение.
Во-первых, моя иерархия представлений выглядит так:
tableHeaderView
Теперь внутри представления (№ 3) я установил все ограничения, как обычно, включая нижнее пространство для контейнера. Это заставит контейнер (т.е. 3.View, то есть headerView) иметь размер в зависимости от его подпредставлений и их ограничений.
После этого я установил ограничения между ними
3. View
и2. View
:Обратите внимание, что я намеренно опускаю нижнее пространство.
Как только все это будет сделано в раскадровке, все, что осталось сделать, это вставить эти три строки кода:
источник
Подсказки: если вы используете метод setAndLayoutTableHeaderView, вы должны обновить фрейм подпредставлений, поэтому в этой ситуации предпочтительныйMaxLayoutWidth UILabel должен вызывать перед вызовом systemLayoutSizeFittingSize, не вызывайте в layoutSubview.
код шоу
источник
Поделитесь моим подходом.
UITableView+XXXAdditions.m
Использование.
источник
В моем случае метод с systemLayoutSizeFittingSize по какой-то причине не работал. У меня сработала модификация решения, опубликованного HotJard (его оригинальное решение также не сработало в моем случае на iOS 8). Что мне нужно было сделать, так это поместить в представление заголовка подпредставление и закрепить его слева, справа, сверху (не прикреплять к низу). Поместите все, используя autolayout в этом subview, и в коде сделайте следующее:
источник
Старый пост. Но хороший пост. Вот мои 2 цента.
Во-первых, убедитесь, что ваше представление заголовка имеет свои ограничения так, чтобы оно могло поддерживать собственный внутренний размер контента. Затем сделайте следующее.
источник
Мне удалось добиться этого с помощью следующего подхода (это работает и для нижнего колонтитула).
Для начала вам понадобится небольшое
UITableView
расширение:Swift 3
В вашей реализации класса контроллера представления:
Примечания о
UIView
реализации подпредставления заголовка :Вы должны быть на 100% уверены, что ваше представление заголовка имеет правильную настройку автоматического размещения. Я бы рекомендовал начать с простого представления заголовка с одним ограничением по высоте и опробовать описанную выше настройку.
Отменить
requiresConstraintBasedLayout
и вернутьtrue
:.
источник
Для пользователей Xamarin:
Предполагая, что вы назвали представление заголовка своего представления таблицы как TableviewHeader
источник
Вот как вы можете сделать в своем
UIViewController
источник
Любые ограничения
UIView
могут быть хорошимиtableHeaderView
.Необходимо установить
tableFooterView
до, а затем наложить дополнительное конечное ограничение наtableFooterView
иtableHeaderView
.}
Все подробности и фрагменты кода можно найти здесь
источник
Я нашел обходной путь. оберните представление заголовка xib, написанное автоматически, в пустую оболочку uiview и назначьте представление заголовка свойству tableViewHeader tableView.
источник
Вот что работает для UITableViewController в ios 12,
Перетащите UIView в TableView над всеми ячейками прототипа для заголовка и под всеми ячейками прототипа для нижнего колонтитула. При необходимости настройте верхний и нижний колонтитулы. Установите все необходимые ограничения.
Теперь используйте следующие методы расширения
и вызовите его в ViewDidLayoutSubviews подкласса UITableViewController
источник
Я столкнулся с проблемой получения ширины 375pt, единственный способ, который сработал для меня, - это ретранслировать tableView, чтобы получить правильную ширину. Я также предпочел AutoLayout настройке размера кадра.
Вот версия, которая мне подходит:
Xamarin.iOS
Swift Version (изменено из ответа @Ben Packard)
источник
Я создал подкласс
UITableView
и использовал егоUIStackView
как для верхнего, так и для нижнего колонтитула, он также позволяет настроить более одного представления.https://github.com/omaralbeik/StackableTableView
источник
Мое решение - создать такой новый класс.
Чтобы использовать его, просто добавьте все свои подпредставления в экземпляр
BaseTableHeaderView
и прикрепите его к представлению таблицы.Он автоматически изменит размер в зависимости от ограничений.
источник
Принятый ответ полезен только для таблиц с одним разделом. Если вы работаете с несколькими разделами,
UITableView
просто убедитесь, что ваш заголовок наследуется от,UITableViewHeaderFooterView
и все будет в порядке.В качестве альтернативы, просто вставить свой текущий заголовок в
contentView
оUITableViewHeaderFooterView
. Точно вродеUITableViewCell
работает.источник
tableHeaderView
не в шапке раздела.