c'est une question assez simple, mais je n'ai pas pu trouver de réponse définitive à cette question le SO (si je l'ai manquée, corrigez-moi, s'il vous plaît).
En gros, ma question est la suivante:Est-il possible d’aligner le contenu de la rangée UICollectionView
de droite à gauche au lieu de gauche à droite?
Dans mes recherches, j'ai vu des réponses suggérant un sous-groupe UICollectionViewFlowLayout
, mais je n'ai pas été en mesure de trouver un exemple où il en a été créé un pour l'alignement à droite.
Mon objectif est d’avoir 2 vues de collection configurées comme ceci:
Toute aide est grandement appréciée!
Vous pouvez obtenir un résultat similaire en effectuant une transformation sur la vue de la collection et en inversant le retournement de son contenu:
Tout d'abord, lors de la création de UICollectionView, j'ai effectué un retournement horizontal:
[collectionView_ setTransform:CGAffineTransformMakeScale(-1, 1)];
Puis la sous-classe UICollectionViewCell
et ici font le même retournement horizontal sur son contenuView:
[self.contentView setTransform:CGAffineTransformMakeScale(-1, 1)];
Sans faire aucun Xtransform à la vue de la collection, simplement forcé RTL
YourCollectionView.semanticContentAttribute = UISemanticContentAttribute.forceRightToLeft
En plus de la réponse de Tawfik:
Vous pouvez également définir la propriété Semantic
de UICollectionView via Interface Builder:
En savoir plus sur cette propriété: dans cette question
À partir de iOS 9, Collection Views prend en charge RTL selon cette vidéo WWDC . Il n'est donc plus nécessaire de créer une mise en page de flux RTL (sauf si vous utilisez déjà une mise en page personnalisée).
Sélectionnez: Edit Scheme ...> Options> Run> Langage d'application> Pseudolangue de droite à gauche
Lorsque vous construirez dans Simulator, le texte sera aligné à droite et votre vue Collection sera ordonnée de droite à gauche.
Il y a un problème cependant. Lorsque contentOffset.x == 0
, la position de défilement de la vue Collection est sur le bord Left
(faux) au lieu du bord Right
(correct). Voir cet article de la pile } pour plus de détails.
Une solution de contournement consiste simplement à faire défiler l'élément First
au .Left
(il y a un gotcha - .Left
est en fait sur le bord Right ou Leading):
override func viewDidAppear(animated: Bool) {
if collectionView?.numberOfItemsInSection(0) > 0 {
let indexPath = NSIndexPath(forItem: 0, inSection: 0)
collectionView?.scrollToItemAtIndexPath(indexPath, atScrollPosition: .Left, animated: false)
}
}
Dans mon projet de test, ma vue Collection était imbriquée dans une cellule de vue Table, je n'avais donc pas accès à viewDidAppear()
. Alors au lieu de cela, j'ai fini par accrocher à drawRect()
:
class CategoryRow : UITableViewCell {
@IBOutlet weak var collectionView: UICollectionView!
override func drawRect(rect: CGRect) {
super.drawRect(rect)
scrollToBeginning()
}
override func prepareForReuse() {
scrollToBeginning()
}
func scrollToBeginning() {
guard collectionView.numberOfItems(inSection: 0) > 0 else { return }
let indexPath = IndexPath(item: 0, section: 0)
collectionView.scrollToItem(at: indexPath, at: .left, animated: false)
}
}
Pour voir cela en action, consultez le branche RTL sur ce dépôt Git . Et pour le contexte, voir ceci article de blog et ses commentaires .
Pour tous ceux qui essaient d’obtenir la disposition UICollectionView
de droite à gauche dans Swift
//in viewDidLoad
YourCollectionView.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
//in cellForItemAtIndexPath
cell.transform = CGAffineTransform(scaleX: -1.0, y: 1.0)
Pour ceux qui ont la même question:
J'ai fini par utiliser la bibliothèque UICollectionViewRightAlignedLayout that @ chinttu-roxen-ramani recommandée. Vous pouvez soit le définir avec le code:
self.collectionView.collectionViewLayout = [[UICollectionViewRightAlignedLayout alloc] init];
ou via le constructeur d'interface:
J'ai fini par apporter quelques modifications à la bibliothèque, mais dans l'ensemble, cela fonctionne très bien.
vous pouvez l'utiliser depuis iOS 11
extension UICollectionViewFlowLayout {
open override var flipsHorizontallyInOppositeLayoutDirection: Bool {
return true
}
}
Solution pour Swift 4.2 et iOS 9+ en 2 étapes simples
inversez votre collectionView dans viewDidLoad () comme ceci:
myCollectionView.transform = CGAffineTransform (scaleX: -1, y: 1)
inverser votre cellule (car tout est inversé) dans cellForItemAt comme ceci:
cell.transform = CGAffineTransform (scaleX: -1, y: 1)
maintenant le contenu est à droite et le défilement commence à droite.
En modifiant les deux flipsHorizontallyInOppositeLayoutDirection
et developmentLayoutDirection
, j'ai pu réaliser un défilement RTL en plein écran où le premier élément se trouvait complètement à droite et pour atteindre la dernière cellule, l'utilisateur devra faire défiler vers la gauche.
Ainsi:
class RTLCollectionViewFlowLayout: UICollectionViewFlowLayout {
override var flipsHorizontallyInOppositeLayoutDirection: Bool {
return true
}
override var developmentLayoutDirection: UIUserInterfaceLayoutDirection {
return UIUserInterfaceLayoutDirection.rightToLeft
}
}