Aligning right to left on UICollectionView
You can get similar result by performing a transform on the collection view and reverse the flip on its content:
First when creating the UICollectionView I performed a horizontal flip on it:
[collectionView_ setTransform:CGAffineTransformMakeScale(-1, 1)];
Then subclass UICollectionViewCell
and in here do the same horizontal flip on its contentView:
[self.contentView setTransform:CGAffineTransformMakeScale(-1, 1)];
Aligning right to left on UICollectionView with contents
In viewDidLoad():
let alignedFlowLayout = collectionView.collectionViewLayout as? AlignedCollectionViewFlowLayout
collectionView.transform = CGAffineTransform(scaleX: -1, y: 1)
[enter link description here][1]alignedFlowLayout?.horizontalAlignment = .left
@Hemang comment worked for me.
If you have any subviews in your cell, then you have transform it as well. For e.g.
self.titleLabel.transform = CGAffineTransform(scaleX: -1, y: 1)
AlignedCollectionViewFlowLayout
Left Align Cells in UICollectionView
The other solutions in this thread do not work properly, when the line is composed by only 1 item or are over complicated.
Based on the example given by Ryan, I changed the code to detect a new line by inspecting the Y position of the new element. Very simple and quick in performance.
Swift:
class LeftAlignedCollectionViewFlowLayout: UICollectionViewFlowLayout {
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
let attributes = super.layoutAttributesForElements(in: rect)
var leftMargin = sectionInset.left
var maxY: CGFloat = -1.0
attributes?.forEach { layoutAttribute in
if layoutAttribute.frame.origin.y >= maxY {
leftMargin = sectionInset.left
}
layoutAttribute.frame.origin.x = leftMargin
leftMargin += layoutAttribute.frame.width + minimumInteritemSpacing
maxY = max(layoutAttribute.frame.maxY , maxY)
}
return attributes
}
}
If you want to have supplementary views keep their size, add the following at the top of the closure in the forEach
call:
guard layoutAttribute.representedElementCategory == .cell else {
return
}
Objective-C:
- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect {
NSArray *attributes = [super layoutAttributesForElementsInRect:rect];
CGFloat leftMargin = self.sectionInset.left; //initalized to silence compiler, and actaully safer, but not planning to use.
CGFloat maxY = -1.0f;
//this loop assumes attributes are in IndexPath order
for (UICollectionViewLayoutAttributes *attribute in attributes) {
if (attribute.frame.origin.y >= maxY) {
leftMargin = self.sectionInset.left;
}
attribute.frame = CGRectMake(leftMargin, attribute.frame.origin.y, attribute.frame.size.width, attribute.frame.size.height);
leftMargin += attribute.frame.size.width + self.minimumInteritemSpacing;
maxY = MAX(CGRectGetMaxY(attribute.frame), maxY);
}
return attributes;
}
align single UICollectionViewCell to the left of the collectionView
Since sectionInset
is the same as func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets { }
protocol, one could call this protocol to know which section has only one cell left.
You can replace :
flowLayout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
With:
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {
if collectionView.numberOfItems(inSection: section) == 1 {
let flowLayout = collectionViewLayout as! UICollectionViewFlowLayout
return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: collectionView.frame.width - flowLayout.itemSize.width)
}
return UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
}
This red cell is the only one left in the second section , and it is left aligned:
How to fill data right to left in UICollectionView
Creation of a custom UICollectionViewFlowLayout
maybe is the most straight answer, but it's too expensive.
I always rather use this way (Flip the collectionView
and it's subviews).
Inside init
or viewDidLoad()
put this:
self.collectionView.transform = CGAffineTransformMakeScale(-1, 1)
Inside collectionView:cellForItemAtIndexPath:
or cell class put this:
cell.transform = CGAffineTransformMakeScale(-1, 1)
EDIT:
You can make your app completely RTL by doing the following:
- Set the minimum deployment target version to iOS
9.0
- In your
Info.plist
, setLocalization native development region
to your RTL localization. (Likear_AE
for Arabic orfa_IR
for Persian-Iran)
How Can I align the colectionViewCells to the left?
You can manage your cell with below code. Do not forget to add UICollectionViewDelegateFlowLayout
func collectionView(_ collectionView: UICollectionView,
layout collectionViewLayout: UICollectionViewLayout,
sizeForItemAt indexPath: IndexPath) -> CGSize {
// your code here
}
Left align a UICollectionView
It seems the question should read, left align a UICollectionView.
The simplest solution is to go to:
https://github.com/mokagio/UICollectionViewLeftAlignedLayout
And subclass your layout to this, this will ensure your UICollectionView left aligns, you should set all your insets to 0 first then begin changing them according to your design.
Related Topics
Firebase Chat Push Notifications
How to Calculate the Uilabel Height Dynamically
Where Do I Find iOS Obj-C Code to Scan and Connect to Wifi (Private API)
Apple MACh-O Linker Warning "Directory Not Found for Option..."
Uiprogressview Custom Track and Progress Images in iOS 7.1
Uitableview Reloaddata Automatically Calls Resignfirstresponder
When Exactly Do Implicit Animations Take Place in iOS
Change Uiimageview Size to Match Image with Autolayout
How to Play Video Stream with Mpmovieplayercontroller in iOS
Why Can't I Call the Default Super.Init() on Uiviewcontroller in Swift
Mfmailcomposeviewcontroller in iOS 7 Statusbar Are Black
Xcode Cannot Run on the Selected Destination
@Property/@Synthesize Equivalent in Swift