diff --git a/Podfile b/Podfile index e79dd2ba..adeb4fd6 100644 --- a/Podfile +++ b/Podfile @@ -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' diff --git a/Podfile.lock b/Podfile.lock index b06c19c3..4b36481a 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -25,15 +25,17 @@ PODS: - MZFayeClient (1.0.0): - Base64 (~> 1.0.1) - SocketRocket (~> 0.3.1-beta2) - - Realm (0.91.1): - - Realm/Headers (= 0.91.1) - - Realm/Headers (0.91.1) + - pop (1.0.7) + - Realm (0.91.3): + - Realm/Headers (= 0.91.3) + - Realm/Headers (0.91.3) - SocketRocket (0.3.1-beta2) DEPENDENCIES: - AFNetworking - JPushSDK - MZFayeClient (from `../CatchLib-iOS/MZFayeClient/`) + - pop - Realm EXTERNAL SOURCES: @@ -45,7 +47,8 @@ SPEC CHECKSUMS: Base64: 4924bf3ca6fa559a5161ef717291bd450eb7bd1a JPushSDK: c68dd04c595a5c93aa003f212974010790410d8e MZFayeClient: 19df756a4c86c8f414668e6edc54fccfee54adbb - Realm: b9c1fd9defa26aa7276ce938a8df52ec81f24528 + pop: 628ffc631644601567ee8bfaaaea493ebd7d0923 + Realm: 4bfdac6f0f3170a3947c7196e2e9a2e49c943719 SocketRocket: 7284ab9370a06c99aba92b2fe3a32aedd0f9a6fa COCOAPODS: 0.36.3 diff --git a/Yep.xcodeproj/project.pbxproj b/Yep.xcodeproj/project.pbxproj index afff29f1..0e1bafb8 100644 --- a/Yep.xcodeproj/project.pbxproj +++ b/Yep.xcodeproj/project.pbxproj @@ -8,6 +8,8 @@ /* 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 */; }; @@ -20,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 */; }; @@ -134,6 +137,8 @@ /* 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 = ""; }; + 0A0A11811AE389380008772C /* RegisterSkillsLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = RegisterSkillsLayout.swift; path = ViewControllers/Register/RegisterSkillsLayout.swift; sourceTree = ""; }; 0A271FD61ACA055400822DFC /* YepAudioService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = YepAudioService.swift; path = Services/YepAudioService.swift; sourceTree = ""; }; 0A3E605F1ACCA9C0003DC853 /* String+Yep.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "String+Yep.swift"; path = "Extensions/String+Yep.swift"; sourceTree = ""; }; 0A3E60661ACCAECE003DC853 /* YepLocationService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = YepLocationService.swift; path = Services/YepLocationService.swift; sourceTree = ""; }; @@ -150,6 +155,7 @@ 0A8F54C61AB67D11004AD60E /* YepTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = YepTests.swift; sourceTree = ""; }; 0A944C241AC8BB2F00037A06 /* YepStorageService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = YepStorageService.swift; path = Services/YepStorageService.swift; sourceTree = ""; }; 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 = ""; }; 0AD7EA511AC3EA6F00617758 /* JPushSDK.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JPushSDK.framework; path = "Pods/../build/Debug-iphoneos/Pods/JPushSDK.framework"; sourceTree = ""; }; 0AD7EA581AC3EAF300617758 /* Yep-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Yep-Bridging-Header.h"; sourceTree = ""; }; 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 = ""; }; @@ -290,6 +296,15 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 0A0A11801AE382AF0008772C /* Annoation */ = { + isa = PBXGroup; + children = ( + 0A0A117E1AE382AC0008772C /* AnnoationCollectionReusableView.swift */, + 0AC725AD1AE3A94D005A3A98 /* SecondAnnoationLabelView.swift */, + ); + name = Annoation; + sourceTree = ""; + }; 0A3E60631ACCAC02003DC853 /* NSDate+TimeAgo */ = { isa = PBXGroup; children = ( @@ -534,6 +549,7 @@ 50C0909A1ADE234F00CC6389 /* RegisterPickSkillsViewController.swift */, 50C0909C1ADE294800CC6389 /* RegisterPickSkillsLayout.swift */, 50C090A31ADE46D500CC6389 /* RegisterSelectSkillsViewController.swift */, + 0A0A11811AE389380008772C /* RegisterSkillsLayout.swift */, ); name = Register; sourceTree = ""; @@ -610,6 +626,7 @@ children = ( 502AE55A1AB932D9005BD199 /* ProfileSectionHeader */, 50C090A21ADE391900CC6389 /* AddSkills */, + 0A0A11801AE382AF0008772C /* Annoation */, ); name = ReusableViews; sourceTree = ""; @@ -1064,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 */, @@ -1090,8 +1108,10 @@ 5023DE301AB6861500B3EE96 /* ProfileViewController.swift in Sources */, 50E114F71ABBFA7000F13000 /* RLMSupport.swift in Sources */, 5023DE261AB6856300B3EE96 /* ConversationsViewController.swift in Sources */, + 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 */, diff --git a/Yep/Base.lproj/Intro.storyboard b/Yep/Base.lproj/Intro.storyboard index ed151d28..89f0db7a 100644 --- a/Yep/Base.lproj/Intro.storyboard +++ b/Yep/Base.lproj/Intro.storyboard @@ -558,35 +558,82 @@ - - + - + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + @@ -601,14 +648,11 @@ - + - - - diff --git a/Yep/Base.lproj/Main.storyboard b/Yep/Base.lproj/Main.storyboard index 0b22106c..917fc243 100644 --- a/Yep/Base.lproj/Main.storyboard +++ b/Yep/Base.lproj/Main.storyboard @@ -1,7 +1,7 @@ - + - + @@ -70,7 +70,7 @@ - + diff --git a/Yep/ViewControllers/Register/RegisterSelectSkillsViewController.swift b/Yep/ViewControllers/Register/RegisterSelectSkillsViewController.swift index 403bc40c..b5060d83 100644 --- a/Yep/ViewControllers/Register/RegisterSelectSkillsViewController.swift +++ b/Yep/ViewControllers/Register/RegisterSelectSkillsViewController.swift @@ -7,6 +7,7 @@ // import UIKit +import pop class RegisterSelectSkillsViewController: UIViewController { @@ -49,7 +50,30 @@ class RegisterSelectSkillsViewController: UIViewController { skillsCollectionView.registerNib(UINib(nibName: skillSelectionCellIdentifier, bundle: nil), forCellWithReuseIdentifier: skillSelectionCellIdentifier) - annotationLabel.text = annotationText + + 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.1 + + }) as! POPAnimatableProperty + + anim.property = prop + anim.fromValue = 100.0 + anim.toValue = originLineSpacing + + layout.pop_addAnimation(anim, forKey: "AnimateLine") let tap = UITapGestureRecognizer(target: self, action: "dismiss") annotationLabel.userInteractionEnabled = true @@ -85,6 +109,33 @@ class RegisterSelectSkillsViewController: UIViewController { extension RegisterSelectSkillsViewController: UICollectionViewDataSource, UICollectionViewDelegate { + func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView { + var reusableview: UICollectionReusableView! + + + if kind == UICollectionElementKindSectionHeader { + 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 + } + } + + + return reusableview + } + func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int { return 1 } @@ -149,7 +200,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 @@ -160,20 +211,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.1 + + }) 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 - - self.skillsCollectionViewBottomConstrain.constant = 0 - + 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 diff --git a/Yep/ViewControllers/Register/RegisterSkillsLayout.swift b/Yep/ViewControllers/Register/RegisterSkillsLayout.swift new file mode 100644 index 00000000..685bc425 --- /dev/null +++ b/Yep/ViewControllers/Register/RegisterSkillsLayout.swift @@ -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 + } +} diff --git a/Yep/Views/ReusableViews/AnnoationLabel/AnnoationCollectionReusableView.swift b/Yep/Views/ReusableViews/AnnoationLabel/AnnoationCollectionReusableView.swift new file mode 100644 index 00000000..dac5129f --- /dev/null +++ b/Yep/Views/ReusableViews/AnnoationLabel/AnnoationCollectionReusableView.swift @@ -0,0 +1,14 @@ +// +// AnnoationCollectionReusableView.swift +// Yep +// +// Created by kevinzhow on 15/4/19. +// Copyright (c) 2015年 Catch Inc. All rights reserved. +// + +import UIKit + +class AnnoationCollectionReusableView: UICollectionReusableView { + @IBOutlet weak var label: UILabel! + +} diff --git a/Yep/Views/ReusableViews/AnnoationLabel/SecondAnnoationLabelView.swift b/Yep/Views/ReusableViews/AnnoationLabel/SecondAnnoationLabelView.swift new file mode 100644 index 00000000..41d43e76 --- /dev/null +++ b/Yep/Views/ReusableViews/AnnoationLabel/SecondAnnoationLabelView.swift @@ -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 { + +}