将UIButton添加到UITableView节头

时间:2013-12-26 21:35:38

标签: ios objective-c uitableview uiview uibutton

我有一个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;
}

7 个答案:

答案 0 :(得分:24)

问题是此时您的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;
}

答案 1 :(得分:10)

从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];
    }
}

答案 2 :(得分:6)

如果您对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)
}

答案 3 :(得分:3)

您可以使用以下代码执行此操作,您可以在标题视图中放置任何类型的视图,但您必须为其指定框架。

- (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;
}

答案 4 :(得分:3)

您可以通过tableView.delegate进行2项选择。第一个涉及实现委托方法

- (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;
    }
}

注意,因为tableView重新使用标题,所以在多节表格中,您必须确保删除之前添加的任何按钮,否则您最终会在不需要的部分中使用按钮。然后,如果这是正确的部分,请将按钮添加到现有标题。请注意,我使用NSLayoutAnchor(iOS 9+)来布局按钮以简洁起见;您可以使用NSLayoutConstraint(iOS 6 +)

执行相同的操作

这种方法具有明显的优势 - 只需添加按钮 - 您无需重新创建常规布局以匹配所有其他(非按钮)标题,或者担心旋转设备时边距会发生变化等。特别是,标题标题不受影响,并将保留您可能为表格标题定义的任何全局外观设置(例如字体,颜色,......),所有这些设置都会让您重新创建,你采用了tableView:viewForHeaderInSection:方法。

答案 5 :(得分:0)

如果要使用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
}

答案 6 :(得分:0)

斯威夫特4:

let frame = tableView.frame
let button = UIButton(frame: CGRectMake(5, 10, 15, 15))
button.tag = section
button.setImage(UIImage(named: "remove_button"), for: UIControlState.normal)
button.addTarget(self,action:#selector(buttonClicked),for:.touchUpInside) 

let headerView = UIView(frame: CGRectMake(0, 0, frame.size.width, frame.size.height)) 
headerView.addSubview(button)

return headerView

重新定义Apple的功能

   func CGRectMake(_ x: CGFloat, _ y: CGFloat, _ width: CGFloat, _ height: CGFloat) -> CGRect {
        return CGRect(x: x, y: y, width: width, height: height)
    }

这是功能:

@objc func buttonClicked(sender:UIButton)
{
    if(sender.tag == 1){

       //Do something for tag 1
    }
    print("buttonClicked")
}