web-dev-qa-db-fra.com

UITableView horizontal

Je veux implémenter une disposition dans mon application ipad qui a une vue modifiable qui défile de gauche à droite plutôt que de haut en bas:

Donc plutôt que

ligne 1 ligne 2 ligne 3 (défilement vertical) Ce serait: ligne 1, ligne 2, ligne 3 (défilement horizontal)

J'ai vu que UItableView est conçu pour ne faire que le défilement vertical, donc faire une transformation ne donne pas l'effet souhaité. Existe-t-il un moyen standard de le faire en profitant d'un fournisseur de source de données comme uitableview fournit?
Je veux essentiellement faire quelque chose de similaire à ce que fait le BBC News reader app sur l'Ipad avec la liste des histoires à sélectionner.

Merci

39
imran

J'ai publié un exemple de code qui illustre une approche pour implémenter des vues de table à défilement horizontal à l'aide de transformations. Il s'appelle EasyTableView et fournit la même interface pour les vues de table à défilement vertical et horizontal.

29
aleksey

Voici la méthode que j'utilise:

1) Implémentez votre propre sous-classe de UITableView et remplacez son initWithCoder: méthode comme indiqué ci-dessous:

- (id)initWithCoder:(NSCoder *)aDecoder
{
    assert([aDecoder isKindOfClass:[NSCoder class]]);

    self = [super initWithCoder:aDecoder];

    if (self) {

        const CGFloat k90DegreesCounterClockwiseAngle = (CGFloat) -(90 * M_PI / 180.0);

        CGRect frame = self.frame;
        self.transform = CGAffineTransformRotate(CGAffineTransformIdentity, k90DegreesCounterClockwiseAngle);
        self.frame = frame;    

    }

    assert(self);
    return self;
}

2) Créez votre propre classe UITableViewCell et remplacez initWithCoder: encore:

- (id)initWithCoder:(NSCoder *)aDecoder
{
    assert([aDecoder isKindOfClass:[NSCoder class]]);

    self = [super initWithCoder:aDecoder];

    if (self) {

        const CGFloat k90DegreesClockwiseAngle = (CGFloat) (90 * M_PI / 180.0);

        self.transform = CGAffineTransformRotate(CGAffineTransformIdentity, k90DegreesClockwiseAngle);
    }

    assert(self);
    return self;
}

3) Vous pouvez maintenant créer un élément UITableView dans IB et définir sa classe sur "MyHorizontalTableView" dans l'inspecteur d'identité.

4) Créez votre élément UITableViewCell dans IB et définissez sa classe sur "MyHorizontalTableViewCell" dans l'inspecteur d'identité.

Et c'est tout.

Cela fonctionnerait en remplaçant également les autres initialiseurs au cas où vous préféreriez ne pas utiliser IB pour instancier votre vue de tableau ou votre cellule.

Un exemple de projet que j'ai construit autour de ce concept se trouve dans GitHub.

25
diegoreymendez

Si vous pouvez restreindre votre application à seulement iOS 6 et versions ultérieures, la meilleure façon de le faire est avec ICollectionView .

Si vous devez prendre en charge iOS 4/5, essayez l'une des réimplémentations open source d'UICollectionView, par exemple. PSTCollectionView

7
JosephH

Cette question a été réponse d'Apple . Exemple de défilement par Apple

Montre comment implémenter deux styles UIScrollViews différents. Le premier scroller contient plusieurs images, montrant comment mettre en page un contenu volumineux avec plusieurs blocs de données (dans notre cas, 5 UIImageViews distincts).

cela fonctionne aussi pour iPad.

5
Saqib Saud

Pour l'instant, vous devez utiliser UIScrollView et définir le défilement sur horizontal uniquement. En ce qui concerne les données, vous devez gérer vous-même le retrait et les optimisations. Si vous ne vous attendez pas à plus d'une douzaine d'objets, vous pouvez probablement les ignorer, mais s'ils sont gourmands en données, essayez d'implémenter un approvisionnement et un chargement de données similaires à ceux utilisés par UITableView. Notez que l'application BBC News Reader utilise également la pagination activée pour faire défiler chaque "page (environ 4 icônes d'actualités)".

3
hardway

Il existe une astuce simple et brillante pour obtenir une vue UITableView permettant de faire un défilement vertical et horizontal parfaitement.

Vous pouvez le faire avec et sans mise en page automatique - je vais l'expliquer avec la mise en page automatique.

Sur UITableView, vous avez une contrainte de largeur et aucune contrainte d'alignement de queue. Le lier cette contrainte de largeur avec un IBOutlet et dans votre contrôleur définissez les propriétés suivantes sur la vue de table.

let contentWidth = 1000 // you calculate that
tableViewWidthConstraint.constant = contentWidth
tableView.contentSize.width = (contentWidth * 2) - UIScreen.main.bounds.size.width

La vue de table doit être pleine largeur pour rendre tout le contenu dans le sens horizontal, et nous jouons avec la taille du contenu par rapport à la taille de l'écran qui fait l'affaire.

Les emplacements ci-dessous fonctionnent, mais vous pouvez essayer les dans différentes étapes du cycle de vie:

override func viewWillAppear(_ animated: Bool) {
    super.viewWillAppear(animated)

    tableViewWidthConstraint.constant = contentWidth
}

override func viewDidAppear(_ animated: Bool) {
    super.viewDidAppear(animated)

    tableView.contentSize.width = (contentWidth * 2) - UIScreen.main.bounds.size.width
}

// and this is needed to support rotation:
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
        coordinator.animate(alongsideTransition: { (UIViewControllerTransitionCoordinatorContext) -> Void in
            self.tableView.contentSize.width = (contentWidth * 2) - UIScreen.main.bounds.size.width
        }, completion: nil)
    }
    super.viewWillTransition(to: size, with: coordinator)
}
1
Morten Holmgaard

J'ai écrit une simple sous-classe UIScrollView qui, comme UITableView, implémente la réutilisation des cellules, le projet MMHorizontalListView est sur gitHub, il y a aussi un projet de test, vous pouvez donc voir comment l'utiliser avec un exemple, cela fonctionne aussi avec anciennes versions iOS comme 4.x (probablement encore plus anciennes ...)

1
Manu