Skip to content

Commit f589bb9

Browse files
Mischa Hildebrande-sung
authored andcommitted
Refactor code to use a second horizontal alignment type for internal use.
1 parent 37d7f7e commit f589bb9

File tree

1 file changed

+60
-29
lines changed

1 file changed

+60
-29
lines changed

AlignedCollectionViewFlowLayout/Classes/AlignedCollectionViewFlowLayout.swift

Lines changed: 60 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -27,38 +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-
/**
36-
Defines an alignment for UI elements.
37-
38-
- Note:
39-
To support semantics for Right-to-Left language Users, use `leading` or `trailing`
40-
just like you do with Autolayout.
41-
42-
If you want to force frame based `left` or `right` alighment, use `left` or `right`
43-
*/
36+
/// Defines a horizontal alignment for UI elements.
4437
public enum HorizontalAlignment: Alignment {
4538
case left
46-
case justified
4739
case right
4840
case leading
4941
case trailing
50-
51-
/// trailing becomes right, and leading becomes left for RTL languages
52-
var swapForRTL: HorizontalAlignment {
53-
switch self {
54-
case .leading:
55-
return isRTL ?.right : .left
56-
case .trailing:
57-
return isRTL ? .left : .right
58-
default:
59-
return self
60-
}
61-
}
42+
case justified
6243
}
6344

6445
/// Defines a vertical alignment for UI elements.
@@ -68,6 +49,14 @@ public enum VerticalAlignment: Alignment {
6849
case bottom
6950
}
7051

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+
7160
/// Describes an axis with respect to which items can be aligned.
7261
private struct AlignmentAxis<A: Alignment> {
7362

@@ -81,6 +70,9 @@ private struct AlignmentAxis<A: Alignment> {
8170
}
8271

8372

73+
74+
// MARK: - Flow Layout
75+
8476
/// A `UICollectionViewFlowLayout` subclass that gives you control
8577
/// over the horizontal and vertical alignment of the cells.
8678
/// You can use it to align the cells like words in a left- or right-aligned text
@@ -92,15 +84,57 @@ open class AlignedCollectionViewFlowLayout: UICollectionViewFlowLayout {
9284
/// Determines how the cells are horizontally aligned in a row.
9385
/// - Note: The default is `.justified`.
9486
public var horizontalAlignment: HorizontalAlignment = .justified
95-
87+
9688
/// Determines how the cells are vertically aligned in a row.
9789
/// - Note: The default is `.center`.
9890
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+
}
99133

100134
/// The vertical axis with respect to which the cells are horizontally aligned.
101135
/// For a `justified` alignment the alignment axis is not defined and this value is `nil`.
102136
fileprivate var alignmentAxis: AlignmentAxis<HorizontalAlignment>? {
103-
switch horizontalAlignment.swapForRTL {
137+
switch effectiveHorizontalAlignment {
104138
case .left:
105139
return AlignmentAxis(alignment: HorizontalAlignment.left, position: sectionInset.left)
106140
case .right:
@@ -302,6 +336,7 @@ open class AlignedCollectionViewFlowLayout: UICollectionViewFlowLayout {
302336
}
303337

304338

339+
305340
// MARK: - 👷 Layout attributes helpers
306341

307342
fileprivate extension UICollectionViewLayoutAttributes {
@@ -422,7 +457,7 @@ fileprivate extension UICollectionViewLayoutAttributes {
422457
return
423458
}
424459

425-
switch collectionViewLayout.horizontalAlignment.swapForRTL {
460+
switch collectionViewLayout.effectiveHorizontalAlignment {
426461

427462
case .left:
428463
if isRepresentingFirstItemInLine(collectionViewLayout: collectionViewLayout) {
@@ -452,7 +487,3 @@ fileprivate extension UICollectionViewLayoutAttributes {
452487
}
453488

454489
}
455-
456-
fileprivate var isRTL: Bool {
457-
return UIApplication.shared.userInterfaceLayoutDirection == .rightToLeft
458-
}

0 commit comments

Comments
 (0)