mirror of
https://github.com/wahyd4/Yep.git
synced 2026-08-20 18:26:34 +10:00
Add second annoation and animation
This commit is contained in:
@@ -2,6 +2,7 @@ source 'https://github.com/CocoaPods/Specs.git'
|
||||
platform :ios, '8.0'
|
||||
use_frameworks!
|
||||
|
||||
pod 'pop'
|
||||
pod 'AFNetworking'
|
||||
pod 'MZFayeClient', :path => '../CatchLib-iOS/MZFayeClient/'
|
||||
pod 'JPushSDK'
|
||||
|
||||
@@ -25,6 +25,7 @@ PODS:
|
||||
- MZFayeClient (1.0.0):
|
||||
- Base64 (~> 1.0.1)
|
||||
- SocketRocket (~> 0.3.1-beta2)
|
||||
- pop (1.0.7)
|
||||
- Realm (0.91.3):
|
||||
- Realm/Headers (= 0.91.3)
|
||||
- Realm/Headers (0.91.3)
|
||||
@@ -34,6 +35,7 @@ DEPENDENCIES:
|
||||
- AFNetworking
|
||||
- JPushSDK
|
||||
- MZFayeClient (from `../CatchLib-iOS/MZFayeClient/`)
|
||||
- pop
|
||||
- Realm
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
@@ -45,6 +47,7 @@ SPEC CHECKSUMS:
|
||||
Base64: 4924bf3ca6fa559a5161ef717291bd450eb7bd1a
|
||||
JPushSDK: c68dd04c595a5c93aa003f212974010790410d8e
|
||||
MZFayeClient: 19df756a4c86c8f414668e6edc54fccfee54adbb
|
||||
pop: 628ffc631644601567ee8bfaaaea493ebd7d0923
|
||||
Realm: 4bfdac6f0f3170a3947c7196e2e9a2e49c943719
|
||||
SocketRocket: 7284ab9370a06c99aba92b2fe3a32aedd0f9a6fa
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
/* Begin PBXBuildFile section */
|
||||
0A02E46F1AC9208A00235DBF /* libxml2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 0A02E46E1AC9208A00235DBF /* libxml2.dylib */; };
|
||||
0A0A117F1AE382AC0008772C /* AnnoationCollectionReusableView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A0A117E1AE382AC0008772C /* AnnoationCollectionReusableView.swift */; };
|
||||
0A0A11821AE389380008772C /* RegisterSkillsLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A0A11811AE389380008772C /* RegisterSkillsLayout.swift */; };
|
||||
0A271FD71ACA055400822DFC /* YepAudioService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A271FD61ACA055400822DFC /* YepAudioService.swift */; };
|
||||
0A3E60601ACCA9C0003DC853 /* String+Yep.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A3E605F1ACCA9C0003DC853 /* String+Yep.swift */; };
|
||||
0A3E60671ACCAECE003DC853 /* YepLocationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A3E60661ACCAECE003DC853 /* YepLocationService.swift */; };
|
||||
@@ -21,6 +22,7 @@
|
||||
0A8F54C71AB67D11004AD60E /* YepTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A8F54C61AB67D11004AD60E /* YepTests.swift */; };
|
||||
0A944C251AC8BB2F00037A06 /* YepStorageService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A944C241AC8BB2F00037A06 /* YepStorageService.swift */; };
|
||||
0AAFCFF91AC8CA5B00EB0EF8 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0AAFCFF81AC8CA5B00EB0EF8 /* MobileCoreServices.framework */; };
|
||||
0AC725AE1AE3A94D005A3A98 /* SecondAnnoationLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AC725AD1AE3A94D005A3A98 /* SecondAnnoationLabelView.swift */; };
|
||||
0AD7EA5E1AC3ED1200617758 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0AD7EA5D1AC3ED1200617758 /* CFNetwork.framework */; };
|
||||
0AD7EA601AC3ED1900617758 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0AD7EA5F1AC3ED1900617758 /* CoreFoundation.framework */; };
|
||||
0AD7EA621AC3ED2100617758 /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0AD7EA611AC3ED2100617758 /* CoreTelephony.framework */; };
|
||||
@@ -136,6 +138,7 @@
|
||||
/* Begin PBXFileReference section */
|
||||
0A02E46E1AC9208A00235DBF /* libxml2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libxml2.dylib; path = usr/lib/libxml2.dylib; sourceTree = SDKROOT; };
|
||||
0A0A117E1AE382AC0008772C /* AnnoationCollectionReusableView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AnnoationCollectionReusableView.swift; path = Views/ReusableViews/AnnoationLabel/AnnoationCollectionReusableView.swift; sourceTree = "<group>"; };
|
||||
0A0A11811AE389380008772C /* RegisterSkillsLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RegisterSkillsLayout.swift; path = ViewControllers/Register/RegisterSkillsLayout.swift; sourceTree = "<group>"; };
|
||||
0A271FD61ACA055400822DFC /* YepAudioService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = YepAudioService.swift; path = Services/YepAudioService.swift; sourceTree = "<group>"; };
|
||||
0A3E605F1ACCA9C0003DC853 /* String+Yep.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "String+Yep.swift"; path = "Extensions/String+Yep.swift"; sourceTree = "<group>"; };
|
||||
0A3E60661ACCAECE003DC853 /* YepLocationService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = YepLocationService.swift; path = Services/YepLocationService.swift; sourceTree = "<group>"; };
|
||||
@@ -152,6 +155,7 @@
|
||||
0A8F54C61AB67D11004AD60E /* YepTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YepTests.swift; sourceTree = "<group>"; };
|
||||
0A944C241AC8BB2F00037A06 /* YepStorageService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = YepStorageService.swift; path = Services/YepStorageService.swift; sourceTree = "<group>"; };
|
||||
0AAFCFF81AC8CA5B00EB0EF8 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
|
||||
0AC725AD1AE3A94D005A3A98 /* SecondAnnoationLabelView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SecondAnnoationLabelView.swift; path = Views/ReusableViews/AnnoationLabel/SecondAnnoationLabelView.swift; sourceTree = "<group>"; };
|
||||
0AD7EA511AC3EA6F00617758 /* JPushSDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JPushSDK.framework; path = "Pods/../build/Debug-iphoneos/Pods/JPushSDK.framework"; sourceTree = "<group>"; };
|
||||
0AD7EA581AC3EAF300617758 /* Yep-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Yep-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
0AD7EA5B1AC3ECD700617758 /* libPushSDK-1.8.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = "libPushSDK-1.8.3.a"; path = "Yep/lib/libPushSDK-1.8.3.a"; sourceTree = "<group>"; };
|
||||
@@ -296,6 +300,7 @@
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0A0A117E1AE382AC0008772C /* AnnoationCollectionReusableView.swift */,
|
||||
0AC725AD1AE3A94D005A3A98 /* SecondAnnoationLabelView.swift */,
|
||||
);
|
||||
name = Annoation;
|
||||
sourceTree = "<group>";
|
||||
@@ -544,6 +549,7 @@
|
||||
50C0909A1ADE234F00CC6389 /* RegisterPickSkillsViewController.swift */,
|
||||
50C0909C1ADE294800CC6389 /* RegisterPickSkillsLayout.swift */,
|
||||
50C090A31ADE46D500CC6389 /* RegisterSelectSkillsViewController.swift */,
|
||||
0A0A11811AE389380008772C /* RegisterSkillsLayout.swift */,
|
||||
);
|
||||
name = Register;
|
||||
sourceTree = "<group>";
|
||||
@@ -1075,6 +1081,7 @@
|
||||
503CAB431AC00CB100DFE830 /* ConversationViewController.swift in Sources */,
|
||||
50553F931ADBA50600F80B59 /* NSDate+Yep.swift in Sources */,
|
||||
5023DE331AB688F600B3EE96 /* UIColor+Yep.swift in Sources */,
|
||||
0AC725AE1AE3A94D005A3A98 /* SecondAnnoationLabelView.swift in Sources */,
|
||||
503315971AC1017E0008A209 /* ChatLeftTextCell.swift in Sources */,
|
||||
0A8F54B11AB67D11004AD60E /* AppDelegate.swift in Sources */,
|
||||
508D174C1ACCF49B0092D666 /* ChatRightAudioCell.swift in Sources */,
|
||||
@@ -1104,6 +1111,7 @@
|
||||
0A0A117F1AE382AC0008772C /* AnnoationCollectionReusableView.swift in Sources */,
|
||||
50A9D4511ACD383E000B2599 /* NSDate+Extension.swift in Sources */,
|
||||
506EC20A1AC95BFC00CE42B3 /* UIFont+Yep.swift in Sources */,
|
||||
0A0A11821AE389380008772C /* RegisterSkillsLayout.swift in Sources */,
|
||||
50C0909B1ADE234F00CC6389 /* RegisterPickSkillsViewController.swift in Sources */,
|
||||
508D16BD1ADCAF0400270E3F /* PullToRefreshView.swift in Sources */,
|
||||
508D17441ACCDC9F0092D666 /* VoiceRecordButton.swift in Sources */,
|
||||
|
||||
@@ -557,11 +557,11 @@
|
||||
</collectionViewFlowLayout>
|
||||
<cells/>
|
||||
<collectionReusableView key="sectionHeaderView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="annoationLabelView" id="LgN-Ip-NL7" customClass="AnnoationCollectionReusableView" customModule="Yep" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="50"/>
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="150"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="What are you learning?" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="aSB-2s-v3n" userLabel="Annotation Label">
|
||||
<rect key="frame" x="152" y="7" width="296" height="36"/>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="What are you learning?" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="aSB-2s-v3n" userLabel="Annotation Label">
|
||||
<rect key="frame" x="152" y="57" width="296" height="36"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="200" id="bNN-vJ-go0"/>
|
||||
</constraints>
|
||||
@@ -591,8 +591,37 @@
|
||||
<collectionView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" translatesAutoresizingMaskIntoConstraints="NO" id="xur-C9-Tc1" userLabel="Skills Collection View">
|
||||
<rect key="frame" x="0.0" y="20" width="600" height="580"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<collectionViewLayout key="collectionViewLayout" id="C6X-CX-CTd" customClass="RegisterPickSkillsLayout" customModule="Yep" customModuleProvider="target"/>
|
||||
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="10" minimumInteritemSpacing="10" id="Q4i-Zz-uXN">
|
||||
<size key="itemSize" width="50" height="50"/>
|
||||
<size key="headerReferenceSize" width="50" height="100"/>
|
||||
<size key="footerReferenceSize" width="0.0" height="0.0"/>
|
||||
<inset key="sectionInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
|
||||
</collectionViewFlowLayout>
|
||||
<cells/>
|
||||
<collectionReusableView key="sectionHeaderView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="secondAnnoationLabelView" id="b3p-vo-BwH" customClass="SecondAnnoationLabelView" customModule="Yep" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="600" height="50"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Popular in Art" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Mr8-HT-R4V" userLabel="Annotation Label">
|
||||
<rect key="frame" x="213" y="32" width="175" height="36"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="width" constant="200" id="sAV-N9-QfM"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" weight="light" pointSize="30"/>
|
||||
<color key="textColor" cocoaTouchSystemColor="darkTextColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
<variation key="default">
|
||||
<mask key="constraints">
|
||||
<exclude reference="sAV-N9-QfM"/>
|
||||
</mask>
|
||||
</variation>
|
||||
</label>
|
||||
</subviews>
|
||||
<constraints>
|
||||
<constraint firstAttribute="centerX" secondItem="Mr8-HT-R4V" secondAttribute="centerX" id="BfU-jo-hRr"/>
|
||||
<constraint firstAttribute="centerY" secondItem="Mr8-HT-R4V" secondAttribute="centerY" id="pK4-zR-gnS"/>
|
||||
</constraints>
|
||||
</collectionReusableView>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="vEE-XY-eq4" id="sK5-GO-ZjU"/>
|
||||
<outlet property="delegate" destination="vEE-XY-eq4" id="3Vs-cc-fvq"/>
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import pop
|
||||
|
||||
class RegisterSelectSkillsViewController: UIViewController {
|
||||
|
||||
@@ -83,6 +84,30 @@ class RegisterSelectSkillsViewController: UIViewController {
|
||||
|
||||
skillsCollectionView.registerNib(UINib(nibName: skillSelectionCellIdentifier, bundle: nil), forCellWithReuseIdentifier: skillSelectionCellIdentifier)
|
||||
|
||||
|
||||
var layout = self.skillCategoriesCollectionView.collectionViewLayout as! UICollectionViewFlowLayout
|
||||
var originLineSpacing = layout.minimumLineSpacing
|
||||
var anim = POPBasicAnimation();
|
||||
anim.duration = 0.8
|
||||
anim.timingFunction = CAMediaTimingFunction(name: "easeInEaseOut")
|
||||
var prop = POPAnimatableProperty.propertyWithName("minimumLineSpacing", initializer: { props in
|
||||
|
||||
props.readBlock = { obj, values in
|
||||
values[0] = (obj as! UICollectionViewFlowLayout).minimumLineSpacing
|
||||
}
|
||||
props.writeBlock = { obj, values in
|
||||
(obj as! UICollectionViewFlowLayout).minimumLineSpacing = values[0]
|
||||
}
|
||||
|
||||
props.threshold = 0.01
|
||||
|
||||
}) as! POPAnimatableProperty
|
||||
|
||||
anim.property = prop
|
||||
anim.fromValue = 100.0
|
||||
anim.toValue = originLineSpacing
|
||||
|
||||
layout.pop_addAnimation(anim, forKey: "AnimateLine")
|
||||
|
||||
}
|
||||
|
||||
@@ -104,17 +129,24 @@ extension RegisterSelectSkillsViewController: UICollectionViewDataSource, UIColl
|
||||
func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
|
||||
var reusableview: UICollectionReusableView!
|
||||
|
||||
|
||||
if kind == UICollectionElementKindSectionHeader {
|
||||
var headerView: AnnoationCollectionReusableView = collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionHeader, withReuseIdentifier: "annoationLabelView", forIndexPath: indexPath) as! AnnoationCollectionReusableView
|
||||
|
||||
headerView.label.text = annotationText
|
||||
|
||||
let tap = UITapGestureRecognizer(target: self, action: "dismiss")
|
||||
headerView.label.userInteractionEnabled = true
|
||||
headerView.label.addGestureRecognizer(tap)
|
||||
self.annotationLabel = headerView.label
|
||||
|
||||
reusableview = headerView
|
||||
if collectionView == skillCategoriesCollectionView {
|
||||
var headerView: AnnoationCollectionReusableView = collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionHeader, withReuseIdentifier: "annoationLabelView", forIndexPath: indexPath) as! AnnoationCollectionReusableView
|
||||
|
||||
headerView.label.text = annotationText
|
||||
|
||||
let tap = UITapGestureRecognizer(target: self, action: "dismiss")
|
||||
headerView.label.userInteractionEnabled = true
|
||||
headerView.label.addGestureRecognizer(tap)
|
||||
self.annotationLabel = headerView.label
|
||||
|
||||
reusableview = headerView
|
||||
}else {
|
||||
var headerView: SecondAnnoationLabelView = collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionHeader, withReuseIdentifier: "secondAnnoationLabelView", forIndexPath: indexPath) as! SecondAnnoationLabelView
|
||||
|
||||
reusableview = headerView
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -182,7 +214,7 @@ extension RegisterSelectSkillsViewController: UICollectionViewDataSource, UIColl
|
||||
self.currentSkillCategoryButtonTopConstraint = topConstraint
|
||||
self.currentSkillCategoryButtonTopConstraintOriginalConstant = self.currentSkillCategoryButtonTopConstraint.constant
|
||||
|
||||
UIView.animateWithDuration(0.5, delay: 0.0, options: .CurveEaseInOut, animations: { () -> Void in
|
||||
UIView.animateWithDuration(0.8, delay: 0.0, options: .CurveEaseInOut, animations: { () -> Void in
|
||||
|
||||
topConstraint.constant = 60
|
||||
|
||||
@@ -193,20 +225,47 @@ extension RegisterSelectSkillsViewController: UICollectionViewDataSource, UIColl
|
||||
|
||||
}, completion: { (finished) -> Void in
|
||||
})
|
||||
|
||||
var layout = self.skillsCollectionView.collectionViewLayout as! UICollectionViewFlowLayout
|
||||
var originLineSpacing = layout.minimumLineSpacing
|
||||
var anim = POPBasicAnimation();
|
||||
anim.duration = 1.5
|
||||
anim.timingFunction = CAMediaTimingFunction(name: "easeOut")
|
||||
var prop = POPAnimatableProperty.propertyWithName("minimumLineSpacing", initializer: { props in
|
||||
|
||||
props.readBlock = { obj, values in
|
||||
values[0] = (obj as! UICollectionViewFlowLayout).minimumLineSpacing
|
||||
}
|
||||
props.writeBlock = { obj, values in
|
||||
(obj as! UICollectionViewFlowLayout).minimumLineSpacing = values[0]
|
||||
}
|
||||
|
||||
props.threshold = 0.01
|
||||
|
||||
}) as! POPAnimatableProperty
|
||||
|
||||
anim.property = prop
|
||||
anim.fromValue = 150.0
|
||||
anim.toValue = originLineSpacing
|
||||
|
||||
layout.pop_addAnimation(anim, forKey: "AnimateLine")
|
||||
|
||||
|
||||
UIView.animateWithDuration(0.5, delay: 0.2, options: .CurveEaseInOut, animations: { () -> Void in
|
||||
|
||||
UIView.animateWithDuration(0.8, delay: 0.2, options: .CurveEaseInOut, animations: { () -> Void in
|
||||
|
||||
|
||||
self.skillsCollectionViewBottomConstrain.constant = -150
|
||||
|
||||
self.view.layoutIfNeeded()
|
||||
|
||||
self.skillsCollectionView.alpha = 1
|
||||
|
||||
|
||||
|
||||
}, completion: { (finished) -> Void in
|
||||
})
|
||||
|
||||
} else {
|
||||
if let button = self.currentSkillCategoryButton {
|
||||
|
||||
|
||||
UIView.animateWithDuration(0.2, delay: 0.0, options: .CurveEaseInOut, animations: { () -> Void in
|
||||
|
||||
self.skillsCollectionView.alpha = 0
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
//
|
||||
// RegisterSkillsLayout.swift
|
||||
// Yep
|
||||
//
|
||||
// Created by kevinzhow on 15/4/19.
|
||||
// Copyright (c) 2015年 Catch Inc. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class RegisterSkillsLayout: UICollectionViewFlowLayout {
|
||||
|
||||
var animator: UIDynamicAnimator!
|
||||
|
||||
var visibleIndexPaths = NSMutableSet()
|
||||
|
||||
var lastContentOffset = CGPoint(x: 0, y: 0)
|
||||
var lastScrollDelta: CGFloat!
|
||||
var lastTouchLocation: CGPoint!
|
||||
|
||||
let kScrollPaddingRect:CGFloat = 100.0
|
||||
let kScrollRefreshThreshold:Float = 50.0
|
||||
let kScrollResistanceCoefficient:CGFloat = 1 / 600.0
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
setup()
|
||||
}
|
||||
|
||||
required init(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
setup()
|
||||
}
|
||||
|
||||
func setup() {
|
||||
animator = UIDynamicAnimator(collectionViewLayout: self)
|
||||
}
|
||||
|
||||
override func prepareLayout() {
|
||||
super.prepareLayout()
|
||||
var contentOffset = self.collectionView!.contentOffset
|
||||
|
||||
// only refresh the set of UIAttachmentBehaviours if we've moved more than the scroll threshold since last load
|
||||
if (fabsf(Float(contentOffset.y) - Float(lastContentOffset.y)) < Float(kScrollRefreshThreshold)) && visibleIndexPaths.count > 0{
|
||||
return
|
||||
}
|
||||
lastContentOffset = contentOffset
|
||||
|
||||
var padding = kScrollPaddingRect
|
||||
var currentRect = CGRectMake(0, contentOffset.y - padding, self.collectionView!.frame.size.width, self.collectionView!.frame.size.height + 3 * padding)
|
||||
|
||||
var itemsInCurrentRect = super.layoutAttributesForElementsInRect(currentRect)! as NSArray
|
||||
var indexPathsInVisibleRect = NSSet(array: itemsInCurrentRect.valueForKey("indexPath") as! [AnyObject])
|
||||
|
||||
// Remove behaviours that are no longer visible
|
||||
|
||||
for behaviour in animator!.behaviors as! [UIAttachmentBehavior] {
|
||||
var indexPath = behaviour.items.first?.indexPath
|
||||
|
||||
var isInVisibleIndexPaths = indexPathsInVisibleRect.member(indexPath!) != nil
|
||||
if (!isInVisibleIndexPaths){
|
||||
animator.removeBehavior(behaviour)
|
||||
visibleIndexPaths.removeObject(indexPath!)
|
||||
}
|
||||
}
|
||||
|
||||
// Find newly visible indexes
|
||||
var newVisibleItems = itemsInCurrentRect.filteredArrayUsingPredicate(NSPredicate(block: { (item, bindings) -> Bool in
|
||||
var isInVisibleIndexPaths = self.visibleIndexPaths.member(item.indexPath) != nil
|
||||
return !isInVisibleIndexPaths
|
||||
}));
|
||||
|
||||
for attribute in newVisibleItems as! [UICollectionViewLayoutAttributes] {
|
||||
var spring = UIAttachmentBehavior(item: attribute, attachedToAnchor: attribute.center)
|
||||
spring.length = 0
|
||||
spring.frequency = 1.5
|
||||
spring.damping = 0.8
|
||||
|
||||
// If our touchLocation is not (0,0), we need to adjust our item's center
|
||||
if (lastScrollDelta != nil) {
|
||||
self.adjustSpring(spring, touchLocation: lastTouchLocation, scrollDelta: lastScrollDelta)
|
||||
}
|
||||
animator.addBehavior(spring)
|
||||
visibleIndexPaths.addObject(attribute.indexPath)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func adjustSpring(spring: UIAttachmentBehavior, touchLocation: CGPoint, scrollDelta: CGFloat) {
|
||||
let anchorPoint = spring.anchorPoint
|
||||
let distanceFromTouch = fabs(touchLocation.y - anchorPoint.y)
|
||||
let scrollResistance = distanceFromTouch * kScrollResistanceCoefficient
|
||||
|
||||
let attributes = spring.items.first as! UICollectionViewLayoutAttributes
|
||||
|
||||
attributes.center.y += lastScrollDelta > 0 ? min(scrollDelta, scrollDelta * scrollResistance) : max(scrollDelta, scrollDelta * scrollResistance)
|
||||
}
|
||||
|
||||
override func layoutAttributesForItemAtIndexPath(indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes! {
|
||||
if let layoutAttributes = animator!.layoutAttributesForCellAtIndexPath(indexPath) {
|
||||
return layoutAttributes
|
||||
}else {
|
||||
var layoutAttributes = super.layoutAttributesForItemAtIndexPath(indexPath)
|
||||
return layoutAttributes
|
||||
}
|
||||
}
|
||||
|
||||
override func layoutAttributesForElementsInRect(rect: CGRect) -> [AnyObject]? {
|
||||
var newRect = rect
|
||||
var padding:CGFloat = kScrollPaddingRect
|
||||
newRect.size.height += 3.0*padding
|
||||
newRect.origin.y -= padding
|
||||
return animator!.itemsInRect(newRect)
|
||||
}
|
||||
|
||||
override func shouldInvalidateLayoutForBoundsChange(newBounds: CGRect) -> Bool {
|
||||
let scrollView = collectionView! as UIScrollView
|
||||
|
||||
lastScrollDelta = newBounds.origin.y - scrollView.bounds.origin.y
|
||||
|
||||
lastTouchLocation = scrollView.panGestureRecognizer.locationInView(scrollView)
|
||||
|
||||
for behaviour in animator!.behaviors as! [UIAttachmentBehavior] {
|
||||
self.adjustSpring(behaviour, touchLocation: lastTouchLocation, scrollDelta: lastScrollDelta)
|
||||
animator!.updateItemUsingCurrentState(behaviour.items.first as! UIDynamicItem)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func reset() {
|
||||
animator.removeAllBehaviors()
|
||||
visibleIndexPaths.removeAllObjects()
|
||||
}
|
||||
|
||||
override func layoutAttributesForSupplementaryViewOfKind(elementKind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionViewLayoutAttributes! {
|
||||
var attributes = UICollectionViewLayoutAttributes(forSupplementaryViewOfKind: elementKind, withIndexPath: indexPath)
|
||||
attributes.frame = CGRect(x: 0, y: 0, width: 320, height: 50)
|
||||
|
||||
return attributes
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
//
|
||||
// SecondAnnoationLabelView.swift
|
||||
// Yep
|
||||
//
|
||||
// Created by kevinzhow on 15/4/19.
|
||||
// Copyright (c) 2015年 Catch Inc. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
class SecondAnnoationLabelView: UICollectionReusableView {
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user