web-dev-qa-db-fra.com

Ajouter UIButton à l’en-tête de la section UITableView

J'ai une UITableView avec 1 section et pour l'en-tête de section, j'aimerais que tout ce qui concerne l'en-tête reste identique, mais ajoute simplement un bouton sur le côté droit. Je ne peux pas placer le bouton dans le contrôleur de navigation car les deux emplacements disponibles pour placer un tel bouton sont déjà occupés par d'autres boutons. 

Ici, vous pouvez voir le résultat de ce que j'ai essayé de faire. Maintenant, tout ce que je veux faire est de mettre un bouton Ajouter à droite de l'en-tête, mais ce que j'ai essayé n'a pas fonctionné. J'ai également essayé d'autres solutions sur StackOverflow, mais elles n'ont pas vraiment abouti à ce que je voulais faire. En outre, s'il existe un meilleur moyen de créer un bouton d'ajout, veuillez me le faire savoir. J'ai essayé d'utiliser une variable UIBarButtonItem, mais je ne savais pas comment ajouter sa vue à une vue réelle. Merci!

enter image description here

Voici ce que j'ai jusqu'à présent chez mon délégué:

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

Le problème est que votre self.tableView.tableHeaderView estnilpour le moment, vous ne pouvez donc pas l'utiliser. Vous devez donc créer un UIView, lui ajouter un titre et un bouton, lui donner un style et le renvoyer.

Cela devrait ajouter un titre et un bouton à l'en-tête de votre section. Vous devez néanmoins attribuer un titre au titre avec la police et la taille correctes, mais cela vous donnera une idée.

- (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.

Depuis iOS 6, vous pouvez également implémenter 

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

dans votre UITableViewDelegate. Par exemple:

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

Si vous êtes intéressé par la solution 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   
}

Vous voudrez peut-être spécifier la hauteur de l'en-tête dans la section. Cela doit être synchronisé avec la hauteur de la vue personnalisée:

override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
    return CGFloat(30)
}
6
Lubos

Vous pouvez le faire en utilisant le code ci-dessous, vous pouvez mettre n'importe quel type de vue en vue d'en-tête, mais vous devez spécifier le cadre correspondant.

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

Vous avez 2 choix, tous deux via votre tableView.delegate. La première consiste à implémenter la méthode déléguée

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

ce qui vous permet essentiellement de renvoyer tout ce que vous voulez dans une vue personnalisée, qui sera utilisée comme en-tête de la section souhaitée. Cela pourrait être aussi simple que

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

qui mettra un bouton rond d'information (centré) comme en-tête. Mais il est plus probable que vous souhaitiez créer un objet UIView réel et le renseigner avec votre bouton (et une étiquette de titre de section?) Et disposez-le à votre guise [voir les réponses des autres pour savoir comment faire].

Cependant, la deuxième approche est probablement meilleure dans le cas général de simplement ajouter un bouton à (un des) en-têtes de section [je sais que vous avez indiqué une section, mais beaucoup de gens vont probablement atterrir sur cette question en voulant faire la même chose de manière similaire. table multi-sections]. Cela implique l'implémentation de la méthode delegate

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

et en gros, ajouter votre bouton à l'en-tête après coup; Plus précisément

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

Notez que, comme tableView réutilise les en-têtes, vous devez vous assurer que tous les boutons que vous avez ajoutés précédemment sont supprimés, sinon vous finirez par avoir des boutons dans des sections non désirées. Ensuite, s'il s'agit de la bonne section, ajoutez le bouton à l'en-tête existant. Notez que j'utilise NSLayoutAnchor (iOS 9+) pour organiser le bouton par souci de concision; vous pouvez faire la même chose avec NSLayoutConstraint (iOS 6+)

Cette approche a le net avantage - pour l’ajout d’un bouton - de ne pas devoir recréer la disposition habituelle pour correspondre à tous vos autres en-têtes (sans bouton), ni vous inquiéter des marges qui changent lorsque vous faites pivoter votre appareil, etc. le titre de l'en-tête n'est pas touché et conservera tous les paramètres d'apparence globale que vous avez définis pour les en-têtes de tableau (par exemple, police, couleur, ...), que vous auriez le travail fastidieux de recréer si vous adoptiez l'approche tableView:viewForHeaderInSection: .

3
tiritea

Si vous souhaitez utiliser Interface Builder pour créer votre en-tête de section, vous pouvez utiliser UITableViewCell comme en-tête. Créez une cellule prototype pour votre en-tête dans votre UITableView, personnalisez-la comme vous le feriez avec toute autre cellule, en ajoutant notamment des étiquettes, des boutons et des contraintes. 

Vous pouvez instancier dans votre UITableViewController paresseusement:

lazy var headerCell: MyHeaderTableViewCell = {
    let cell = tableView.dequeueReusableCell(withIdentifier: "Header") as! MyHeaderTableViewCell
    return cell
}()

Pour en faire l'en-tête:

override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
    return headerCell
}
0
jbaraga

Swift 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

redéfinir les fonctions Apple

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

et c'est la fonction: 

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

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