Skip to content

Commit 03024fd

Browse files
Merge pull request mischa-hildebrand#20 from e-sung/master
Add support for `trailing` and `leading` horizontal alignment.
2 parents 613b58c + f589bb9 commit 03024fd

File tree

2 files changed

+63
-6
lines changed

2 files changed

+63
-6
lines changed

AlignedCollectionViewFlowLayout/Classes/AlignedCollectionViewFlowLayout.swift

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,16 +27,19 @@
2727

2828
import UIKit
2929

30+
3031
// MARK: - 🦆 Type definitions
3132

3233
/// An abstract protocol that defines an alignment.
3334
protocol Alignment {}
3435

35-
/// Defines an alignment for UI elements.
36+
/// Defines a horizontal alignment for UI elements.
3637
public enum HorizontalAlignment: Alignment {
3738
case left
38-
case justified
3939
case right
40+
case leading
41+
case trailing
42+
case justified
4043
}
4144

4245
/// Defines a vertical alignment for UI elements.
@@ -46,6 +49,14 @@ public enum VerticalAlignment: Alignment {
4649
case bottom
4750
}
4851

52+
/// A horizontal alignment used internally by `AlignedCollectionViewFlowLayout`
53+
/// to layout the items, after resolving layout direction specifics.
54+
private enum EffectiveHorizontalAlignment: Alignment {
55+
case left
56+
case right
57+
case justified
58+
}
59+
4960
/// Describes an axis with respect to which items can be aligned.
5061
private struct AlignmentAxis<A: Alignment> {
5162

@@ -59,6 +70,9 @@ private struct AlignmentAxis<A: Alignment> {
5970
}
6071

6172

73+
74+
// MARK: - Flow Layout
75+
6276
/// A `UICollectionViewFlowLayout` subclass that gives you control
6377
/// over the horizontal and vertical alignment of the cells.
6478
/// You can use it to align the cells like words in a left- or right-aligned text
@@ -70,15 +84,57 @@ open class AlignedCollectionViewFlowLayout: UICollectionViewFlowLayout {
7084
/// Determines how the cells are horizontally aligned in a row.
7185
/// - Note: The default is `.justified`.
7286
public var horizontalAlignment: HorizontalAlignment = .justified
73-
87+
7488
/// Determines how the cells are vertically aligned in a row.
7589
/// - Note: The default is `.center`.
7690
public var verticalAlignment: VerticalAlignment = .center
91+
92+
/// The `horizontalAlignment` with its layout direction specifics resolved,
93+
/// i.e. `.leading` and `.trailing` alignments are mapped to `.left` or `right`,
94+
/// depending on the current layout direction.
95+
fileprivate var effectiveHorizontalAlignment: EffectiveHorizontalAlignment {
96+
97+
var trivialMapping: [HorizontalAlignment: EffectiveHorizontalAlignment] {
98+
return [
99+
.left: .left,
100+
.right: .right,
101+
.justified: .justified
102+
]
103+
}
104+
105+
let layoutDirection = UIApplication.shared.userInterfaceLayoutDirection
106+
107+
switch layoutDirection {
108+
case .leftToRight:
109+
switch horizontalAlignment {
110+
case .leading:
111+
return .left
112+
case .trailing:
113+
return .right
114+
default:
115+
break
116+
}
117+
118+
case .rightToLeft:
119+
switch horizontalAlignment {
120+
case .leading:
121+
return .right
122+
case .trailing:
123+
return .left
124+
default:
125+
break
126+
}
127+
}
128+
129+
// It's safe to force-unwrap as `.leading` and `.trailing` are covered
130+
// above and the `trivialMapping` dictionary contains all other keys.
131+
return trivialMapping[horizontalAlignment]!
132+
}
77133

78134
/// The vertical axis with respect to which the cells are horizontally aligned.
79135
/// For a `justified` alignment the alignment axis is not defined and this value is `nil`.
80136
fileprivate var alignmentAxis: AlignmentAxis<HorizontalAlignment>? {
81-
switch horizontalAlignment {
137+
switch effectiveHorizontalAlignment {
82138
case .left:
83139
return AlignmentAxis(alignment: HorizontalAlignment.left, position: sectionInset.left)
84140
case .right:
@@ -280,6 +336,7 @@ open class AlignedCollectionViewFlowLayout: UICollectionViewFlowLayout {
280336
}
281337

282338

339+
283340
// MARK: - 👷 Layout attributes helpers
284341

285342
fileprivate extension UICollectionViewLayoutAttributes {
@@ -400,7 +457,7 @@ fileprivate extension UICollectionViewLayoutAttributes {
400457
return
401458
}
402459

403-
switch collectionViewLayout.horizontalAlignment {
460+
switch collectionViewLayout.effectiveHorizontalAlignment {
404461

405462
case .left:
406463
if isRepresentingFirstItemInLine(collectionViewLayout: collectionViewLayout) {

Example/AlignedCollectionViewFlowLayout/CollectionViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class CollectionViewController: UICollectionViewController {
2626

2727
// Set up the flow layout's cell alignment:
2828
let flowLayout = collectionView?.collectionViewLayout as? AlignedCollectionViewFlowLayout
29-
flowLayout?.horizontalAlignment = .right
29+
flowLayout?.horizontalAlignment = .trailing
3030

3131
// Enable automatic cell-sizing with Auto Layout:
3232
flowLayout?.estimatedItemSize = .init(width: 100, height: 40)

0 commit comments

Comments
 (0)