Adding UIButton to UITableView section header

前端 未结 7 1149
一个人的身影
一个人的身影 2021-02-01 20:20

I have a UITableView with 1 section and for the section header, I would like to keep everything about the header the same but simply add a button on the right side.

7条回答
  •  灰色年华
    2021-02-01 21:03

    You have 2 choices, both via your tableView.delegate. The first involves implementing the delegate method

    - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
    

    which enables you to basically return anything you want in a custom view, which will be used as the header for your desired section. This could be as simple as

    - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
    {
        UIButton *addButton = [UIButton buttonWithType:UIButtonTypeContactAdd];
        [addButton addTarget:self action:@selector(SomeMethod:) forControlEvents:UIControlEventTouchUpInside];
        return addButton;
    }
    

    which will put a round info button (centered) as your header. But more likely you'll want to create an actual UIView object and populate it with your button (and a section title label?) and lay everything out as you like [see others' answers for how to do this].

    However, the second approach is probably better for the general case of simply adding a button to (one of) your section headers [I know you stated 1 section, but a lot of folks will probably land on this question wanting to do similar in a multi-section table]. This involves implementing the delegate method

    - (void)tableView:(UITableView *)tableView willDisplayHeaderView:(UIView *)view forSection:(NSInteger)section
    

    and basically adding your button to the header after-the-fact; specifically

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

    Note, because the tableView re-uses headers, in a multi-section table you must make sure to remove any button you might have previously added, otherwise you'll eventually end up with buttons in unwanted sections. Then, if this is the right section, add the button to the existing header. Note, I'm using NSLayoutAnchor (iOS 9+) to layout the button for brevity; you can do the same with NSLayoutConstraint (iOS 6+)

    This approach has the distinct advantage that - for just adding a button - you dont have to recreate the regular layout to match all your other (non-button) headers, or worry about margins changing when you rotate your device, etc. In particular, the header title is untouched and will retain any global appearance settings you may have defined for table headers (eg font, color, ...), all of which you'd have the messy job of re-creating if you took the tableView:viewForHeaderInSection: approach.

提交回复
热议问题