forked from truongminhthang/CodeSnippets
-
Notifications
You must be signed in to change notification settings - Fork 0
/
D9A059A2-C33B-4148-880C-6254A0D38D1B.codesnippet
122 lines (110 loc) · 5.51 KB
/
D9A059A2-C33B-4148-880C-6254A0D38D1B.codesnippet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDECodeSnippetCompletionScopes</key>
<array>
<string>TopLevel</string>
</array>
<key>IDECodeSnippetContents</key>
<string>import UIKit
class CollectionViewFlowLayout: UICollectionViewFlowLayout {
var scalingOffset: CGFloat = 200 // for offsets >= scalingOffset scale Factor is minimumScaleFactor
var minimumScaleFactor: CGFloat = 0.8
var isScaleItems = true
var lastCollectionViewSize: CGSize?
var pageWidth : CGFloat = 0
static func layoutConfigured(with collectionView: UICollectionView, itemSize: CGSize, minimumLineSpacing: CGFloat) -> CollectionViewFlowLayout {
let layout = CollectionViewFlowLayout()
collectionView.collectionViewLayout = layout
layout.scrollDirection = .horizontal
layout.minimumLineSpacing = minimumLineSpacing
layout.itemSize = itemSize
layout.collectionView?.decelerationRate = UIScrollViewDecelerationRateFast
layout.pageWidth = itemSize.width + minimumLineSpacing;
return layout
}
override func invalidateLayout(with context: UICollectionViewLayoutInvalidationContext) {
super.invalidateLayout(with: context)
let currentCollectionViewSize = collectionView?.bounds.size;
if currentCollectionViewSize != lastCollectionViewSize {
configureInset()
lastCollectionViewSize = currentCollectionViewSize
}
}
func configureInset() {
guard collectionView != nil else {return}
let inset = (collectionView!.bounds.width - self.itemSize.width) / 2
collectionView?.contentInset = UIEdgeInsets(top: 0, left: inset, bottom: 0, right: inset)
collectionView?.contentOffset = CGPoint(x: -inset, y: 0)
}
override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
guard let collectionViewSize = collectionView?.bounds.size else {
assert(false , "Error: There are no CollectionView in CollectionViewFlowLayout")
}
var inoutproposedContentOffset = proposedContentOffset
let proposedContentOffsetCenterX = inoutproposedContentOffset.x + collectionViewSize.width / 2
let proposedRect = CGRect(origin: CGPoint(x: inoutproposedContentOffset.x, y: 0), size: collectionViewSize)
var candidateAttributes : UICollectionViewLayoutAttributes?
if let layoutAttributes = layoutAttributesForElements(in: proposedRect) {
for layoutAttribute in layoutAttributes {
if !(layoutAttribute.representedElementCategory == UICollectionElementCategory.cell) { continue }
if candidateAttributes == nil {
candidateAttributes = layoutAttribute
continue
}
if (fabs(layoutAttribute.center.x - proposedContentOffsetCenterX) < fabs(candidateAttributes!.center.x - proposedContentOffsetCenterX)) {
candidateAttributes = layoutAttribute
}
}
}
inoutproposedContentOffset.x = candidateAttributes!.center.x - collectionViewSize.width / 2
let offset = inoutproposedContentOffset.x - collectionView!.contentOffset.x
if (velocity.x < 0 && offset > 0) || (velocity.x > 0 && offset < 0) {
inoutproposedContentOffset.x += velocity.x > 0 ? pageWidth : -pageWidth
}
return inoutproposedContentOffset
}
override func shouldInvalidateLayout(forBoundsChange newBounds: CGRect) -> Bool {
return true
}
override func layoutAttributesForElements(in rect: CGRect) -> [UICollectionViewLayoutAttributes]? {
guard let attributes = super.layoutAttributesForElements(in: rect) else {
assert(false , "Error: There are no return from layoutAttributesForElements(in: rect)")
return nil
}
var attributesCopy = [UICollectionViewLayoutAttributes]()
for attribute in attributes {
attributesCopy.append(attribute.copy() as! UICollectionViewLayoutAttributes)
}
guard let collectionView = collectionView else {
assert(false , "Error: There are no CollectionView in CollectionViewFlowLayout")
return nil
}
if isScaleItems == false {
return attributesCopy
}
let visibleRect = CGRect(origin: collectionView.contentOffset, size: collectionView.bounds.size)
let visibleRectCenterX = visibleRect.midX
for attribute in attributesCopy{
let distanceFromCenter = visibleRectCenterX - attribute.center.x
let absolutedDistanceFromCenter = [abs(distanceFromCenter),scalingOffset].min()
let scale = absolutedDistanceFromCenter! * (minimumScaleFactor - 1) / scalingOffset + 1
attribute.transform3D = CATransform3DScale(CATransform3DIdentity, scale, scale, 1)
}
return attributesCopy
}
}
</string>
<key>IDECodeSnippetIdentifier</key>
<string>D9A059A2-C33B-4148-880C-6254A0D38D1B</string>
<key>IDECodeSnippetLanguage</key>
<string>Xcode.SourceCodeLanguage.Swift</string>
<key>IDECodeSnippetTitle</key>
<string>Swift 3: transition3D collectionView</string>
<key>IDECodeSnippetUserSnippet</key>
<true/>
<key>IDECodeSnippetVersion</key>
<integer>2</integer>
</dict>
</plist>