├── .gitignore ├── HeaderRefreshView.h ├── HeaderRefreshView.m ├── HeaderRefreshView.podspec ├── HeaderRefreshViewDemo ├── HeaderRefreshViewDemo.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ └── HeaderRefreshViewDemo.xccheckout │ │ └── xcuserdata │ │ │ └── nijino_saki.xcuserdatad │ │ │ ├── UserInterfaceState.xcuserstate │ │ │ └── WorkspaceSettings.xcsettings │ └── xcuserdata │ │ └── nijino_saki.xcuserdatad │ │ └── xcschemes │ │ ├── HeaderRefreshViewDemo.xcscheme │ │ └── xcschememanagement.plist ├── HeaderRefreshViewDemo │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Base.lproj │ │ └── Main.storyboard │ ├── DetailViewController.h │ ├── DetailViewController.m │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── Info.plist │ ├── MasterViewController.h │ ├── MasterViewController.m │ ├── main.m │ └── zh-Hans.lproj │ │ ├── Localizable.strings │ │ └── Main.storyboard └── HeaderRefreshViewDemoTests │ ├── HeaderRefreshViewDemoTests.m │ └── Info.plist ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # CocoaPods 2 | # 3 | # We recommend against adding the Pods directory to your .gitignore. However 4 | # you should judge for yourself, the pros and cons are mentioned at: 5 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control? 6 | # 7 | # Pods/ 8 | 9 | -------------------------------------------------------------------------------- /HeaderRefreshView.h: -------------------------------------------------------------------------------- 1 | // 2 | // HeaderRefreshView.h 3 | // 一个模仿系统下拉刷新的控件 4 | // 5 | // Created by nijino on 14-8-21. 6 | // Copyright (c) 2014年 http://www.nijino.cn. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface HeaderRefreshView : UIControl 12 | 13 | @property (nonatomic, copy) NSString * normalString;//正常状态显示的字符串 14 | @property (nonatomic, copy) NSString * releaseToRefreshString;//松手即可刷新显示的字符串 15 | @property (nonatomic, copy) NSString * loadingString;//读取中显示的字符串 16 | @property (nonatomic) UIColor *textColor;//提示语文字颜色 17 | 18 | - (void)beginRefreshing;//开始刷新 19 | - (void)endRefreshing;//结束刷新 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /HeaderRefreshView.m: -------------------------------------------------------------------------------- 1 | // 2 | // HeaderRefreshView.m 3 | // 一个模仿系统下拉刷新的控件 4 | // 5 | // Created by nijino on 14-8-21. 6 | // Copyright (c) 2014年 http://www.nijino.cn. All rights reserved. 7 | // 8 | 9 | #import "HeaderRefreshView.h" 10 | @import QuartzCore; 11 | 12 | static const int distanceForTriggerRefresh = 75;//触发刷新下拉距离 13 | static const int offsetInRefreshing = 40;//刷新中偏移量 14 | 15 | typedef NS_ENUM(NSUInteger, RefreshState) { 16 | RefreshStateNormal,//一般状态 17 | RefreshStatePulling,//松手可刷新 18 | RefreshStateLoading,//刷新中 19 | }; 20 | 21 | @interface HeaderRefreshView () 22 | 23 | @property (nonatomic) UILabel *statusLabel;//状态Label 24 | @property (nonatomic) CAShapeLayer *pullProgressLayer;//下拉进度随动层 25 | @property (nonatomic) CAShapeLayer *loadingLayer;//读取中转圈层 26 | @property (nonatomic) RefreshState refreshState;//状态枚举值 27 | @property (nonatomic) BOOL isLoading;//是否在读取中 28 | 29 | @end 30 | 31 | @implementation HeaderRefreshView 32 | 33 | - (void)setup{ 34 | _normalString = NSLocalizedString(@"Pull down to refresh...", @"Pull down to refresh status"); 35 | _releaseToRefreshString = NSLocalizedString(@"Release to refresh...", @"Release to refresh status"); 36 | _loadingString = NSLocalizedString(@"Loading...", @"Loading Status"); 37 | self.backgroundColor = [UIColor colorWithRed:242./255 green:242./255 blue:242./255 alpha:1]; 38 | _textColor = [UIColor colorWithRed:100./255 green:107./255 blue:103./255 alpha:1]; 39 | } 40 | 41 | 42 | - (instancetype)init{ 43 | self = [super init]; 44 | if (self) { 45 | [self setup]; 46 | } 47 | return self; 48 | } 49 | 50 | - (instancetype)initWithCoder:(NSCoder *)aDecoder{ 51 | self = [super initWithCoder:aDecoder]; 52 | if (self) { 53 | [self setup]; 54 | } 55 | return self; 56 | } 57 | 58 | - (void)dealloc{ 59 | [self removeObserver:self forKeyPath:@"contentOffset"]; 60 | } 61 | 62 | //画圆圈形状 63 | - (CAShapeLayer *)createRingLayerWithCenter:(CGPoint)center radius:(CGFloat)radius lineWidth:(CGFloat)lineWidth color:(UIColor *)color { 64 | UIBezierPath* smoothedPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(radius, radius) radius:radius startAngle:- M_PI_2 endAngle:(M_PI + M_PI_2) clockwise:NO]; 65 | CAShapeLayer *slice = [CAShapeLayer layer]; 66 | slice.contentsScale = [[UIScreen mainScreen] scale]; 67 | slice.frame = CGRectMake(center.x - radius, center.y - radius, radius * 2, radius * 2); 68 | slice.fillColor = [UIColor clearColor].CGColor; 69 | slice.strokeColor = color.CGColor; 70 | slice.lineWidth = lineWidth; 71 | slice.lineCap = kCALineJoinBevel; 72 | slice.lineJoin = kCALineJoinBevel; 73 | slice.path = smoothedPath.CGPath; 74 | return slice; 75 | } 76 | 77 | - (void)willMoveToSuperview:(UIView *)newSuperview{ 78 | self.frame = CGRectMake(0, - CGRectGetHeight(newSuperview.frame), CGRectGetWidth(newSuperview.frame), CGRectGetHeight(newSuperview.frame)); 79 | 80 | //状态标签 81 | CGRect statusLabelRect = CGRectMake(0.0f, self.frame.size.height - 30.0f, self.frame.size.width, 20.0f); 82 | UILabel *label = [[UILabel alloc] initWithFrame:statusLabelRect]; 83 | label.autoresizingMask = UIViewAutoresizingFlexibleWidth; 84 | label.font = [UIFont boldSystemFontOfSize:13.0f]; 85 | label.textColor = self.textColor; 86 | label.shadowColor = [UIColor colorWithWhite:0.9f alpha:1.0f]; 87 | label.shadowOffset = CGSizeMake(0.0f, 1.0f); 88 | label.backgroundColor = [UIColor clearColor]; 89 | label.textAlignment = NSTextAlignmentCenter; 90 | label.text = self.normalString; 91 | [self addSubview:label]; 92 | self.statusLabel = label; 93 | 94 | //下拉进度 95 | self.pullProgressLayer = [self createRingLayerWithCenter:CGPointMake(80, self.frame.size.height - 20.0f) radius:8 lineWidth:2 color:[UIColor colorWithRed:100./255 green:107./255 blue:103./255 alpha:1]]; 96 | self.pullProgressLayer.strokeEnd = 0; 97 | [self.layer addSublayer:self.pullProgressLayer]; 98 | 99 | //读取层,读取中显示旋转动画 100 | self.loadingLayer = [self createRingLayerWithCenter:CGPointMake(80, self.frame.size.height - 20.0f) radius:8 lineWidth:2 color:[UIColor colorWithRed:100./255 green:107./255 blue:103./255 alpha:1]]; 101 | self.loadingLayer.strokeEnd = 0.9; 102 | self.loadingLayer.hidden = YES; 103 | [self.layer addSublayer:self.loadingLayer]; 104 | 105 | //对superView的contentOffset属性进行监听 106 | if ([newSuperview isKindOfClass:[UIScrollView class]]) { 107 | [newSuperview addObserver:self forKeyPath:@"contentOffset" options:NSKeyValueObservingOptionNew context:nil]; 108 | } 109 | } 110 | 111 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{ 112 | UIScrollView *scrollView; 113 | if ([object isKindOfClass:[UIScrollView class]]) { 114 | scrollView = (UIScrollView *)object; 115 | } 116 | if (self.refreshState == RefreshStateLoading) { 117 | CGFloat offset = MAX(scrollView.contentOffset.y * - 1, 0); 118 | offset = MIN(offset, offsetInRefreshing); 119 | scrollView.contentInset = UIEdgeInsetsMake(offset, 0.0f, 0.0f, 0.0f); 120 | self.pullProgressLayer.strokeEnd = 0; 121 | } else if (scrollView.isDragging) { 122 | if (self.refreshState == RefreshStatePulling 123 | && scrollView.contentOffset.y > - distanceForTriggerRefresh 124 | && scrollView.contentOffset.y < 0 125 | && !self.isLoading) { 126 | self.refreshState = RefreshStateNormal; 127 | } 128 | if (self.refreshState == RefreshStateNormal 129 | && scrollView.contentOffset.y < - distanceForTriggerRefresh 130 | && !self.isLoading) { 131 | self.refreshState = RefreshStatePulling; 132 | } 133 | if (scrollView.contentInset.top != 0) { 134 | scrollView.contentInset = UIEdgeInsetsZero; 135 | } 136 | self.pullProgressLayer.strokeEnd = - scrollView.contentOffset.y / (distanceForTriggerRefresh + 10); 137 | } else if (!scrollView.isDragging){ 138 | if (scrollView.contentOffset.y <= - (distanceForTriggerRefresh - 25) 139 | && !self.isLoading 140 | && self.refreshState != RefreshStateNormal) { 141 | [self beginRefreshing]; 142 | } 143 | } 144 | } 145 | 146 | //无限旋转 147 | - (void)rotateLoadingLayer{ 148 | CABasicAnimation* rotationAnimation = 149 | [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];//"z"还可以是“x”“y”,表示沿z轴旋转 150 | rotationAnimation.toValue = [NSNumber numberWithFloat:(2 * M_PI) * 3]; 151 | rotationAnimation.duration = 2.f; 152 | rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 153 | rotationAnimation.repeatCount = NSIntegerMax; 154 | [self.loadingLayer addAnimation:rotationAnimation forKey:@"rotate"]; 155 | } 156 | 157 | 158 | - (void)setRefreshState:(RefreshState)refreshState{ 159 | switch (refreshState) { 160 | case RefreshStatePulling: 161 | self.statusLabel.text = self.releaseToRefreshString; 162 | break; 163 | case RefreshStateNormal: 164 | self.pullProgressLayer.hidden = NO; 165 | self.statusLabel.text = self.normalString; 166 | self.loadingLayer.hidden = YES; 167 | [self.loadingLayer removeAllAnimations]; 168 | break; 169 | case RefreshStateLoading: 170 | self.statusLabel.text = self.loadingString; 171 | self.loadingLayer.hidden = NO; 172 | [self rotateLoadingLayer]; 173 | break; 174 | default: 175 | break; 176 | } 177 | _refreshState = refreshState; 178 | } 179 | 180 | - (void)beginRefreshing{ 181 | if (!self.isLoading) { 182 | if (self.allTargets.count) { 183 | [self sendActionsForControlEvents:UIControlEventValueChanged]; 184 | self.isLoading = YES; 185 | self.refreshState = RefreshStateLoading; 186 | if ([self.superview isKindOfClass:[UIScrollView class]]) { 187 | UIScrollView *scrollView = (UIScrollView *)self.superview; 188 | [UIView animateWithDuration:.2 animations:^{ 189 | scrollView.contentInset = UIEdgeInsetsMake(offsetInRefreshing, 0, 0, 0); 190 | }]; 191 | } 192 | } 193 | } 194 | } 195 | 196 | - (void)endRefreshing{ 197 | self.isLoading = NO; 198 | if ([self.superview isKindOfClass:[UIScrollView class]]) { 199 | UIScrollView *scrollView = (UIScrollView *)self.superview; 200 | [UIView animateWithDuration:.3 animations:^{ 201 | scrollView.contentInset = UIEdgeInsetsMake(0, 0, 0, 0); 202 | }]; 203 | self.refreshState = RefreshStateNormal; 204 | } 205 | } 206 | 207 | @end -------------------------------------------------------------------------------- /HeaderRefreshView.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint HeaderRefreshView.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | 11 | # ――― Spec Metadata ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 12 | # 13 | # These will help people to find your library, and whilst it 14 | # can feel like a chore to fill in it's definitely to your advantage. The 15 | # summary should be tweet-length, and the description more in depth. 16 | # 17 | 18 | s.name = "HeaderRefreshView" 19 | s.version = "1.0.0" 20 | s.summary = "Add a pull-refresh view to a scrollview using just only one line code!" 21 | 22 | s.description = <<-DESC 23 | Add a pull-refresh view to a scrollview using just only one line code!You can customize normal,release to refresh & refreshing strings & text colors,and begin,end refreshing manually as well. 24 | DESC 25 | 26 | s.homepage = "https://github.com/nijino/HeaderRefreshView" 27 | s.screenshots = "http://ww2.sinaimg.cn/large/540e407ajw1ejovaptjbkg208m0fskaa.gif", "http://ww2.sinaimg.cn/large/540e407ajw1ejov8w9j4hg208m0fsnim.gif" 28 | 29 | 30 | # ――― Spec License ――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 31 | # 32 | # Licensing your code is important. See http://choosealicense.com for more info. 33 | # CocoaPods will detect a license file if there is a named LICENSE* 34 | # Popular ones are 'MIT', 'BSD' and 'Apache License, Version 2.0'. 35 | # 36 | 37 | # s.license = "MIT (example)" 38 | s.license = { :type => "MIT", :file => "FILE_LICENSE" } 39 | 40 | 41 | # ――― Author Metadata ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 42 | # 43 | # Specify the authors of the library, with email addresses. Email addresses 44 | # of the authors are extracted from the SCM log. E.g. $ git log. CocoaPods also 45 | # accepts just a name if you'd rather not provide an email address. 46 | # 47 | # Specify a social_media_url where others can refer to, for example a twitter 48 | # profile URL. 49 | # 50 | 51 | s.author = { "nijino" => "nijino_saki@163.com" } 52 | # Or just: s.author = "nijino" 53 | # s.authors = { "nijino" => "nijino_saki@163.com" } 54 | s.social_media_url = "http://www.weibo.com/nijinosaki" 55 | 56 | # ――― Platform Specifics ――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 57 | # 58 | # If this Pod runs only on iOS or OS X, then specify the platform and 59 | # the deployment target. You can optionally include the target after the platform. 60 | # 61 | 62 | # s.platform = :ios 63 | # s.platform = :ios, "6.0" 64 | 65 | # When using multiple platforms 66 | # s.ios.deployment_target = "5.0" 67 | # s.osx.deployment_target = "10.7" 68 | 69 | 70 | # ――― Source Location ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 71 | # 72 | # Specify the location from where the source should be retrieved. 73 | # Supports git, hg, bzr, svn and HTTP. 74 | # 75 | 76 | s.source = { :git => "https://github.com/nijino/HeaderRefreshView.git", :tag => s.version.to_s } 77 | 78 | 79 | # ――― Source Code ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 80 | # 81 | # CocoaPods is smart about how it includes source code. For source files 82 | # giving a folder will include any h, m, mm, c & cpp files. For header 83 | # files it will include any header in the folder. 84 | # Not including the public_header_files will make all headers public. 85 | # 86 | 87 | s.source_files = "HeaderRefreshView.{h,m}" 88 | # s.exclude_files = "Classes/Exclude" 89 | 90 | # s.public_header_files = "Classes/**/*.h" 91 | 92 | 93 | # ――― Resources ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 94 | # 95 | # A list of resources included with the Pod. These are copied into the 96 | # target bundle with a build phase script. Anything else will be cleaned. 97 | # You can preserve files from being cleaned, please don't preserve 98 | # non-essential files like tests, examples and documentation. 99 | # 100 | 101 | # s.resource = "icon.png" 102 | # s.resources = "Resources/*.png" 103 | 104 | # s.preserve_paths = "FilesToSave", "MoreFilesToSave" 105 | 106 | 107 | # ――― Project Linking ―――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 108 | # 109 | # Link your library with frameworks, or libraries. Libraries do not include 110 | # the lib prefix of their name. 111 | # 112 | 113 | s.framework = "QuartzCore" 114 | # s.frameworks = "SomeFramework", "AnotherFramework" 115 | 116 | # s.library = "iconv" 117 | # s.libraries = "iconv", "xml2" 118 | 119 | 120 | # ――― Project Settings ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― # 121 | # 122 | # If your library depends on compiler flags you can set them in the xcconfig hash 123 | # where they will only apply to your library. If you depend on other Podspecs 124 | # you can include multiple dependencies to ensure it works. 125 | 126 | s.requires_arc = true 127 | 128 | # s.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" } 129 | # s.dependency "JSONKit", "~> 1.4" 130 | 131 | end 132 | -------------------------------------------------------------------------------- /HeaderRefreshViewDemo/HeaderRefreshViewDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | D6A5D55919AA46AD00411992 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = D6A5D55819AA46AD00411992 /* main.m */; }; 11 | D6A5D55C19AA46AD00411992 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = D6A5D55B19AA46AD00411992 /* AppDelegate.m */; }; 12 | D6A5D55F19AA46AD00411992 /* MasterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D6A5D55E19AA46AD00411992 /* MasterViewController.m */; }; 13 | D6A5D56219AA46AD00411992 /* DetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D6A5D56119AA46AD00411992 /* DetailViewController.m */; }; 14 | D6A5D56519AA46AD00411992 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = D6A5D56319AA46AD00411992 /* Main.storyboard */; }; 15 | D6A5D56719AA46AD00411992 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D6A5D56619AA46AD00411992 /* Images.xcassets */; }; 16 | D6A5D57319AA46AD00411992 /* HeaderRefreshViewDemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = D6A5D57219AA46AD00411992 /* HeaderRefreshViewDemoTests.m */; }; 17 | D6A5D57E19AA46F000411992 /* HeaderRefreshView.m in Sources */ = {isa = PBXBuildFile; fileRef = D6A5D57D19AA46F000411992 /* HeaderRefreshView.m */; }; 18 | D6A5D58A19AA4CAF00411992 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = D6A5D58819AA4CAF00411992 /* Localizable.strings */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXContainerItemProxy section */ 22 | D6A5D56D19AA46AD00411992 /* PBXContainerItemProxy */ = { 23 | isa = PBXContainerItemProxy; 24 | containerPortal = D6A5D54B19AA46AD00411992 /* Project object */; 25 | proxyType = 1; 26 | remoteGlobalIDString = D6A5D55219AA46AD00411992; 27 | remoteInfo = HeaderRefreshViewDemo; 28 | }; 29 | /* End PBXContainerItemProxy section */ 30 | 31 | /* Begin PBXFileReference section */ 32 | D6A5D55319AA46AD00411992 /* HeaderRefreshViewDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = HeaderRefreshViewDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 33 | D6A5D55719AA46AD00411992 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 34 | D6A5D55819AA46AD00411992 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 35 | D6A5D55A19AA46AD00411992 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 36 | D6A5D55B19AA46AD00411992 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 37 | D6A5D55D19AA46AD00411992 /* MasterViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MasterViewController.h; sourceTree = ""; }; 38 | D6A5D55E19AA46AD00411992 /* MasterViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MasterViewController.m; sourceTree = ""; }; 39 | D6A5D56019AA46AD00411992 /* DetailViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DetailViewController.h; sourceTree = ""; }; 40 | D6A5D56119AA46AD00411992 /* DetailViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DetailViewController.m; sourceTree = ""; }; 41 | D6A5D56419AA46AD00411992 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 42 | D6A5D56619AA46AD00411992 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 43 | D6A5D56C19AA46AD00411992 /* HeaderRefreshViewDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HeaderRefreshViewDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | D6A5D57119AA46AD00411992 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 45 | D6A5D57219AA46AD00411992 /* HeaderRefreshViewDemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HeaderRefreshViewDemoTests.m; sourceTree = ""; }; 46 | D6A5D57C19AA46F000411992 /* HeaderRefreshView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HeaderRefreshView.h; path = ../../HeaderRefreshView.h; sourceTree = ""; }; 47 | D6A5D57D19AA46F000411992 /* HeaderRefreshView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HeaderRefreshView.m; path = ../../HeaderRefreshView.m; sourceTree = ""; }; 48 | D6A5D58719AA4C4200411992 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = "zh-Hans"; path = "zh-Hans.lproj/Main.storyboard"; sourceTree = ""; }; 49 | D6A5D58919AA4CAF00411992 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; 50 | /* End PBXFileReference section */ 51 | 52 | /* Begin PBXFrameworksBuildPhase section */ 53 | D6A5D55019AA46AD00411992 /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | ); 58 | runOnlyForDeploymentPostprocessing = 0; 59 | }; 60 | D6A5D56919AA46AD00411992 /* Frameworks */ = { 61 | isa = PBXFrameworksBuildPhase; 62 | buildActionMask = 2147483647; 63 | files = ( 64 | ); 65 | runOnlyForDeploymentPostprocessing = 0; 66 | }; 67 | /* End PBXFrameworksBuildPhase section */ 68 | 69 | /* Begin PBXGroup section */ 70 | D6A5D54A19AA46AD00411992 = { 71 | isa = PBXGroup; 72 | children = ( 73 | D6A5D55519AA46AD00411992 /* HeaderRefreshViewDemo */, 74 | D6A5D56F19AA46AD00411992 /* HeaderRefreshViewDemoTests */, 75 | D6A5D55419AA46AD00411992 /* Products */, 76 | ); 77 | sourceTree = ""; 78 | }; 79 | D6A5D55419AA46AD00411992 /* Products */ = { 80 | isa = PBXGroup; 81 | children = ( 82 | D6A5D55319AA46AD00411992 /* HeaderRefreshViewDemo.app */, 83 | D6A5D56C19AA46AD00411992 /* HeaderRefreshViewDemoTests.xctest */, 84 | ); 85 | name = Products; 86 | sourceTree = ""; 87 | }; 88 | D6A5D55519AA46AD00411992 /* HeaderRefreshViewDemo */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | D6A5D55A19AA46AD00411992 /* AppDelegate.h */, 92 | D6A5D55B19AA46AD00411992 /* AppDelegate.m */, 93 | D6A5D57C19AA46F000411992 /* HeaderRefreshView.h */, 94 | D6A5D57D19AA46F000411992 /* HeaderRefreshView.m */, 95 | D6A5D55D19AA46AD00411992 /* MasterViewController.h */, 96 | D6A5D55E19AA46AD00411992 /* MasterViewController.m */, 97 | D6A5D56019AA46AD00411992 /* DetailViewController.h */, 98 | D6A5D56119AA46AD00411992 /* DetailViewController.m */, 99 | D6A5D56319AA46AD00411992 /* Main.storyboard */, 100 | D6A5D56619AA46AD00411992 /* Images.xcassets */, 101 | D6A5D55619AA46AD00411992 /* Supporting Files */, 102 | ); 103 | path = HeaderRefreshViewDemo; 104 | sourceTree = ""; 105 | }; 106 | D6A5D55619AA46AD00411992 /* Supporting Files */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | D6A5D58819AA4CAF00411992 /* Localizable.strings */, 110 | D6A5D55719AA46AD00411992 /* Info.plist */, 111 | D6A5D55819AA46AD00411992 /* main.m */, 112 | ); 113 | name = "Supporting Files"; 114 | sourceTree = ""; 115 | }; 116 | D6A5D56F19AA46AD00411992 /* HeaderRefreshViewDemoTests */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | D6A5D57219AA46AD00411992 /* HeaderRefreshViewDemoTests.m */, 120 | D6A5D57019AA46AD00411992 /* Supporting Files */, 121 | ); 122 | path = HeaderRefreshViewDemoTests; 123 | sourceTree = ""; 124 | }; 125 | D6A5D57019AA46AD00411992 /* Supporting Files */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | D6A5D57119AA46AD00411992 /* Info.plist */, 129 | ); 130 | name = "Supporting Files"; 131 | sourceTree = ""; 132 | }; 133 | /* End PBXGroup section */ 134 | 135 | /* Begin PBXNativeTarget section */ 136 | D6A5D55219AA46AD00411992 /* HeaderRefreshViewDemo */ = { 137 | isa = PBXNativeTarget; 138 | buildConfigurationList = D6A5D57619AA46AD00411992 /* Build configuration list for PBXNativeTarget "HeaderRefreshViewDemo" */; 139 | buildPhases = ( 140 | D6A5D54F19AA46AD00411992 /* Sources */, 141 | D6A5D55019AA46AD00411992 /* Frameworks */, 142 | D6A5D55119AA46AD00411992 /* Resources */, 143 | ); 144 | buildRules = ( 145 | ); 146 | dependencies = ( 147 | ); 148 | name = HeaderRefreshViewDemo; 149 | productName = HeaderRefreshViewDemo; 150 | productReference = D6A5D55319AA46AD00411992 /* HeaderRefreshViewDemo.app */; 151 | productType = "com.apple.product-type.application"; 152 | }; 153 | D6A5D56B19AA46AD00411992 /* HeaderRefreshViewDemoTests */ = { 154 | isa = PBXNativeTarget; 155 | buildConfigurationList = D6A5D57919AA46AD00411992 /* Build configuration list for PBXNativeTarget "HeaderRefreshViewDemoTests" */; 156 | buildPhases = ( 157 | D6A5D56819AA46AD00411992 /* Sources */, 158 | D6A5D56919AA46AD00411992 /* Frameworks */, 159 | D6A5D56A19AA46AD00411992 /* Resources */, 160 | ); 161 | buildRules = ( 162 | ); 163 | dependencies = ( 164 | D6A5D56E19AA46AD00411992 /* PBXTargetDependency */, 165 | ); 166 | name = HeaderRefreshViewDemoTests; 167 | productName = HeaderRefreshViewDemoTests; 168 | productReference = D6A5D56C19AA46AD00411992 /* HeaderRefreshViewDemoTests.xctest */; 169 | productType = "com.apple.product-type.bundle.unit-test"; 170 | }; 171 | /* End PBXNativeTarget section */ 172 | 173 | /* Begin PBXProject section */ 174 | D6A5D54B19AA46AD00411992 /* Project object */ = { 175 | isa = PBXProject; 176 | attributes = { 177 | LastUpgradeCheck = 0600; 178 | ORGANIZATIONNAME = www.nijino.cn; 179 | TargetAttributes = { 180 | D6A5D55219AA46AD00411992 = { 181 | CreatedOnToolsVersion = 6.0; 182 | }; 183 | D6A5D56B19AA46AD00411992 = { 184 | CreatedOnToolsVersion = 6.0; 185 | TestTargetID = D6A5D55219AA46AD00411992; 186 | }; 187 | }; 188 | }; 189 | buildConfigurationList = D6A5D54E19AA46AD00411992 /* Build configuration list for PBXProject "HeaderRefreshViewDemo" */; 190 | compatibilityVersion = "Xcode 3.2"; 191 | developmentRegion = English; 192 | hasScannedForEncodings = 0; 193 | knownRegions = ( 194 | en, 195 | Base, 196 | "zh-Hans", 197 | ); 198 | mainGroup = D6A5D54A19AA46AD00411992; 199 | productRefGroup = D6A5D55419AA46AD00411992 /* Products */; 200 | projectDirPath = ""; 201 | projectRoot = ""; 202 | targets = ( 203 | D6A5D55219AA46AD00411992 /* HeaderRefreshViewDemo */, 204 | D6A5D56B19AA46AD00411992 /* HeaderRefreshViewDemoTests */, 205 | ); 206 | }; 207 | /* End PBXProject section */ 208 | 209 | /* Begin PBXResourcesBuildPhase section */ 210 | D6A5D55119AA46AD00411992 /* Resources */ = { 211 | isa = PBXResourcesBuildPhase; 212 | buildActionMask = 2147483647; 213 | files = ( 214 | D6A5D56519AA46AD00411992 /* Main.storyboard in Resources */, 215 | D6A5D58A19AA4CAF00411992 /* Localizable.strings in Resources */, 216 | D6A5D56719AA46AD00411992 /* Images.xcassets in Resources */, 217 | ); 218 | runOnlyForDeploymentPostprocessing = 0; 219 | }; 220 | D6A5D56A19AA46AD00411992 /* Resources */ = { 221 | isa = PBXResourcesBuildPhase; 222 | buildActionMask = 2147483647; 223 | files = ( 224 | ); 225 | runOnlyForDeploymentPostprocessing = 0; 226 | }; 227 | /* End PBXResourcesBuildPhase section */ 228 | 229 | /* Begin PBXSourcesBuildPhase section */ 230 | D6A5D54F19AA46AD00411992 /* Sources */ = { 231 | isa = PBXSourcesBuildPhase; 232 | buildActionMask = 2147483647; 233 | files = ( 234 | D6A5D55C19AA46AD00411992 /* AppDelegate.m in Sources */, 235 | D6A5D55F19AA46AD00411992 /* MasterViewController.m in Sources */, 236 | D6A5D57E19AA46F000411992 /* HeaderRefreshView.m in Sources */, 237 | D6A5D55919AA46AD00411992 /* main.m in Sources */, 238 | D6A5D56219AA46AD00411992 /* DetailViewController.m in Sources */, 239 | ); 240 | runOnlyForDeploymentPostprocessing = 0; 241 | }; 242 | D6A5D56819AA46AD00411992 /* Sources */ = { 243 | isa = PBXSourcesBuildPhase; 244 | buildActionMask = 2147483647; 245 | files = ( 246 | D6A5D57319AA46AD00411992 /* HeaderRefreshViewDemoTests.m in Sources */, 247 | ); 248 | runOnlyForDeploymentPostprocessing = 0; 249 | }; 250 | /* End PBXSourcesBuildPhase section */ 251 | 252 | /* Begin PBXTargetDependency section */ 253 | D6A5D56E19AA46AD00411992 /* PBXTargetDependency */ = { 254 | isa = PBXTargetDependency; 255 | target = D6A5D55219AA46AD00411992 /* HeaderRefreshViewDemo */; 256 | targetProxy = D6A5D56D19AA46AD00411992 /* PBXContainerItemProxy */; 257 | }; 258 | /* End PBXTargetDependency section */ 259 | 260 | /* Begin PBXVariantGroup section */ 261 | D6A5D56319AA46AD00411992 /* Main.storyboard */ = { 262 | isa = PBXVariantGroup; 263 | children = ( 264 | D6A5D56419AA46AD00411992 /* Base */, 265 | D6A5D58719AA4C4200411992 /* zh-Hans */, 266 | ); 267 | name = Main.storyboard; 268 | sourceTree = ""; 269 | }; 270 | D6A5D58819AA4CAF00411992 /* Localizable.strings */ = { 271 | isa = PBXVariantGroup; 272 | children = ( 273 | D6A5D58919AA4CAF00411992 /* zh-Hans */, 274 | ); 275 | name = Localizable.strings; 276 | sourceTree = ""; 277 | }; 278 | /* End PBXVariantGroup section */ 279 | 280 | /* Begin XCBuildConfiguration section */ 281 | D6A5D57419AA46AD00411992 /* Debug */ = { 282 | isa = XCBuildConfiguration; 283 | buildSettings = { 284 | ALWAYS_SEARCH_USER_PATHS = NO; 285 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 286 | CLANG_CXX_LIBRARY = "libc++"; 287 | CLANG_ENABLE_MODULES = YES; 288 | CLANG_ENABLE_OBJC_ARC = YES; 289 | CLANG_WARN_BOOL_CONVERSION = YES; 290 | CLANG_WARN_CONSTANT_CONVERSION = YES; 291 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 292 | CLANG_WARN_EMPTY_BODY = YES; 293 | CLANG_WARN_ENUM_CONVERSION = YES; 294 | CLANG_WARN_INT_CONVERSION = YES; 295 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 296 | CLANG_WARN_UNREACHABLE_CODE = YES; 297 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 298 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 299 | COPY_PHASE_STRIP = NO; 300 | ENABLE_STRICT_OBJC_MSGSEND = YES; 301 | GCC_C_LANGUAGE_STANDARD = gnu99; 302 | GCC_DYNAMIC_NO_PIC = NO; 303 | GCC_OPTIMIZATION_LEVEL = 0; 304 | GCC_PREPROCESSOR_DEFINITIONS = ( 305 | "DEBUG=1", 306 | "$(inherited)", 307 | ); 308 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 309 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 310 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 311 | GCC_WARN_UNDECLARED_SELECTOR = YES; 312 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 313 | GCC_WARN_UNUSED_FUNCTION = YES; 314 | GCC_WARN_UNUSED_VARIABLE = YES; 315 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 316 | MTL_ENABLE_DEBUG_INFO = YES; 317 | ONLY_ACTIVE_ARCH = YES; 318 | SDKROOT = iphoneos; 319 | }; 320 | name = Debug; 321 | }; 322 | D6A5D57519AA46AD00411992 /* Release */ = { 323 | isa = XCBuildConfiguration; 324 | buildSettings = { 325 | ALWAYS_SEARCH_USER_PATHS = NO; 326 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 327 | CLANG_CXX_LIBRARY = "libc++"; 328 | CLANG_ENABLE_MODULES = YES; 329 | CLANG_ENABLE_OBJC_ARC = YES; 330 | CLANG_WARN_BOOL_CONVERSION = YES; 331 | CLANG_WARN_CONSTANT_CONVERSION = YES; 332 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 333 | CLANG_WARN_EMPTY_BODY = YES; 334 | CLANG_WARN_ENUM_CONVERSION = YES; 335 | CLANG_WARN_INT_CONVERSION = YES; 336 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 337 | CLANG_WARN_UNREACHABLE_CODE = YES; 338 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 339 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 340 | COPY_PHASE_STRIP = YES; 341 | ENABLE_NS_ASSERTIONS = NO; 342 | ENABLE_STRICT_OBJC_MSGSEND = YES; 343 | GCC_C_LANGUAGE_STANDARD = gnu99; 344 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 345 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 346 | GCC_WARN_UNDECLARED_SELECTOR = YES; 347 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 348 | GCC_WARN_UNUSED_FUNCTION = YES; 349 | GCC_WARN_UNUSED_VARIABLE = YES; 350 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 351 | MTL_ENABLE_DEBUG_INFO = NO; 352 | SDKROOT = iphoneos; 353 | VALIDATE_PRODUCT = YES; 354 | }; 355 | name = Release; 356 | }; 357 | D6A5D57719AA46AD00411992 /* Debug */ = { 358 | isa = XCBuildConfiguration; 359 | buildSettings = { 360 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 361 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 362 | INFOPLIST_FILE = HeaderRefreshViewDemo/Info.plist; 363 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 364 | PRODUCT_NAME = "$(TARGET_NAME)"; 365 | }; 366 | name = Debug; 367 | }; 368 | D6A5D57819AA46AD00411992 /* Release */ = { 369 | isa = XCBuildConfiguration; 370 | buildSettings = { 371 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 372 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 373 | INFOPLIST_FILE = HeaderRefreshViewDemo/Info.plist; 374 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 375 | PRODUCT_NAME = "$(TARGET_NAME)"; 376 | }; 377 | name = Release; 378 | }; 379 | D6A5D57A19AA46AD00411992 /* Debug */ = { 380 | isa = XCBuildConfiguration; 381 | buildSettings = { 382 | BUNDLE_LOADER = "$(TEST_HOST)"; 383 | FRAMEWORK_SEARCH_PATHS = ( 384 | "$(SDKROOT)/Developer/Library/Frameworks", 385 | "$(inherited)", 386 | ); 387 | GCC_PREPROCESSOR_DEFINITIONS = ( 388 | "DEBUG=1", 389 | "$(inherited)", 390 | ); 391 | INFOPLIST_FILE = HeaderRefreshViewDemoTests/Info.plist; 392 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 393 | PRODUCT_NAME = "$(TARGET_NAME)"; 394 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HeaderRefreshViewDemo.app/HeaderRefreshViewDemo"; 395 | }; 396 | name = Debug; 397 | }; 398 | D6A5D57B19AA46AD00411992 /* Release */ = { 399 | isa = XCBuildConfiguration; 400 | buildSettings = { 401 | BUNDLE_LOADER = "$(TEST_HOST)"; 402 | FRAMEWORK_SEARCH_PATHS = ( 403 | "$(SDKROOT)/Developer/Library/Frameworks", 404 | "$(inherited)", 405 | ); 406 | INFOPLIST_FILE = HeaderRefreshViewDemoTests/Info.plist; 407 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 408 | PRODUCT_NAME = "$(TARGET_NAME)"; 409 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HeaderRefreshViewDemo.app/HeaderRefreshViewDemo"; 410 | }; 411 | name = Release; 412 | }; 413 | /* End XCBuildConfiguration section */ 414 | 415 | /* Begin XCConfigurationList section */ 416 | D6A5D54E19AA46AD00411992 /* Build configuration list for PBXProject "HeaderRefreshViewDemo" */ = { 417 | isa = XCConfigurationList; 418 | buildConfigurations = ( 419 | D6A5D57419AA46AD00411992 /* Debug */, 420 | D6A5D57519AA46AD00411992 /* Release */, 421 | ); 422 | defaultConfigurationIsVisible = 0; 423 | defaultConfigurationName = Release; 424 | }; 425 | D6A5D57619AA46AD00411992 /* Build configuration list for PBXNativeTarget "HeaderRefreshViewDemo" */ = { 426 | isa = XCConfigurationList; 427 | buildConfigurations = ( 428 | D6A5D57719AA46AD00411992 /* Debug */, 429 | D6A5D57819AA46AD00411992 /* Release */, 430 | ); 431 | defaultConfigurationIsVisible = 0; 432 | defaultConfigurationName = Release; 433 | }; 434 | D6A5D57919AA46AD00411992 /* Build configuration list for PBXNativeTarget "HeaderRefreshViewDemoTests" */ = { 435 | isa = XCConfigurationList; 436 | buildConfigurations = ( 437 | D6A5D57A19AA46AD00411992 /* Debug */, 438 | D6A5D57B19AA46AD00411992 /* Release */, 439 | ); 440 | defaultConfigurationIsVisible = 0; 441 | defaultConfigurationName = Release; 442 | }; 443 | /* End XCConfigurationList section */ 444 | }; 445 | rootObject = D6A5D54B19AA46AD00411992 /* Project object */; 446 | } 447 | -------------------------------------------------------------------------------- /HeaderRefreshViewDemo/HeaderRefreshViewDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /HeaderRefreshViewDemo/HeaderRefreshViewDemo.xcodeproj/project.xcworkspace/xcshareddata/HeaderRefreshViewDemo.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | DF9DC669-89B2-4456-B5A2-C4151D61B75B 9 | IDESourceControlProjectName 10 | HeaderRefreshViewDemo 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 4A22E72E27F4E04BAFB0881AB72DC20A38DC5010 14 | github.com:nijino/HeaderRefreshView.git 15 | 16 | IDESourceControlProjectPath 17 | HeaderRefreshViewDemo/HeaderRefreshViewDemo.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 4A22E72E27F4E04BAFB0881AB72DC20A38DC5010 21 | ../../.. 22 | 23 | IDESourceControlProjectURL 24 | github.com:nijino/HeaderRefreshView.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 4A22E72E27F4E04BAFB0881AB72DC20A38DC5010 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 4A22E72E27F4E04BAFB0881AB72DC20A38DC5010 36 | IDESourceControlWCCName 37 | HeaderRefreshView 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /HeaderRefreshViewDemo/HeaderRefreshViewDemo.xcodeproj/project.xcworkspace/xcuserdata/nijino_saki.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nijino/PullToRefreshView/d281af5ac253cc1129d37359e8c4a3a65faf3675/HeaderRefreshViewDemo/HeaderRefreshViewDemo.xcodeproj/project.xcworkspace/xcuserdata/nijino_saki.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /HeaderRefreshViewDemo/HeaderRefreshViewDemo.xcodeproj/project.xcworkspace/xcuserdata/nijino_saki.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 6 | 7 | SnapshotAutomaticallyBeforeSignificantChanges 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /HeaderRefreshViewDemo/HeaderRefreshViewDemo.xcodeproj/xcuserdata/nijino_saki.xcuserdatad/xcschemes/HeaderRefreshViewDemo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 29 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 47 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 65 | 66 | 75 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 94 | 100 | 101 | 102 | 103 | 105 | 106 | 109 | 110 | 111 | -------------------------------------------------------------------------------- /HeaderRefreshViewDemo/HeaderRefreshViewDemo.xcodeproj/xcuserdata/nijino_saki.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | HeaderRefreshViewDemo.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | D6A5D55219AA46AD00411992 16 | 17 | primary 18 | 19 | 20 | D6A5D56B19AA46AD00411992 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /HeaderRefreshViewDemo/HeaderRefreshViewDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // HeaderRefreshViewDemo 4 | // 5 | // Created by nijino on 14/8/25. 6 | // Copyright (c) 2014年 www.nijino.cn. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | 17 | -------------------------------------------------------------------------------- /HeaderRefreshViewDemo/HeaderRefreshViewDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // HeaderRefreshViewDemo 4 | // 5 | // Created by nijino on 14/8/25. 6 | // Copyright (c) 2014年 www.nijino.cn. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | #import "DetailViewController.h" 11 | 12 | @interface AppDelegate () 13 | 14 | @end 15 | 16 | @implementation AppDelegate 17 | 18 | 19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 20 | // Override point for customization after application launch. 21 | return YES; 22 | } 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 26 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 27 | } 28 | 29 | - (void)applicationDidEnterBackground:(UIApplication *)application { 30 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 31 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 32 | } 33 | 34 | - (void)applicationWillEnterForeground:(UIApplication *)application { 35 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 36 | } 37 | 38 | - (void)applicationDidBecomeActive:(UIApplication *)application { 39 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 40 | } 41 | 42 | - (void)applicationWillTerminate:(UIApplication *)application { 43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /HeaderRefreshViewDemo/HeaderRefreshViewDemo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 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 | 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 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | -------------------------------------------------------------------------------- /HeaderRefreshViewDemo/HeaderRefreshViewDemo/DetailViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DetailViewController.h 3 | // HeaderRefreshViewDemo 4 | // 5 | // Created by nijino on 14/8/25. 6 | // Copyright (c) 2014年 www.nijino.cn. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DetailViewController : UIViewController 12 | 13 | @property (strong, nonatomic) id detailItem; 14 | @property (weak, nonatomic) IBOutlet UILabel *detailDescriptionLabel; 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /HeaderRefreshViewDemo/HeaderRefreshViewDemo/DetailViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // DetailViewController.m 3 | // HeaderRefreshViewDemo 4 | // 5 | // Created by nijino on 14/8/25. 6 | // Copyright (c) 2014年 www.nijino.cn. All rights reserved. 7 | // 8 | 9 | #import "DetailViewController.h" 10 | 11 | @interface DetailViewController () 12 | 13 | @end 14 | 15 | @implementation DetailViewController 16 | 17 | #pragma mark - Managing the detail item 18 | 19 | - (void)setDetailItem:(id)newDetailItem { 20 | if (_detailItem != newDetailItem) { 21 | _detailItem = newDetailItem; 22 | 23 | // Update the view. 24 | [self configureView]; 25 | } 26 | } 27 | 28 | - (void)configureView { 29 | // Update the user interface for the detail item. 30 | if (self.detailItem) { 31 | self.detailDescriptionLabel.text = [self.detailItem description]; 32 | } 33 | } 34 | 35 | - (void)viewDidLoad { 36 | [super viewDidLoad]; 37 | // Do any additional setup after loading the view, typically from a nib. 38 | [self configureView]; 39 | } 40 | 41 | - (void)didReceiveMemoryWarning { 42 | [super didReceiveMemoryWarning]; 43 | // Dispose of any resources that can be recreated. 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /HeaderRefreshViewDemo/HeaderRefreshViewDemo/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /HeaderRefreshViewDemo/HeaderRefreshViewDemo/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /HeaderRefreshViewDemo/HeaderRefreshViewDemo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | -.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UIStatusBarTintParameters 32 | 33 | UINavigationBar 34 | 35 | Style 36 | UIBarStyleDefault 37 | Translucent 38 | 39 | 40 | 41 | UISupportedInterfaceOrientations 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationLandscapeLeft 45 | UIInterfaceOrientationLandscapeRight 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /HeaderRefreshViewDemo/HeaderRefreshViewDemo/MasterViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // MasterViewController.h 3 | // HeaderRefreshViewDemo 4 | // 5 | // Created by nijino on 14/8/25. 6 | // Copyright (c) 2014年 www.nijino.cn. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MasterViewController : UITableViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /HeaderRefreshViewDemo/HeaderRefreshViewDemo/MasterViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // MasterViewController.m 3 | // HeaderRefreshViewDemo 4 | // 5 | // Created by nijino on 14/8/25. 6 | // Copyright (c) 2014年 www.nijino.cn. All rights reserved. 7 | // 8 | 9 | #import "MasterViewController.h" 10 | #import "DetailViewController.h" 11 | #import "HeaderRefreshView.h" 12 | 13 | @interface MasterViewController () 14 | 15 | @property (strong, nonatomic) IBOutlet HeaderRefreshView *headerRefreshView; 16 | @property NSMutableArray *objects; 17 | @end 18 | 19 | @implementation MasterViewController 20 | 21 | - (void)awakeFromNib { 22 | [super awakeFromNib]; 23 | } 24 | 25 | - (void)viewDidLoad { 26 | [super viewDidLoad]; 27 | // Do any additional setup after loading the view, typically from a nib. 28 | self.navigationItem.leftBarButtonItem = self.editButtonItem; 29 | 30 | UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)]; 31 | self.navigationItem.rightBarButtonItem = addButton; 32 | [self.tableView addSubview:self.headerRefreshView]; 33 | } 34 | 35 | - (IBAction)refreshData:(id)sender { 36 | NSLog(@"%@",NSLocalizedString(@"Loading...", @"Loading Status")); 37 | [self.headerRefreshView performSelector:@selector(endRefreshing) withObject:nil afterDelay:3]; 38 | } 39 | 40 | - (void)didReceiveMemoryWarning { 41 | [super didReceiveMemoryWarning]; 42 | // Dispose of any resources that can be recreated. 43 | } 44 | 45 | - (void)insertNewObject:(id)sender { 46 | if (!self.objects) { 47 | self.objects = [[NSMutableArray alloc] init]; 48 | } 49 | [self.objects insertObject:[NSDate date] atIndex:0]; 50 | NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0]; 51 | [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic]; 52 | } 53 | 54 | #pragma mark - Segues 55 | 56 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { 57 | if ([[segue identifier] isEqualToString:@"showDetail"]) { 58 | NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow]; 59 | NSDate *object = self.objects[indexPath.row]; 60 | [[segue destinationViewController] setDetailItem:object]; 61 | } 62 | } 63 | 64 | #pragma mark - Table View 65 | 66 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { 67 | return 1; 68 | } 69 | 70 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 71 | return self.objects.count; 72 | } 73 | 74 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 75 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath]; 76 | 77 | NSDate *object = self.objects[indexPath.row]; 78 | cell.textLabel.text = [object description]; 79 | return cell; 80 | } 81 | 82 | - (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { 83 | // Return NO if you do not want the specified item to be editable. 84 | return YES; 85 | } 86 | 87 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { 88 | if (editingStyle == UITableViewCellEditingStyleDelete) { 89 | [self.objects removeObjectAtIndex:indexPath.row]; 90 | [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; 91 | } else if (editingStyle == UITableViewCellEditingStyleInsert) { 92 | // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view. 93 | } 94 | } 95 | 96 | @end 97 | -------------------------------------------------------------------------------- /HeaderRefreshViewDemo/HeaderRefreshViewDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // HeaderRefreshViewDemo 4 | // 5 | // Created by nijino on 14/8/25. 6 | // Copyright (c) 2014年 www.nijino.cn. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /HeaderRefreshViewDemo/HeaderRefreshViewDemo/zh-Hans.lproj/Localizable.strings: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nijino/PullToRefreshView/d281af5ac253cc1129d37359e8c4a3a65faf3675/HeaderRefreshViewDemo/HeaderRefreshViewDemo/zh-Hans.lproj/Localizable.strings -------------------------------------------------------------------------------- /HeaderRefreshViewDemo/HeaderRefreshViewDemo/zh-Hans.lproj/Main.storyboard: -------------------------------------------------------------------------------- 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 | 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 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /HeaderRefreshViewDemo/HeaderRefreshViewDemoTests/HeaderRefreshViewDemoTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // HeaderRefreshViewDemoTests.m 3 | // HeaderRefreshViewDemoTests 4 | // 5 | // Created by nijino on 14/8/25. 6 | // Copyright (c) 2014年 www.nijino.cn. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface HeaderRefreshViewDemoTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation HeaderRefreshViewDemoTests 17 | 18 | - (void)setUp { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown { 24 | // Put teardown code here. This method is called after the invocation of each test method in the class. 25 | [super tearDown]; 26 | } 27 | 28 | - (void)testExample { 29 | // This is an example of a functional test case. 30 | XCTAssert(YES, @"Pass"); 31 | } 32 | 33 | - (void)testPerformanceExample { 34 | // This is an example of a performance test case. 35 | [self measureBlock:^{ 36 | // Put the code you want to measure the time of here. 37 | }]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /HeaderRefreshViewDemo/HeaderRefreshViewDemoTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | -.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Nijino Saki 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | HeaderRefreshView 2 | ================= 3 | 4 | Add a pull-refresh view to a scrollview using just only *one line code*!(using with xib or storyboard) 5 | 只需通过 *一行代码* 给scrollview添加下拉刷新视图。(使用xib或者故事版) 6 | ![refresh-English][refresh-English] 7 | ![refresh-Chinese][refresh-Chinese] 8 | ##Installation 安装方法 9 | Drop "HeaderRefreshView.h" & "HeaderRefreshView.m" into your project. 10 | 将“HeaderRefreshView.h”和“HeaderRefreshView.m”文件拖拽至工程目录。 11 | ##Usage 使用方法 12 | 1.through Xib or Storyboard: 13 | 1.通过Xib或故事版: 14 | Add a UIView Object to your ViewController and change it class name to HeaderRefreshView. 15 | 在你的ViewController中加入一个UIView对象,并且将它的类名改为HeaderRefreshView。 16 | ![Custom class][Custom class] 17 | Connect a method to HeaderRefreshView object's ValueChanged event. 18 | 连接一个方法到HeaderRefreshView实例的ValueChanged事件。 19 | ![Value Changed Event][Value Changed Event] 20 | Insert below code in viewDidLoad method of a viewcontroller: 21 | 在viewcontroller的viewDidLoad方法中插入下面代码: 22 | 23 | [self.tableView addSubview:self.headerRefreshView]; 24 | 25 | 2.through codes: 26 | 2.通过代码: 27 | 28 | self.headerRefreshView = [HeaderRefreshView new]; 29 | [self.headerRefreshView addTarget:self action:@selector(refreshData:) forControlEvent:UIControlEventValueChanged]; 30 | [self.tableView addSubview:self.headerRefreshView]; 31 | ##API 提供接口 32 | You can customize normal,release to refresh & refreshing strings with below properies declared in header file: 33 | 你可以通过在头文件里声明的以下属性定制正常、松手立即刷新以及刷新中的字符串: 34 | 35 | @property (nonatomic, copy) NSString * normalString; 36 | @property (nonatomic, copy) NSString * releaseToRefreshString; 37 | @property (nonatomic, copy) NSString *loadingString; 38 | 39 | Of course you can change these texts color by: 40 | 当然你也可以改变这些文本颜色,通过: 41 | 42 | @property (nonatomic) UIColor *textColor; 43 | 44 | And as you wish,you can begin & end refresh manually: 45 | 如你所料,可以通过手工开始和结束刷新: 46 | 47 | - (void)beginRefreshing; 48 | - (void)endRefreshing; 49 | ##Demo 示例 50 | You can find a demo project in this repository. 51 | 你可以在这个开源库中找到一个示例工程。 52 | ##Version History 版本信息 53 | * v1.0.0 54 | Initial Release. 55 | 初始发布。 56 | 57 | ##Requirements 系统要求 58 | * iOS >= 6.0 59 | * ARC 60 | 61 | ## Contact 联系方式 62 | * Tech blog: 63 | * E-mail: nijino_saki@163.com 64 | * Sina Weibo: [@3G杨叫兽][] 65 | * Twitter: [@yangyubin][] 66 | * Facebook: [nijino_saki][] 67 | 68 | [refresh-English]:http://ww2.sinaimg.cn/large/540e407ajw1ejovaptjbkg208m0fskaa.gif "refresh-English" 69 | [refresh-Chinese]:http://ww2.sinaimg.cn/large/540e407ajw1ejov8w9j4hg208m0fsnim.gif "refresh-Chinese" 70 | [Custom class]:http://ww2.sinaimg.cn/large/540e407ajw1ejovt10domj2079028a9z.jpg "Change class name to HeaderRefreshView" 71 | [Value Changed Event]:http://ww1.sinaimg.cn/large/540e407ajw1ejow0kuz9aj207506w3yq.jpg "Connect to Value Changed Event" 72 | [@3G杨叫兽]:http://www.weibo.com/nijinosaki "3G杨叫兽" 73 | [@yangyubin]:https://twitter.com/yangyubin "欢迎在twitter上关注我" 74 | [nijino_saki]:http://www.facebook.com/nijinosaki1982 "欢迎在facebook上关注我" 75 | --------------------------------------------------------------------------------