114 votes

Est-il possible d'utiliser AutoLayout avec le tableHeaderView de UITableView ?

Depuis que j'ai découvert AutoLayout Je l'utilise partout, maintenant j'essaie de l'utiliser avec un tableHeaderView .

J'ai fait un subclass de UIView J'ai ajouté tout ce que je voulais (étiquettes etc...) avec leurs contraintes, puis j'ai ajouté ceci CustomView à la UITableView ' tableHeaderView .

Tout fonctionne bien, sauf le UITableView affiche toujours au-dessus de el CustomView par au-dessus de Je veux dire le CustomView es sous el UITableView pour qu'on ne puisse pas le voir !

Il semble que peu importe ce que je fais, les height de la UITableView ' tableHeaderView es toujours 0 (ainsi que la largeur, x et y).

Ma question : est-il possible d'accomplir cette tâche ? sans régler le cadre manuellement ?

EDIT : Le site CustomView ' subview que j'utilise a ces contraintes :

_title = [[UILabel alloc]init];
_title.text = @"Title";
[self addSubview:_title];
[_title keep:[KeepTopInset rules:@[[KeepEqual must:5]]]]; // title has to stay at least 5 away from the supperview Top
[_title keep:[KeepRightInset rules:@[[KeepMin must:5]]]];
[_title keep:[KeepLeftInset rules:@[[KeepMin must:5]]]];
[_title keep:[KeepBottomInset rules:@[[KeepMin must:5]]]];

J'utilise une bibliothèque pratique, 'KeepLayout', car écrire des contraintes manuellement prend une éternité et nécessite beaucoup trop de lignes pour une seule contrainte, mais les méthodes s'expliquent d'elles-mêmes.

Et le UITableView a ces contraintes :

_tableView = [[UITableView alloc]init];
_tableView.translatesAutoresizingMaskIntoConstraints = NO;
_tableView.delegate = self;
_tableView.dataSource = self;
_tableView.backgroundColor = [UIColor clearColor];
[self.view addSubview:_tableView];
[_tableView keep:[KeepTopInset rules:@[[KeepEqual must:0]]]];// These 4 constraints make the UITableView stays 0 away from the superview top left right and bottom.
[_tableView keep:[KeepLeftInset rules:@[[KeepEqual must:0]]]];
[_tableView keep:[KeepRightInset rules:@[[KeepEqual must:0]]]];
[_tableView keep:[KeepBottomInset rules:@[[KeepEqual must:0]]]];

_detailsView = [[CustomView alloc]init];
_tableView.tableHeaderView = _detailsView;

Je ne sais pas si je dois définir des contraintes directement sur l'interface de l'utilisateur. CustomView Je pense que la hauteur de la CustomView est déterminée par les contraintes sur l'interface de l'utilisateur. UILabel "titre" dans celui-ci.

EDIT 2 : Après une autre enquête, il semble que la hauteur et la largeur du CustomView soient correctement calculées, mais le haut du CustomView est toujours au même niveau que le haut du UITableView et ils se déplacent ensemble lorsque je fais défiler.

0voto

Pour les utilisateurs de Xamarin :

public override void ViewDidLayoutSubviews()
{
    base.ViewDidLayoutSubviews();

    TableviewHeader.SetNeedsLayout();
    TableviewHeader.LayoutIfNeeded();

    var height = TableviewHeader.SystemLayoutSizeFittingSize(UIView.UILayoutFittingCompressedSize).Height;
    var frame = TableviewHeader.Frame;
    frame.Height = height;
    TableviewHeader.Frame = frame;
}

En supposant que vous avez nommé la vue d'en-tête de votre tableview comme TableviewHeader

0voto

onmyway133 Points 2196

Voici comment vous pouvez faire dans votre UIViewController

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()

    if headerView.frame.size.height == 0 {
      headerView.label.preferredMaxLayoutWidth = view.bounds.size.width - 20
      let height = headerView.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height

      headerView.frame.size = CGSize(width: tableView.bounds.size.width, height: height)
    }
  }

0voto

malex Points 2992

Tout système basé sur des contraintes UIView peut être une bonne tableHeaderView .

Il faut définir un tableFooterView avant d'imposer une contrainte supplémentaire à l'arrière de l'appareil. tableFooterView y tableHeaderView .

- (void)viewDidLoad {

    ........................
    // let self.headerView is some constraint-based UIView
    self.tableView.tableFooterView = [UIView new];
    [self.headerView layoutIfNeeded];
    self.tableView.tableHeaderView = self.headerView;

    [self.tableView.leadingAnchor constraintEqualToAnchor:self.headerView.leadingAnchor].active = YES;
    [self.tableView.trailingAnchor constraintEqualToAnchor:self.headerView.trailingAnchor].active = YES;
    [self.tableView.topAnchor constraintEqualToAnchor:self.headerView.topAnchor].active = YES;
    [self.tableFooterView.trailingAnchor constraintEqualToAnchor:self.headerView.trailingAnchor].active = YES;

}

On peut trouver tous les détails et les extraits de code aquí

0voto

tounaobun Points 38

J'ai trouvé une solution de contournement. Enveloppez votre vue d'en-tête autolayout wrriten xib dans un wrapper uiview vide, et assignez la vue d'en-tête à la propriété tableViewHeader de tableView.

    UIView *headerWrapper = [[UIView alloc] init];
    AXLHomeDriverHeaderView *headerView = [AXLHomeDriverHeaderView loadViewFromNib];
    [headerWrapper addSubview:headerView];
    [headerView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(headerWrapper);
    }];
    self.tableView.tableHeaderView = headerView;

0voto

HeisenBerg Points 2230

Voici ce qui fonctionne pour UITableViewController dans ios 12,

Déplacer un UIView dans le TableView au-dessus de toutes les cellules prototypes de l'en-tête et au-dessous de toutes les cellules prototypes du pied de page. Configurez votre en-tête et votre pied de page selon vos besoins. Définissez toutes les contraintes requises.

Utilisez maintenant les méthodes d'extension suivantes

public static class UITableVIewExtensions
{

    public static void MakeHeaderAutoDimension(this UITableView tableView)
    {
        if (tableView.TableHeaderView is UIView headerView) {
            var size = headerView.SystemLayoutSizeFittingSize(UIView.UILayoutFittingCompressedSize);
            if (headerView.Frame.Size.Height != size.Height) {
                var frame = headerView.Frame;
                frame.Height = size.Height;
                headerView.Frame = frame;
                tableView.TableHeaderView = headerView;
                tableView.LayoutIfNeeded();
            }
        }
    }

    public static void MakeFooterAutoDimension(this UITableView tableView)
    {
        if (tableView.TableFooterView is UIView footerView) {
            var size = footerView.SystemLayoutSizeFittingSize(UIView.UILayoutFittingCompressedSize);
            if (footerView.Frame.Size.Height != size.Height) {
                var frame = footerView.Frame;
                frame.Height = size.Height;
                footerView.Frame = frame;
                tableView.TableFooterView = footerView;
                tableView.LayoutIfNeeded();
            }
        }
    }
}

et l'appeler dans ViewDidLayoutSubviews de la sous-classe de UITableViewController

public override void ViewDidLayoutSubviews()
{
    base.ViewDidLayoutSubviews();

    TableView.MakeHeaderAutoDimension();
    TableView.MakeFooterAutoDimension();
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X