web-dev-qa-db-ja.com

UITableViewセクションヘッダーへのUIButtonの追加

セクションが1つのUITableViewがあり、セクションヘッダーについては、ヘッダーのすべてを同じに保ち、右側にボタンを追加するだけです。ナビゲーションコントローラーにボタンを配置することができません。そのようなボタンを配置するために使用できる2つの場所は、既に他のボタンで占められています。

ここで私がやろうとした結果を見ることができます。ヘッダーの右側に追加ボタンを配置するだけですが、試してもうまくいきませんでした。 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;
}
15
Iowa15

問題は、あなたのself.tableView.tableHeaderView is 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;
}
24
Yas T.

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];
    }
}
11
mwl

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)
}
6
Lubos

_tableView.delegate_による2つの選択肢があります。 1つ目は、デリゲートメソッドの実装です。

_- (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つ)にボタンを追加するだけの一般的なケースでは、2番目のアプローチの方がおそらく適切です[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:_アプローチ。

4
tiritea

これを行うには、以下のコードを使用します。ヘッダービューに任意のタイプのビューを配置できますが、そのためのフレームを指定する必要があります。

- (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;
}
3
Jiten Parmar

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
}
0
jbaraga

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")
}
0
Osman