Добавление заголовка UIButton в UITableView
У меня есть UITableView
с 1 секцией и для заголовка раздела, я хотел бы сохранить все о заголовке так же, но просто добавить кнопку с правой стороны. Я не могу поместить кнопку в контроллер навигации, потому что два доступных пятна для такой кнопки уже заняты другими кнопками.
Здесь вы можете увидеть результат того, что я пытался сделать. Теперь все, что я хочу сделать, это добавить кнопку добавления в правой части заголовка, но то, что я пробовал, не работает. Я также пробовал некоторые другие решения на StackOverflow, но они не достигли того, что я хотел сделать. Кроме того, если есть лучший способ создать кнопку добавления, пожалуйста, дайте мне знать. Я попытался использовать UIBarButtonItem
, но я не мог понять, как добавить его представление в фактическое представление. Спасибо!
![enter image description here]()
Это то, что у меня есть до сих пор в моем делегате:
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIButton *addButton = [[UIButton alloc] init]; //I also tried setting a frame for the
button, but that did not seem to work, so I figured I would just leave it blank for posting
the question.
addButton.titleLabel.text = @"+";
addButton.backgroundColor = [UIColor redColor];
[self.tableView.tableHeaderView insertSubview:addButton atIndex:0];
//I feel like this is a bad idea
return self.tableView.tableHeaderView;
}
- (CGFloat) tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section
{
return 50;
}
Ответы
Ответ 1
Проблема в том, что ваш self.tableView.tableHeaderView
на данный момент nil
, поэтому вы не можете его использовать. Итак, что вам нужно сделать, создайте UIView, добавьте заголовок и кнопку в него, создайте их и верните.
Это должно добавить заголовок и кнопку в заголовок раздела, вам все же нужно будет стилизовать заголовок с правильным шрифтом и размером, но даст вам представление.
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
CGRect frame = tableView.frame;
UIButton *addButton = [[UIButton alloc] initWithFrame:CGRectMake(frame.size.width-60, 10, 50, 30)];
[addButton setTitle:@"+" forState:UIControlStateNormal];
addButton.backgroundColor = [UIColor redColor];
UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(10, 10, 100, 30)];
title.text = @"Reminders";
UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, frame.size.width, frame.size.height)];
[headerView addSubview:title];
[headerView addSubview:addButton];
return headerView;
}
Ответ 2
Из iOS 6 вы также можете реализовать
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
в UITableViewDelegate
. Например:
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section {
if (section == 0) {
if ([view.subviews.lastObject isKindOfClass:[UIButton class]]) {
return;
}
UIButton *button = [UIButtonbuttonWithType:UIButtonTypeSystem];
button.frame = CGRectMake(view.frame.size.width - 160.0, 0, 160.0, view.frame.size.height); // x,y,width,height
[button setTitle:@"My Button" forState:UIControlStateNormal];
[button addTarget:self action:@selector(sectionHeaderButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
[view addSubview:button];
}
}
Ответ 3
Если вы заинтересованы в решении Swift:
override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let frame = tableView.frame
let button = UIButton(frame: CGRectMake(5, 10, 15, 15)) // create button
button.tag = section
// the button is image - set image
button.setImage(UIImage(named: "remove_button"), forState: UIControlState.Normal) // assumes there is an image named "remove_button"
button.addTarget(self, action: #selector(TestController.remove(_:)), forControlEvents: .TouchUpInside) // add selector called by clicking on the button
let headerView = UIView(frame: CGRectMake(0, 0, frame.size.width, frame.size.height)) // create custom view
headerView.addSubview(button) // add the button to the view
return headerView
}
Возможно, вы захотите указать высоту заголовка в разделе. Это должно быть синхронизировано с высотой пользовательского представления:
override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return CGFloat(30)
}
Ответ 4
У вас есть 2 варианта, оба с помощью tableView.delegate
. Первый включает в себя реализацию метода делегата
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
который позволяет вам в принципе возвращать все, что угодно, в пользовательском представлении, которое будет использоваться в качестве заголовка для нужного раздела. Это может быть так же просто, как
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIButton *addButton = [UIButton buttonWithType:UIButtonTypeContactAdd];
[addButton addTarget:self action:@selector(SomeMethod:) forControlEvents:UIControlEventTouchUpInside];
return addButton;
}
который поместит в качестве заголовка круглую информационную кнопку (в центре). Но, скорее всего, вы захотите создать реальный объект UIView и заполнить его своей кнопкой (и ярлыком заголовка раздела?) И выложить все, как вам нравится [см. Ответы других, как это сделать].
Однако второй подход, вероятно, лучше для общего случая простого добавления кнопки в (один из) заголовков разделов [я знаю, что вы заявили 1 раздел, но многие люди, вероятно, приземляются на этот вопрос, желая сделать аналогичный в многосекционной таблице]. Это включает в себя реализацию метода делегата
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
и в основном добавление вашей кнопки в заголовок после факта; в частности,
- (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
{
// Remove old button from re-used header
if ([view.subviews.lastObject isKindOfClass:UIButton.class])
[view.subviews.lastObject removeFromSuperview];
if (section == MySectionNumberWithButton) {
UIButton *addButton = [UIButton buttonWithType:UIButtonTypeContactAdd];
[addButton addTarget:self action:@selector(SomeMethod:) forControlEvents:UIControlEventTouchUpInside];
[view addSubview:addButton];
// Place button on far right margin of header
addButton.translatesAutoresizingMaskIntoConstraints = NO; // use autolayout constraints instead
[addButton.trailingAnchor constraintEqualToAnchor:view.layoutMarginsGuide.trailingAnchor].active = YES;
[addButton.bottomAnchor constraintEqualToAnchor:view.layoutMarginsGuide.bottomAnchor].active = YES;
}
}
Обратите внимание: поскольку таблицаView повторно использует заголовки, в таблице с несколькими разделами вы должны обязательно удалить любую кнопку, которую вы могли бы добавить ранее, иначе вы в конечном итоге получите кнопки в нежелательных разделах. Затем, если это правильный раздел, добавьте кнопку в существующий заголовок. Заметьте, я использую NSLayoutAnchor
(iOS 9+) для макета кнопки для краткости; вы можете сделать то же самое с NSLayoutConstraint
(iOS 6 +)
Этот подход имеет явное преимущество - просто добавив кнопку - вам не нужно воссоздавать обычный макет, чтобы соответствовать всем другим (без кнопки) заголовкам, или беспокоиться о изменении полей при повороте устройства и т.д. В частности, заголовок заголовка не затронут и сохранит любые глобальные параметры внешнего вида, которые вы, возможно, определили для заголовков таблиц (например, шрифт, цвет и т.д.), Все из которых вы имели бы грязную работу по воссозданию, если бы вы взяли подход tableView:viewForHeaderInSection:
.
Ответ 5
Вы можете сделать это, используя приведенный ниже код, вы можете поместить любой тип представления в представление заголовка, но вы должны указать его для него.
- (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
{
UIView *view=[[UIView alloc]init];
UIButton *addButton=[UIButton buttonWithType:UIButtonTypeContactAdd];
addButton.frame=CGRectMake(250, 0, 100, 50);
[view addSubview:addButton];
[tblView.tableHeaderView insertSubview:view atIndex:0];
//I feel like this is a bad idea
return view;
}
Ответ 6
Если вы хотите использовать Interface Builder для создания заголовка раздела, вы можете использовать UITableViewCell
в качестве заголовка. Создайте ячейку-прототип для вашего заголовка в UITableView, настройте ее так же, как любую другую ячейку, включая добавление меток, кнопок и ограничений.
Вы можете создать экземпляр в вашем UITableViewController лениво:
lazy var headerCell: MyHeaderTableViewCell = {
let cell = tableView.dequeueReusableCell(withIdentifier: "Header") as! MyHeaderTableViewCell
return cell
}()
Чтобы сделать его заголовком:
override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
return headerCell
}
Ответ 7
Swift 4:
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let frame = tableView.frame
let button = UIButton(frame: CGRect(x: 5, y: 10, width: 15, height: 15))
button.tag = section
button.setImage(UIImage(named: "remove_button"), for: UIControl.State.normal)
button.addTarget(self,action:#selector(buttonClicked),for:.touchUpInside)
let headerView = UIView(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height))
headerView.addSubview(button)
return headerView
}
Эта функция обрабатывает нажатие кнопки:
@objc func buttonClicked(sender:UIButton)
{
if(sender.tag == 1){
//Do something for tag 1
}
print("buttonClicked")
}