├── .gitignore ├── KCCScrollViewContext.h ├── KCCScrollViewContext.m ├── KCCScrollViewContext.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── KCCScrollViewContext ├── AppDelegate.h ├── AppDelegate.m ├── Base.lproj │ ├── LaunchScreen.xib │ └── Main.storyboard ├── DemoTableCell.h ├── DemoTableCell.m ├── DemoTableHeaderView.h ├── DemoTableHeaderView.m ├── DemoTableHeaderView.xib ├── DemoTableViewController.h ├── DemoTableViewController.m ├── DemoTextViewController.h ├── DemoTextViewController.m ├── DemoZoomViewController.h ├── DemoZoomViewController.m ├── Images.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Info.plist ├── demoImages │ ├── 0.jpg │ ├── 1.jpg │ ├── 2.jpg │ ├── 3.jpg │ ├── 4.jpg │ ├── 5.jpg │ ├── 6.jpg │ ├── 7.jpg │ ├── 8.jpg │ ├── 9.jpg │ └── zoom.jpg └── main.m ├── KCCScrollViewContextTests ├── Info.plist └── KCCScrollViewContextTests.m ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | 20 | # CocoaPods 21 | # 22 | # We recommend against adding the Pods directory to your .gitignore. However 23 | # you should judge for yourself, the pros and cons are mentioned at: 24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 25 | # 26 | #Pods/ 27 | -------------------------------------------------------------------------------- /KCCScrollViewContext.h: -------------------------------------------------------------------------------- 1 | // 2 | // KCCScrollViewContext.h 3 | // KCCScrollViewContext 4 | // 5 | // Created by Steven Grace on 6/15/15. 6 | // Copyright (c) 2015 Steven Grace. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | @protocol KCCScrollViewContextDelegate; 12 | 13 | 14 | 15 | @interface KCCScrollViewContext : NSObject 16 | 17 | 18 | - (instancetype)initWithScrollView:(UIScrollView *)scrollView andDelegate:(id)delegate; 19 | 20 | @property (nonatomic, readonly, weak) UIScrollView *scrollView; 21 | @property (nonatomic, readonly, weak) id scrollDelegate; 22 | 23 | // Max contentOffset calculated from the ContentSize and ScrollView Frame 24 | @property (nonatomic, readonly, assign) CGPoint maxOffset; 25 | // YES when scrolling because of user interaction or animation 26 | @property (nonatomic, readonly, assign) BOOL isScrolling; 27 | // YES when using the UIScrollView animation methods 28 | @property (nonatomic, readonly, assign) BOOL isAnimating; 29 | 30 | // last recorded location of the UIScrollView panGesture 31 | @property (nonatomic, readonly ,assign) CGPoint lastKnownTrackingPoint; 32 | 33 | 34 | /* Calculated Scrolling Points */ 35 | 36 | // set when the user begins dragging 37 | @property (nonatomic, readonly, assign) CGPoint scrollingBeganOffset; 38 | // (NAN,NAN) when not scrolling or dragging. Updated once the user has stopped dragging 39 | // and UIScrollgView has been given a chance to caluculate a final offset 40 | @property (nonatomic, readonly, assign) CGPoint expectedScrollingEndOffset; 41 | // ContentOffset when the scrolling last stopped 42 | @property (nonatomic, readonly, assign) CGPoint scrollingEndedOffset; 43 | 44 | 45 | /* Scrolling Direction */ 46 | 47 | // Valid when UIScrollView isScrolling otherwise UIRectEdgeNone 48 | @property (nonatomic, readonly, assign) UIRectEdge scrollingToHorizontalEdge; 49 | @property (nonatomic, readonly, assign) UIRectEdge scrollingToVerticalEdge; 50 | 51 | 52 | /* ZOOM */ 53 | 54 | // set at UIScrollView's callback @selector(scrollViewWillBeginZooming:withView:) 55 | @property (nonatomic, readonly, assign) CGFloat zoomingBeganScale; 56 | 57 | /* Animation */ 58 | 59 | // Completion block is copied and released once animation completes 60 | - (void)setContentOffset:(CGPoint)offset animated:(BOOL)animated complete:(void (^)(void))complete; 61 | - (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated complete:(void (^)(void))complete; 62 | 63 | 64 | // Margin for a given point and edge in the UIScrollView space including contentInset 65 | - (CGFloat)contentMarginForOffset:(CGPoint)point fromEdge:(UIRectEdge)edge; 66 | 67 | @end 68 | 69 | 70 | @protocol KCCScrollViewContextDelegate 71 | 72 | @optional 73 | 74 | /* Scroll Intent */ 75 | 76 | // called after a UIScrollView has calculated a final content offset 77 | - (void)scrollViewWillScroll:(KCCScrollViewContext *)context toOffset:(CGPoint)offset; 78 | // called once UIScrollView has stopped 79 | - (void)scrollViewDidScroll:(KCCScrollViewContext *)context toOffset:(CGPoint)offset; 80 | 81 | /* Content Edge */ 82 | 83 | // called at End Dragging and end of scrolling based on calculated offsets 84 | - (void)scrollViewWillScroll:(KCCScrollViewContext *)context toContentEdge:(UIRectEdge)edge; 85 | - (void)scrollViewDidScroll:(KCCScrollViewContext *)context toContentEdge:(UIRectEdge)edge; 86 | 87 | /* Bounce */ 88 | 89 | // called before UIScrollView deceleration begins and UIScrollView will 'bounce' in respose to the calculated offset 90 | - (void)scrollViewWillBounce:(KCCScrollViewContext *)context toEdge:(UIRectEdge)edge; 91 | // called after UIScrollView stopped scrolling and after a 'bounce' 92 | - (void)scrollViewDidBounce:(KCCScrollViewContext *)context fromEdge:(UIRectEdge)edge; 93 | 94 | 95 | /* Zoom */ 96 | 97 | // called when the zoom interaction begins at the MIN or MAX zoom scale and continues to less than or greated than that scale. 98 | - (void)scrollViewDidZoomPastMinimumScale:(KCCScrollViewContext *)context; 99 | - (void)scrollViewDidZoomPastMaximumScale:(KCCScrollViewContext *)context; 100 | 101 | @end 102 | 103 | 104 | // Description Support 105 | NSString* KCC_NSStringFromUIRectEdge(UIRectEdge edge); 106 | -------------------------------------------------------------------------------- /KCCScrollViewContext.m: -------------------------------------------------------------------------------- 1 | // 2 | // KCCScrollViewContext.m 3 | // KCCScrollViewContext 4 | // 5 | // Created by Steven Grace on 6/15/15. 6 | // Copyright (c) 2015 Steven Grace. All rights reserved. 7 | // 8 | 9 | #import "KCCScrollViewContext.h" 10 | 11 | 12 | // Private Interface 13 | @interface KCCScrollViewContext () 14 | 15 | @property (nonatomic, readwrite ,weak) UIScrollView *scrollView; 16 | 17 | @property (nonatomic, readwrite, assign) BOOL isScrolling; 18 | @property (nonatomic, readwrite, assign) BOOL isAnimating; 19 | 20 | @property (nonatomic, readwrite, copy) void (^scrollAnimationCompleteBlock)(void); 21 | 22 | @property (nonatomic, readwrite, assign) CGPoint scrollingBeganOffset; 23 | @property (nonatomic, readwrite, assign) CGPoint expectedScrollingEndOffset; 24 | @property (nonatomic, readwrite, assign) CGPoint proposedScrollingEndOffset; 25 | 26 | @property (nonatomic, readwrite, assign) CGPoint scrollingEndedOffset; 27 | 28 | @property (nonatomic, readwrite, assign) CGPoint lastContentOffset; 29 | @property (nonatomic, readwrite, assign) CGPoint scrollingVelocity; 30 | 31 | @property (nonatomic, readwrite ,assign) UIRectEdge scrollingToHorizontalEdge; 32 | @property (nonatomic, readwrite ,assign) UIRectEdge scrollingToVerticalEdge; 33 | 34 | @property (nonatomic, readwrite ,assign) CGFloat zoomingBeganScale; 35 | 36 | @property (nonatomic, readwrite ,assign) UIRectEdge bouncingEdge; 37 | 38 | @end 39 | 40 | @implementation KCCScrollViewContext 41 | 42 | 43 | #pragma mark - init 44 | 45 | - (instancetype)initWithScrollView:(UIScrollView*)scrollView andDelegate:(id)delegate { 46 | 47 | if ([super init]) { 48 | _scrollDelegate = delegate; 49 | _scrollView = scrollView; 50 | _scrollView.delegate = self; 51 | _lastContentOffset = _scrollView.contentOffset; 52 | [_scrollView.panGestureRecognizer addTarget:self action:@selector(scrollViewPanGestureHandler:)]; 53 | } 54 | return self; 55 | 56 | } 57 | 58 | - (void)dealloc { 59 | 60 | [_scrollView.panGestureRecognizer removeTarget:self action:@selector(scrollViewPanGestureHandler:)]; 61 | } 62 | 63 | - (void)sendScroll:(UIScrollView *)scroll messageIfNeeded:(SEL)message { 64 | 65 | if ([self.scrollDelegate respondsToSelector:message]) { 66 | # pragma clang diagnostic push 67 | # pragma clang diagnostic ignored "-Warc-performSelector-leaks" 68 | [self.scrollDelegate performSelector:message withObject:scroll]; 69 | # pragma clang diagnostic pop 70 | 71 | } 72 | } 73 | 74 | - (BOOL)respondsToSelector:(SEL)aSelector { 75 | 76 | BOOL result = [super respondsToSelector:aSelector]; 77 | if (!result) { 78 | result = [self.scrollDelegate respondsToSelector:aSelector]; 79 | } 80 | return result; 81 | } 82 | 83 | - (id)forwardingTargetForSelector:(SEL)aSelector { 84 | 85 | if ([self.scrollDelegate respondsToSelector:aSelector]) { 86 | return self.scrollDelegate; 87 | } 88 | return [super forwardingTargetForSelector:aSelector]; 89 | } 90 | 91 | #pragma mark - Setters 92 | 93 | - (void)setIsScrolling:(BOOL)isScrolling { 94 | 95 | if (_isScrolling == isScrolling) { 96 | return; 97 | } 98 | 99 | _isScrolling = isScrolling; 100 | 101 | self.scrollingVelocity = CGPointZero; 102 | 103 | self.scrollingToHorizontalEdge = UIRectEdgeNone; 104 | self.scrollingToVerticalEdge = UIRectEdgeNone; 105 | 106 | self.bouncingEdge = UIRectEdgeNone; 107 | 108 | if (_isScrolling) { 109 | self.expectedScrollingEndOffset = CGPointMake(NAN,NAN); 110 | self.scrollingBeganOffset = self.scrollView.contentOffset; 111 | self.scrollingEndedOffset = CGPointZero; 112 | } 113 | else{ 114 | self.scrollingEndedOffset = self.scrollView.contentOffset; 115 | 116 | if ([self.scrollDelegate respondsToSelector:@selector(scrollViewDidScroll:toOffset:)]) { 117 | [self.scrollDelegate scrollViewDidScroll:self toOffset:self.scrollingEndedOffset]; 118 | } 119 | 120 | self.expectedScrollingEndOffset = CGPointMake(NAN,NAN); 121 | } 122 | } 123 | 124 | #pragma mark - Internal 125 | 126 | - (void)informDelegeateOfScrollingToContentEdgeIfNeededWillScroll:(BOOL)willScroll { 127 | 128 | if (![self.scrollDelegate respondsToSelector:@selector(scrollViewDidScroll:toContentEdge:)]) { 129 | return; 130 | } 131 | 132 | CGPoint offset = willScroll ? self.proposedScrollingEndOffset : self.scrollView.contentOffset; 133 | 134 | UIRectEdge edge= UIRectEdgeNone; 135 | 136 | if ([self contentMarginForOffset:offset fromEdge:UIRectEdgeTop]<0) { 137 | edge = UIRectEdgeTop; 138 | } 139 | else if([self contentMarginForOffset:offset fromEdge:UIRectEdgeBottom]<0) { 140 | edge = UIRectEdgeBottom; 141 | } 142 | else if([self contentMarginForOffset:offset fromEdge:UIRectEdgeRight]<0) { 143 | edge = UIRectEdgeRight; 144 | } 145 | else if([self contentMarginForOffset:offset fromEdge:UIRectEdgeLeft]<0) { 146 | edge = UIRectEdgeLeft; 147 | } 148 | 149 | if (edge==UIRectEdgeNone) { 150 | return; 151 | } 152 | 153 | 154 | if (willScroll) { 155 | [self.scrollDelegate scrollViewWillScroll:self toContentEdge:edge]; 156 | } 157 | else{ 158 | [self.scrollDelegate scrollViewDidScroll:self toContentEdge:edge]; 159 | } 160 | 161 | } 162 | 163 | - (void)informDelegateOfBounceEventIfNeeded { 164 | 165 | if (!self.scrollView.bounces) { 166 | return; 167 | } 168 | 169 | if (![self.scrollDelegate respondsToSelector:@selector(scrollViewWillBounce:toEdge:)]) { 170 | return; 171 | } 172 | 173 | 174 | UIRectEdge edge= UIRectEdgeNone; 175 | 176 | if([self contentMarginForOffset:self.proposedScrollingEndOffset fromEdge:UIRectEdgeTop]<0) { 177 | edge= UIRectEdgeTop; 178 | } 179 | else if ([self contentMarginForOffset:self.proposedScrollingEndOffset fromEdge:UIRectEdgeBottom]<0){ 180 | edge = UIRectEdgeBottom; 181 | } 182 | else if([self contentMarginForOffset:self.proposedScrollingEndOffset fromEdge:UIRectEdgeRight]<0) { 183 | edge= UIRectEdgeRight; 184 | } 185 | else if ([self contentMarginForOffset:self.proposedScrollingEndOffset fromEdge:UIRectEdgeLeft]<0){ 186 | edge = UIRectEdgeLeft; 187 | } 188 | 189 | if (edge==UIRectEdgeNone) { 190 | return; 191 | } 192 | 193 | self.bouncingEdge = edge; 194 | 195 | [self.scrollDelegate scrollViewWillBounce:self toEdge:edge]; 196 | } 197 | 198 | - (void)scrollViewPanGestureHandler:(UIPanGestureRecognizer *)sender { 199 | 200 | _lastKnownTrackingPoint = [sender locationInView:sender.view]; 201 | } 202 | 203 | #pragma mark - Getters 204 | 205 | -(CGPoint)maxOffset { 206 | 207 | return CGPointMake(self.scrollView.contentSize.width-CGRectGetWidth(self.scrollView.frame),self.scrollView.contentSize.height-CGRectGetHeight(self.scrollView.frame)); 208 | } 209 | 210 | #pragma mark - Public 211 | 212 | -(CGFloat)contentMarginForOffset:(CGPoint)point fromEdge:(UIRectEdge)edge { 213 | 214 | switch (edge) { 215 | case UIRectEdgeTop: 216 | return point.y-self.scrollView.contentInset.top; 217 | case UIRectEdgeBottom: 218 | return (self.scrollView.contentSize.height - (point.y + CGRectGetHeight(self.scrollView.frame))) + self.scrollView.contentInset.bottom; 219 | case UIRectEdgeLeft: 220 | return point.x-self.scrollView.contentInset.left; 221 | case UIRectEdgeRight: 222 | return (self.scrollView.contentSize.width - (point.x + CGRectGetWidth(self.scrollView.frame))) + self.scrollView.contentInset.bottom; 223 | default: 224 | break; 225 | } 226 | return 0; 227 | } 228 | 229 | - (void)setContentOffset:(CGPoint)offset animated:(BOOL)animated complete:(void (^)(void))complete { 230 | 231 | if (CGPointEqualToPoint(self.scrollView.contentOffset,offset)) { 232 | complete(); 233 | return; 234 | } 235 | 236 | self.scrollAnimationCompleteBlock = complete; 237 | self.isAnimating = YES; 238 | [self.scrollView setContentOffset:offset animated:animated]; 239 | } 240 | 241 | - (void)scrollRectToVisible:(CGRect)rect animated:(BOOL)animated complete:(void (^)(void))complete { 242 | 243 | self.scrollAnimationCompleteBlock = complete; 244 | self.isAnimating = YES; 245 | [self.scrollView scrollRectToVisible:rect animated:animated]; 246 | } 247 | 248 | #pragma mark - Scroll View Delegate 249 | 250 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView { 251 | 252 | self.scrollingToVerticalEdge = (self.lastContentOffset.y != scrollView.contentOffset.y) ? ( (self.lastContentOffset.yx,targetContentOffset->y); 275 | 276 | 277 | if ([self.scrollDelegate respondsToSelector:@selector(scrollViewWillScroll:toOffset:)]) { 278 | [self.scrollDelegate scrollViewWillScroll:self toOffset:self.proposedScrollingEndOffset]; 279 | } 280 | 281 | 282 | CGPoint offset = CGPointZero; 283 | offset.x = targetContentOffset->x; 284 | offset.y = targetContentOffset->y; 285 | self.expectedScrollingEndOffset = offset; 286 | 287 | 288 | [self informDelegateOfBounceEventIfNeeded]; 289 | } 290 | 291 | - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { 292 | 293 | self.isScrolling = decelerate; 294 | [self sendScroll:scrollView messageIfNeeded:_cmd]; 295 | 296 | if (!decelerate) { 297 | [self informDelegeateOfScrollingToContentEdgeIfNeededWillScroll:NO]; 298 | } 299 | 300 | } 301 | 302 | - (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView { 303 | 304 | [self sendScroll:scrollView messageIfNeeded:_cmd]; 305 | 306 | [self informDelegeateOfScrollingToContentEdgeIfNeededWillScroll:YES]; 307 | } 308 | 309 | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 310 | 311 | 312 | // check before setting scrollingIvar 313 | if (self.bouncingEdge != UIRectEdgeNone) { 314 | if ([self.scrollDelegate respondsToSelector:@selector(scrollViewDidBounce:fromEdge:)]) { 315 | [self.scrollDelegate scrollViewDidBounce:self fromEdge:self.bouncingEdge]; 316 | } 317 | } 318 | 319 | self.isScrolling = NO; 320 | [self sendScroll:scrollView messageIfNeeded:_cmd]; 321 | 322 | [self informDelegeateOfScrollingToContentEdgeIfNeededWillScroll:NO]; 323 | 324 | } 325 | 326 | - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView { 327 | 328 | 329 | self.isScrolling = NO; 330 | self.isAnimating = NO; 331 | 332 | if (self.scrollAnimationCompleteBlock) { 333 | self.scrollAnimationCompleteBlock(); 334 | self.scrollAnimationCompleteBlock = nil; 335 | } 336 | 337 | [self sendScroll:scrollView messageIfNeeded:_cmd]; 338 | } 339 | 340 | - (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView { 341 | 342 | if ([self.scrollDelegate respondsToSelector:@selector(scrollViewShouldScrollToTop:)]) { 343 | return [self.scrollDelegate scrollViewShouldScrollToTop:scrollView]; 344 | } 345 | 346 | return YES; // UIKit default 347 | } 348 | 349 | - (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView { 350 | 351 | [self sendScroll:scrollView messageIfNeeded:_cmd]; 352 | } 353 | 354 | #pragma mark - Zooming 355 | 356 | - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { 357 | 358 | if ([self.scrollDelegate respondsToSelector:@selector(viewForZoomingInScrollView:)]) { 359 | return [self.scrollDelegate viewForZoomingInScrollView:scrollView]; 360 | } 361 | return nil; 362 | } 363 | 364 | - (void)scrollViewDidZoom:(UIScrollView *)scrollView { 365 | 366 | [self sendScroll:scrollView messageIfNeeded:_cmd]; 367 | 368 | if (self.zoomingBeganScale == scrollView.minimumZoomScale && scrollView.zoomScalescrollView.maximumZoomScale) { 374 | 375 | if ([self.scrollDelegate respondsToSelector:@selector(scrollViewDidZoomPastMaximumScale:)]) { 376 | [self.scrollDelegate scrollViewDidZoomPastMaximumScale:self]; 377 | } 378 | } 379 | } 380 | 381 | - (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view { 382 | 383 | self.zoomingBeganScale = scrollView.zoomScale; 384 | } 385 | 386 | - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale { 387 | 388 | [self sendScroll:scrollView messageIfNeeded:_cmd]; 389 | } 390 | 391 | #pragma mark - Description 392 | 393 | - (NSString *)description { 394 | 395 | return [NSString stringWithFormat:@"%@ isScrolling : %@ scrollingBeganOffset: %@ expectedScrollingEndOffst: %@ scrollingEndedOffset : %@ scrollingToHorizontalEdge: %@ scrollingToVerticalEdge: %@", 396 | NSStringFromClass([self class]), 397 | [NSNumber numberWithBool:self.isScrolling], 398 | NSStringFromCGPoint(self.scrollingBeganOffset), 399 | NSStringFromCGPoint(self.expectedScrollingEndOffset), 400 | NSStringFromCGPoint(self.scrollingEndedOffset),KCC_NSStringFromUIRectEdge(self.scrollingToHorizontalEdge),KCC_NSStringFromUIRectEdge(self.scrollingToVerticalEdge)]; 401 | } 402 | 403 | @end 404 | 405 | NSString* KCC_NSStringFromUIRectEdge(UIRectEdge edge) { 406 | 407 | switch (edge) { 408 | case UIRectEdgeLeft: 409 | return @"Left"; 410 | case UIRectEdgeRight: 411 | return @"Right"; 412 | case UIRectEdgeBottom: 413 | return @"Bottom"; 414 | case UIRectEdgeTop: 415 | return @"Top"; 416 | case UIRectEdgeAll: 417 | return @"All"; 418 | case UIRectEdgeNone: 419 | return @"None"; 420 | } 421 | } 422 | -------------------------------------------------------------------------------- /KCCScrollViewContext.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 8B48590C1B2EEFB400C950AB /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B48590B1B2EEFB400C950AB /* main.m */; }; 11 | 8B48590F1B2EEFB400C950AB /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B48590E1B2EEFB400C950AB /* AppDelegate.m */; }; 12 | 8B4859151B2EEFB400C950AB /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 8B4859131B2EEFB400C950AB /* Main.storyboard */; }; 13 | 8B4859171B2EEFB400C950AB /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 8B4859161B2EEFB400C950AB /* Images.xcassets */; }; 14 | 8B48591A1B2EEFB400C950AB /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8B4859181B2EEFB400C950AB /* LaunchScreen.xib */; }; 15 | 8B4859261B2EEFB400C950AB /* KCCScrollViewContextTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B4859251B2EEFB400C950AB /* KCCScrollViewContextTests.m */; }; 16 | 8B4859311B2EF03700C950AB /* KCCScrollViewContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B4859301B2EF03700C950AB /* KCCScrollViewContext.m */; }; 17 | 8B48593E1B2EFFCB00C950AB /* 0.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8B4859331B2EFFCB00C950AB /* 0.jpg */; }; 18 | 8B48593F1B2EFFCB00C950AB /* 1.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8B4859341B2EFFCB00C950AB /* 1.jpg */; }; 19 | 8B4859401B2EFFCB00C950AB /* 2.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8B4859351B2EFFCB00C950AB /* 2.jpg */; }; 20 | 8B4859411B2EFFCB00C950AB /* 3.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8B4859361B2EFFCB00C950AB /* 3.jpg */; }; 21 | 8B4859421B2EFFCB00C950AB /* 4.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8B4859371B2EFFCB00C950AB /* 4.jpg */; }; 22 | 8B4859431B2EFFCB00C950AB /* 5.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8B4859381B2EFFCB00C950AB /* 5.jpg */; }; 23 | 8B4859441B2EFFCB00C950AB /* 6.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8B4859391B2EFFCB00C950AB /* 6.jpg */; }; 24 | 8B4859451B2EFFCB00C950AB /* 7.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8B48593A1B2EFFCB00C950AB /* 7.jpg */; }; 25 | 8B4859461B2EFFCB00C950AB /* 8.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8B48593B1B2EFFCB00C950AB /* 8.jpg */; }; 26 | 8B4859471B2EFFCB00C950AB /* 9.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8B48593C1B2EFFCB00C950AB /* 9.jpg */; }; 27 | 8B4859481B2EFFCB00C950AB /* zoom.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 8B48593D1B2EFFCB00C950AB /* zoom.jpg */; }; 28 | 8B4859541B2F00FA00C950AB /* DemoTableCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B48594A1B2F00FA00C950AB /* DemoTableCell.m */; }; 29 | 8B4859551B2F00FA00C950AB /* DemoTableHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B48594C1B2F00FA00C950AB /* DemoTableHeaderView.m */; }; 30 | 8B4859561B2F00FA00C950AB /* DemoTableHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8B48594D1B2F00FA00C950AB /* DemoTableHeaderView.xib */; }; 31 | 8B4859571B2F00FA00C950AB /* DemoTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B48594F1B2F00FA00C950AB /* DemoTableViewController.m */; }; 32 | 8B4859581B2F00FA00C950AB /* DemoTextViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B4859511B2F00FA00C950AB /* DemoTextViewController.m */; }; 33 | 8B4859591B2F00FA00C950AB /* DemoZoomViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8B4859531B2F00FA00C950AB /* DemoZoomViewController.m */; }; 34 | /* End PBXBuildFile section */ 35 | 36 | /* Begin PBXContainerItemProxy section */ 37 | 8B4859201B2EEFB400C950AB /* PBXContainerItemProxy */ = { 38 | isa = PBXContainerItemProxy; 39 | containerPortal = 8B4858FE1B2EEFB400C950AB /* Project object */; 40 | proxyType = 1; 41 | remoteGlobalIDString = 8B4859051B2EEFB400C950AB; 42 | remoteInfo = KCCScrollViewContext; 43 | }; 44 | /* End PBXContainerItemProxy section */ 45 | 46 | /* Begin PBXFileReference section */ 47 | 8B4859061B2EEFB400C950AB /* KCCScrollViewContext.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = KCCScrollViewContext.app; sourceTree = BUILT_PRODUCTS_DIR; }; 48 | 8B48590A1B2EEFB400C950AB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 49 | 8B48590B1B2EEFB400C950AB /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 50 | 8B48590D1B2EEFB400C950AB /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 51 | 8B48590E1B2EEFB400C950AB /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 52 | 8B4859141B2EEFB400C950AB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 53 | 8B4859161B2EEFB400C950AB /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 54 | 8B4859191B2EEFB400C950AB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 55 | 8B48591F1B2EEFB400C950AB /* KCCScrollViewContextTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = KCCScrollViewContextTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 56 | 8B4859241B2EEFB400C950AB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 57 | 8B4859251B2EEFB400C950AB /* KCCScrollViewContextTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = KCCScrollViewContextTests.m; sourceTree = ""; }; 58 | 8B48592F1B2EF03700C950AB /* KCCScrollViewContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = KCCScrollViewContext.h; sourceTree = ""; }; 59 | 8B4859301B2EF03700C950AB /* KCCScrollViewContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = KCCScrollViewContext.m; sourceTree = ""; }; 60 | 8B4859331B2EFFCB00C950AB /* 0.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = 0.jpg; path = demoImages/0.jpg; sourceTree = ""; }; 61 | 8B4859341B2EFFCB00C950AB /* 1.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = 1.jpg; path = demoImages/1.jpg; sourceTree = ""; }; 62 | 8B4859351B2EFFCB00C950AB /* 2.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = 2.jpg; path = demoImages/2.jpg; sourceTree = ""; }; 63 | 8B4859361B2EFFCB00C950AB /* 3.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = 3.jpg; path = demoImages/3.jpg; sourceTree = ""; }; 64 | 8B4859371B2EFFCB00C950AB /* 4.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = 4.jpg; path = demoImages/4.jpg; sourceTree = ""; }; 65 | 8B4859381B2EFFCB00C950AB /* 5.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = 5.jpg; path = demoImages/5.jpg; sourceTree = ""; }; 66 | 8B4859391B2EFFCB00C950AB /* 6.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = 6.jpg; path = demoImages/6.jpg; sourceTree = ""; }; 67 | 8B48593A1B2EFFCB00C950AB /* 7.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = 7.jpg; path = demoImages/7.jpg; sourceTree = ""; }; 68 | 8B48593B1B2EFFCB00C950AB /* 8.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = 8.jpg; path = demoImages/8.jpg; sourceTree = ""; }; 69 | 8B48593C1B2EFFCB00C950AB /* 9.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = 9.jpg; path = demoImages/9.jpg; sourceTree = ""; }; 70 | 8B48593D1B2EFFCB00C950AB /* zoom.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = zoom.jpg; path = demoImages/zoom.jpg; sourceTree = ""; }; 71 | 8B4859491B2F00FA00C950AB /* DemoTableCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DemoTableCell.h; sourceTree = ""; }; 72 | 8B48594A1B2F00FA00C950AB /* DemoTableCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DemoTableCell.m; sourceTree = ""; }; 73 | 8B48594B1B2F00FA00C950AB /* DemoTableHeaderView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DemoTableHeaderView.h; sourceTree = ""; }; 74 | 8B48594C1B2F00FA00C950AB /* DemoTableHeaderView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DemoTableHeaderView.m; sourceTree = ""; }; 75 | 8B48594D1B2F00FA00C950AB /* DemoTableHeaderView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = DemoTableHeaderView.xib; sourceTree = ""; }; 76 | 8B48594E1B2F00FA00C950AB /* DemoTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DemoTableViewController.h; sourceTree = ""; }; 77 | 8B48594F1B2F00FA00C950AB /* DemoTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DemoTableViewController.m; sourceTree = ""; }; 78 | 8B4859501B2F00FA00C950AB /* DemoTextViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DemoTextViewController.h; sourceTree = ""; }; 79 | 8B4859511B2F00FA00C950AB /* DemoTextViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DemoTextViewController.m; sourceTree = ""; }; 80 | 8B4859521B2F00FA00C950AB /* DemoZoomViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DemoZoomViewController.h; sourceTree = ""; }; 81 | 8B4859531B2F00FA00C950AB /* DemoZoomViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DemoZoomViewController.m; sourceTree = ""; }; 82 | /* End PBXFileReference section */ 83 | 84 | /* Begin PBXFrameworksBuildPhase section */ 85 | 8B4859031B2EEFB400C950AB /* Frameworks */ = { 86 | isa = PBXFrameworksBuildPhase; 87 | buildActionMask = 2147483647; 88 | files = ( 89 | ); 90 | runOnlyForDeploymentPostprocessing = 0; 91 | }; 92 | 8B48591C1B2EEFB400C950AB /* Frameworks */ = { 93 | isa = PBXFrameworksBuildPhase; 94 | buildActionMask = 2147483647; 95 | files = ( 96 | ); 97 | runOnlyForDeploymentPostprocessing = 0; 98 | }; 99 | /* End PBXFrameworksBuildPhase section */ 100 | 101 | /* Begin PBXGroup section */ 102 | 8B4858FD1B2EEFB400C950AB = { 103 | isa = PBXGroup; 104 | children = ( 105 | 8B48592F1B2EF03700C950AB /* KCCScrollViewContext.h */, 106 | 8B4859301B2EF03700C950AB /* KCCScrollViewContext.m */, 107 | 8B4859081B2EEFB400C950AB /* KCCScrollViewContext */, 108 | 8B4859221B2EEFB400C950AB /* KCCScrollViewContextTests */, 109 | 8B4859071B2EEFB400C950AB /* Products */, 110 | ); 111 | sourceTree = ""; 112 | }; 113 | 8B4859071B2EEFB400C950AB /* Products */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | 8B4859061B2EEFB400C950AB /* KCCScrollViewContext.app */, 117 | 8B48591F1B2EEFB400C950AB /* KCCScrollViewContextTests.xctest */, 118 | ); 119 | name = Products; 120 | sourceTree = ""; 121 | }; 122 | 8B4859081B2EEFB400C950AB /* KCCScrollViewContext */ = { 123 | isa = PBXGroup; 124 | children = ( 125 | 8B48590D1B2EEFB400C950AB /* AppDelegate.h */, 126 | 8B48590E1B2EEFB400C950AB /* AppDelegate.m */, 127 | 8B4859491B2F00FA00C950AB /* DemoTableCell.h */, 128 | 8B48594A1B2F00FA00C950AB /* DemoTableCell.m */, 129 | 8B48594B1B2F00FA00C950AB /* DemoTableHeaderView.h */, 130 | 8B48594C1B2F00FA00C950AB /* DemoTableHeaderView.m */, 131 | 8B48594D1B2F00FA00C950AB /* DemoTableHeaderView.xib */, 132 | 8B48594E1B2F00FA00C950AB /* DemoTableViewController.h */, 133 | 8B48594F1B2F00FA00C950AB /* DemoTableViewController.m */, 134 | 8B4859501B2F00FA00C950AB /* DemoTextViewController.h */, 135 | 8B4859511B2F00FA00C950AB /* DemoTextViewController.m */, 136 | 8B4859521B2F00FA00C950AB /* DemoZoomViewController.h */, 137 | 8B4859531B2F00FA00C950AB /* DemoZoomViewController.m */, 138 | 8B4859131B2EEFB400C950AB /* Main.storyboard */, 139 | 8B4859161B2EEFB400C950AB /* Images.xcassets */, 140 | 8B4859181B2EEFB400C950AB /* LaunchScreen.xib */, 141 | 8B4859091B2EEFB400C950AB /* Supporting Files */, 142 | ); 143 | path = KCCScrollViewContext; 144 | sourceTree = ""; 145 | }; 146 | 8B4859091B2EEFB400C950AB /* Supporting Files */ = { 147 | isa = PBXGroup; 148 | children = ( 149 | 8B4859321B2EFF9A00C950AB /* demoImages */, 150 | 8B48590A1B2EEFB400C950AB /* Info.plist */, 151 | 8B48590B1B2EEFB400C950AB /* main.m */, 152 | ); 153 | name = "Supporting Files"; 154 | sourceTree = ""; 155 | }; 156 | 8B4859221B2EEFB400C950AB /* KCCScrollViewContextTests */ = { 157 | isa = PBXGroup; 158 | children = ( 159 | 8B4859251B2EEFB400C950AB /* KCCScrollViewContextTests.m */, 160 | 8B4859231B2EEFB400C950AB /* Supporting Files */, 161 | ); 162 | path = KCCScrollViewContextTests; 163 | sourceTree = ""; 164 | }; 165 | 8B4859231B2EEFB400C950AB /* Supporting Files */ = { 166 | isa = PBXGroup; 167 | children = ( 168 | 8B4859241B2EEFB400C950AB /* Info.plist */, 169 | ); 170 | name = "Supporting Files"; 171 | sourceTree = ""; 172 | }; 173 | 8B4859321B2EFF9A00C950AB /* demoImages */ = { 174 | isa = PBXGroup; 175 | children = ( 176 | 8B4859331B2EFFCB00C950AB /* 0.jpg */, 177 | 8B4859341B2EFFCB00C950AB /* 1.jpg */, 178 | 8B4859351B2EFFCB00C950AB /* 2.jpg */, 179 | 8B4859361B2EFFCB00C950AB /* 3.jpg */, 180 | 8B4859371B2EFFCB00C950AB /* 4.jpg */, 181 | 8B4859381B2EFFCB00C950AB /* 5.jpg */, 182 | 8B4859391B2EFFCB00C950AB /* 6.jpg */, 183 | 8B48593A1B2EFFCB00C950AB /* 7.jpg */, 184 | 8B48593B1B2EFFCB00C950AB /* 8.jpg */, 185 | 8B48593C1B2EFFCB00C950AB /* 9.jpg */, 186 | 8B48593D1B2EFFCB00C950AB /* zoom.jpg */, 187 | ); 188 | name = demoImages; 189 | sourceTree = ""; 190 | }; 191 | /* End PBXGroup section */ 192 | 193 | /* Begin PBXNativeTarget section */ 194 | 8B4859051B2EEFB400C950AB /* KCCScrollViewContext */ = { 195 | isa = PBXNativeTarget; 196 | buildConfigurationList = 8B4859291B2EEFB400C950AB /* Build configuration list for PBXNativeTarget "KCCScrollViewContext" */; 197 | buildPhases = ( 198 | 8B4859021B2EEFB400C950AB /* Sources */, 199 | 8B4859031B2EEFB400C950AB /* Frameworks */, 200 | 8B4859041B2EEFB400C950AB /* Resources */, 201 | ); 202 | buildRules = ( 203 | ); 204 | dependencies = ( 205 | ); 206 | name = KCCScrollViewContext; 207 | productName = KCCScrollViewContext; 208 | productReference = 8B4859061B2EEFB400C950AB /* KCCScrollViewContext.app */; 209 | productType = "com.apple.product-type.application"; 210 | }; 211 | 8B48591E1B2EEFB400C950AB /* KCCScrollViewContextTests */ = { 212 | isa = PBXNativeTarget; 213 | buildConfigurationList = 8B48592C1B2EEFB400C950AB /* Build configuration list for PBXNativeTarget "KCCScrollViewContextTests" */; 214 | buildPhases = ( 215 | 8B48591B1B2EEFB400C950AB /* Sources */, 216 | 8B48591C1B2EEFB400C950AB /* Frameworks */, 217 | 8B48591D1B2EEFB400C950AB /* Resources */, 218 | ); 219 | buildRules = ( 220 | ); 221 | dependencies = ( 222 | 8B4859211B2EEFB400C950AB /* PBXTargetDependency */, 223 | ); 224 | name = KCCScrollViewContextTests; 225 | productName = KCCScrollViewContextTests; 226 | productReference = 8B48591F1B2EEFB400C950AB /* KCCScrollViewContextTests.xctest */; 227 | productType = "com.apple.product-type.bundle.unit-test"; 228 | }; 229 | /* End PBXNativeTarget section */ 230 | 231 | /* Begin PBXProject section */ 232 | 8B4858FE1B2EEFB400C950AB /* Project object */ = { 233 | isa = PBXProject; 234 | attributes = { 235 | LastUpgradeCheck = 0610; 236 | ORGANIZATIONNAME = Developer; 237 | TargetAttributes = { 238 | 8B4859051B2EEFB400C950AB = { 239 | CreatedOnToolsVersion = 6.1.1; 240 | }; 241 | 8B48591E1B2EEFB400C950AB = { 242 | CreatedOnToolsVersion = 6.1.1; 243 | TestTargetID = 8B4859051B2EEFB400C950AB; 244 | }; 245 | }; 246 | }; 247 | buildConfigurationList = 8B4859011B2EEFB400C950AB /* Build configuration list for PBXProject "KCCScrollViewContext" */; 248 | compatibilityVersion = "Xcode 3.2"; 249 | developmentRegion = English; 250 | hasScannedForEncodings = 0; 251 | knownRegions = ( 252 | en, 253 | Base, 254 | ); 255 | mainGroup = 8B4858FD1B2EEFB400C950AB; 256 | productRefGroup = 8B4859071B2EEFB400C950AB /* Products */; 257 | projectDirPath = ""; 258 | projectRoot = ""; 259 | targets = ( 260 | 8B4859051B2EEFB400C950AB /* KCCScrollViewContext */, 261 | 8B48591E1B2EEFB400C950AB /* KCCScrollViewContextTests */, 262 | ); 263 | }; 264 | /* End PBXProject section */ 265 | 266 | /* Begin PBXResourcesBuildPhase section */ 267 | 8B4859041B2EEFB400C950AB /* Resources */ = { 268 | isa = PBXResourcesBuildPhase; 269 | buildActionMask = 2147483647; 270 | files = ( 271 | 8B4859471B2EFFCB00C950AB /* 9.jpg in Resources */, 272 | 8B4859461B2EFFCB00C950AB /* 8.jpg in Resources */, 273 | 8B4859481B2EFFCB00C950AB /* zoom.jpg in Resources */, 274 | 8B4859451B2EFFCB00C950AB /* 7.jpg in Resources */, 275 | 8B4859421B2EFFCB00C950AB /* 4.jpg in Resources */, 276 | 8B4859401B2EFFCB00C950AB /* 2.jpg in Resources */, 277 | 8B4859561B2F00FA00C950AB /* DemoTableHeaderView.xib in Resources */, 278 | 8B48593E1B2EFFCB00C950AB /* 0.jpg in Resources */, 279 | 8B4859431B2EFFCB00C950AB /* 5.jpg in Resources */, 280 | 8B4859441B2EFFCB00C950AB /* 6.jpg in Resources */, 281 | 8B4859151B2EEFB400C950AB /* Main.storyboard in Resources */, 282 | 8B48591A1B2EEFB400C950AB /* LaunchScreen.xib in Resources */, 283 | 8B4859171B2EEFB400C950AB /* Images.xcassets in Resources */, 284 | 8B4859411B2EFFCB00C950AB /* 3.jpg in Resources */, 285 | 8B48593F1B2EFFCB00C950AB /* 1.jpg in Resources */, 286 | ); 287 | runOnlyForDeploymentPostprocessing = 0; 288 | }; 289 | 8B48591D1B2EEFB400C950AB /* Resources */ = { 290 | isa = PBXResourcesBuildPhase; 291 | buildActionMask = 2147483647; 292 | files = ( 293 | ); 294 | runOnlyForDeploymentPostprocessing = 0; 295 | }; 296 | /* End PBXResourcesBuildPhase section */ 297 | 298 | /* Begin PBXSourcesBuildPhase section */ 299 | 8B4859021B2EEFB400C950AB /* Sources */ = { 300 | isa = PBXSourcesBuildPhase; 301 | buildActionMask = 2147483647; 302 | files = ( 303 | 8B4859571B2F00FA00C950AB /* DemoTableViewController.m in Sources */, 304 | 8B4859551B2F00FA00C950AB /* DemoTableHeaderView.m in Sources */, 305 | 8B4859311B2EF03700C950AB /* KCCScrollViewContext.m in Sources */, 306 | 8B48590F1B2EEFB400C950AB /* AppDelegate.m in Sources */, 307 | 8B4859591B2F00FA00C950AB /* DemoZoomViewController.m in Sources */, 308 | 8B48590C1B2EEFB400C950AB /* main.m in Sources */, 309 | 8B4859581B2F00FA00C950AB /* DemoTextViewController.m in Sources */, 310 | 8B4859541B2F00FA00C950AB /* DemoTableCell.m in Sources */, 311 | ); 312 | runOnlyForDeploymentPostprocessing = 0; 313 | }; 314 | 8B48591B1B2EEFB400C950AB /* Sources */ = { 315 | isa = PBXSourcesBuildPhase; 316 | buildActionMask = 2147483647; 317 | files = ( 318 | 8B4859261B2EEFB400C950AB /* KCCScrollViewContextTests.m in Sources */, 319 | ); 320 | runOnlyForDeploymentPostprocessing = 0; 321 | }; 322 | /* End PBXSourcesBuildPhase section */ 323 | 324 | /* Begin PBXTargetDependency section */ 325 | 8B4859211B2EEFB400C950AB /* PBXTargetDependency */ = { 326 | isa = PBXTargetDependency; 327 | target = 8B4859051B2EEFB400C950AB /* KCCScrollViewContext */; 328 | targetProxy = 8B4859201B2EEFB400C950AB /* PBXContainerItemProxy */; 329 | }; 330 | /* End PBXTargetDependency section */ 331 | 332 | /* Begin PBXVariantGroup section */ 333 | 8B4859131B2EEFB400C950AB /* Main.storyboard */ = { 334 | isa = PBXVariantGroup; 335 | children = ( 336 | 8B4859141B2EEFB400C950AB /* Base */, 337 | ); 338 | name = Main.storyboard; 339 | sourceTree = ""; 340 | }; 341 | 8B4859181B2EEFB400C950AB /* LaunchScreen.xib */ = { 342 | isa = PBXVariantGroup; 343 | children = ( 344 | 8B4859191B2EEFB400C950AB /* Base */, 345 | ); 346 | name = LaunchScreen.xib; 347 | sourceTree = ""; 348 | }; 349 | /* End PBXVariantGroup section */ 350 | 351 | /* Begin XCBuildConfiguration section */ 352 | 8B4859271B2EEFB400C950AB /* Debug */ = { 353 | isa = XCBuildConfiguration; 354 | buildSettings = { 355 | ALWAYS_SEARCH_USER_PATHS = NO; 356 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 357 | CLANG_CXX_LIBRARY = "libc++"; 358 | CLANG_ENABLE_MODULES = YES; 359 | CLANG_ENABLE_OBJC_ARC = YES; 360 | CLANG_WARN_BOOL_CONVERSION = YES; 361 | CLANG_WARN_CONSTANT_CONVERSION = YES; 362 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 363 | CLANG_WARN_EMPTY_BODY = YES; 364 | CLANG_WARN_ENUM_CONVERSION = YES; 365 | CLANG_WARN_INT_CONVERSION = YES; 366 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 367 | CLANG_WARN_UNREACHABLE_CODE = YES; 368 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 369 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 370 | COPY_PHASE_STRIP = NO; 371 | ENABLE_STRICT_OBJC_MSGSEND = YES; 372 | GCC_C_LANGUAGE_STANDARD = gnu99; 373 | GCC_DYNAMIC_NO_PIC = NO; 374 | GCC_OPTIMIZATION_LEVEL = 0; 375 | GCC_PREPROCESSOR_DEFINITIONS = ( 376 | "DEBUG=1", 377 | "$(inherited)", 378 | ); 379 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 380 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 381 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 382 | GCC_WARN_UNDECLARED_SELECTOR = YES; 383 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 384 | GCC_WARN_UNUSED_FUNCTION = YES; 385 | GCC_WARN_UNUSED_VARIABLE = YES; 386 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 387 | MTL_ENABLE_DEBUG_INFO = YES; 388 | ONLY_ACTIVE_ARCH = YES; 389 | SDKROOT = iphoneos; 390 | TARGETED_DEVICE_FAMILY = "1,2"; 391 | }; 392 | name = Debug; 393 | }; 394 | 8B4859281B2EEFB400C950AB /* Release */ = { 395 | isa = XCBuildConfiguration; 396 | buildSettings = { 397 | ALWAYS_SEARCH_USER_PATHS = NO; 398 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 399 | CLANG_CXX_LIBRARY = "libc++"; 400 | CLANG_ENABLE_MODULES = YES; 401 | CLANG_ENABLE_OBJC_ARC = YES; 402 | CLANG_WARN_BOOL_CONVERSION = YES; 403 | CLANG_WARN_CONSTANT_CONVERSION = YES; 404 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 405 | CLANG_WARN_EMPTY_BODY = YES; 406 | CLANG_WARN_ENUM_CONVERSION = YES; 407 | CLANG_WARN_INT_CONVERSION = YES; 408 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 409 | CLANG_WARN_UNREACHABLE_CODE = YES; 410 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 411 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 412 | COPY_PHASE_STRIP = YES; 413 | ENABLE_NS_ASSERTIONS = NO; 414 | ENABLE_STRICT_OBJC_MSGSEND = YES; 415 | GCC_C_LANGUAGE_STANDARD = gnu99; 416 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 417 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 418 | GCC_WARN_UNDECLARED_SELECTOR = YES; 419 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 420 | GCC_WARN_UNUSED_FUNCTION = YES; 421 | GCC_WARN_UNUSED_VARIABLE = YES; 422 | IPHONEOS_DEPLOYMENT_TARGET = 8.1; 423 | MTL_ENABLE_DEBUG_INFO = NO; 424 | SDKROOT = iphoneos; 425 | TARGETED_DEVICE_FAMILY = "1,2"; 426 | VALIDATE_PRODUCT = YES; 427 | }; 428 | name = Release; 429 | }; 430 | 8B48592A1B2EEFB400C950AB /* Debug */ = { 431 | isa = XCBuildConfiguration; 432 | buildSettings = { 433 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 434 | INFOPLIST_FILE = KCCScrollViewContext/Info.plist; 435 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 436 | PRODUCT_NAME = "$(TARGET_NAME)"; 437 | }; 438 | name = Debug; 439 | }; 440 | 8B48592B1B2EEFB400C950AB /* Release */ = { 441 | isa = XCBuildConfiguration; 442 | buildSettings = { 443 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 444 | INFOPLIST_FILE = KCCScrollViewContext/Info.plist; 445 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 446 | PRODUCT_NAME = "$(TARGET_NAME)"; 447 | }; 448 | name = Release; 449 | }; 450 | 8B48592D1B2EEFB400C950AB /* Debug */ = { 451 | isa = XCBuildConfiguration; 452 | buildSettings = { 453 | BUNDLE_LOADER = "$(TEST_HOST)"; 454 | FRAMEWORK_SEARCH_PATHS = ( 455 | "$(SDKROOT)/Developer/Library/Frameworks", 456 | "$(inherited)", 457 | ); 458 | GCC_PREPROCESSOR_DEFINITIONS = ( 459 | "DEBUG=1", 460 | "$(inherited)", 461 | ); 462 | INFOPLIST_FILE = KCCScrollViewContextTests/Info.plist; 463 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 464 | PRODUCT_NAME = "$(TARGET_NAME)"; 465 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/KCCScrollViewContext.app/KCCScrollViewContext"; 466 | }; 467 | name = Debug; 468 | }; 469 | 8B48592E1B2EEFB400C950AB /* Release */ = { 470 | isa = XCBuildConfiguration; 471 | buildSettings = { 472 | BUNDLE_LOADER = "$(TEST_HOST)"; 473 | FRAMEWORK_SEARCH_PATHS = ( 474 | "$(SDKROOT)/Developer/Library/Frameworks", 475 | "$(inherited)", 476 | ); 477 | INFOPLIST_FILE = KCCScrollViewContextTests/Info.plist; 478 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 479 | PRODUCT_NAME = "$(TARGET_NAME)"; 480 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/KCCScrollViewContext.app/KCCScrollViewContext"; 481 | }; 482 | name = Release; 483 | }; 484 | /* End XCBuildConfiguration section */ 485 | 486 | /* Begin XCConfigurationList section */ 487 | 8B4859011B2EEFB400C950AB /* Build configuration list for PBXProject "KCCScrollViewContext" */ = { 488 | isa = XCConfigurationList; 489 | buildConfigurations = ( 490 | 8B4859271B2EEFB400C950AB /* Debug */, 491 | 8B4859281B2EEFB400C950AB /* Release */, 492 | ); 493 | defaultConfigurationIsVisible = 0; 494 | defaultConfigurationName = Release; 495 | }; 496 | 8B4859291B2EEFB400C950AB /* Build configuration list for PBXNativeTarget "KCCScrollViewContext" */ = { 497 | isa = XCConfigurationList; 498 | buildConfigurations = ( 499 | 8B48592A1B2EEFB400C950AB /* Debug */, 500 | 8B48592B1B2EEFB400C950AB /* Release */, 501 | ); 502 | defaultConfigurationIsVisible = 0; 503 | defaultConfigurationName = Release; 504 | }; 505 | 8B48592C1B2EEFB400C950AB /* Build configuration list for PBXNativeTarget "KCCScrollViewContextTests" */ = { 506 | isa = XCConfigurationList; 507 | buildConfigurations = ( 508 | 8B48592D1B2EEFB400C950AB /* Debug */, 509 | 8B48592E1B2EEFB400C950AB /* Release */, 510 | ); 511 | defaultConfigurationIsVisible = 0; 512 | defaultConfigurationName = Release; 513 | }; 514 | /* End XCConfigurationList section */ 515 | }; 516 | rootObject = 8B4858FE1B2EEFB400C950AB /* Project object */; 517 | } 518 | -------------------------------------------------------------------------------- /KCCScrollViewContext.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /KCCScrollViewContext/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // KCCScrollViewContext 4 | // 5 | // 6 | // Created by Steven Grace on 6/15/15. 7 | // Copyright (c) 2015 Steven Grace. All rights reserved. 8 | // 9 | 10 | 11 | #import 12 | 13 | @interface AppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | 17 | 18 | @end 19 | 20 | -------------------------------------------------------------------------------- /KCCScrollViewContext/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // KCCScrollViewContext 4 | // 5 | // 6 | // Created by Steven Grace on 6/15/15. 7 | // Copyright (c) 2015 Steven Grace. All rights reserved. 8 | // 9 | 10 | 11 | #import "AppDelegate.h" 12 | 13 | @interface AppDelegate () 14 | 15 | @end 16 | 17 | @implementation AppDelegate 18 | 19 | 20 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 21 | // Override point for customization after application launch. 22 | return YES; 23 | } 24 | 25 | - (void)applicationWillResignActive:(UIApplication *)application { 26 | // 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. 27 | // 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. 28 | } 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // 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. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | - (void)applicationWillEnterForeground:(UIApplication *)application { 36 | // 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. 37 | } 38 | 39 | - (void)applicationDidBecomeActive:(UIApplication *)application { 40 | // 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. 41 | } 42 | 43 | - (void)applicationWillTerminate:(UIApplication *)application { 44 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /KCCScrollViewContext/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /KCCScrollViewContext/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 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | Fanny pack blog cred, bicycle rights roof party banjo synth chillwave kogi fashion axe lomo cold-pressed ennui meh distillery. Health goth Brooklyn fixie, actually VHS semiotics wayfarers tilde cardigan letterpress occupy Odd Future beard gluten-free. Echo Park bespoke Brooklyn Portland tilde. Thundercats paleo normcore Echo Park, swag four dollar toast wolf hella pop-up VHS brunch keffiyeh sriracha Neutra. 90's selfies Schlitz sustainable ethical. Before they sold out roof party Williamsburg fanny pack distillery, twee Bushwick. Godard selvage put a bird on it swag pork belly, tattooed forage High Life gentrify. 108 | 109 | Irony blog lumbersexual, sriracha banjo meggings taxidermy art party four loko plaid narwhal. Vinyl drinking vinegar listicle swag DIY master cleanse McSweeney's. Portland salvia scenester church-key plaid, brunch hashtag heirloom gentrify retro. Truffaut cliche farm-to-table, tousled quinoa street art XOXO fixie pork belly keytar four loko Godard tattooed blog authentic. Church-key try-hard +1 dreamcatcher yr, Blue Bottle lumbersexual Intelligentsia Helvetica. Vice Godard hella organic selfies. Meditation McSweeney's Odd Future deep v, crucifix XOXO whatever DIY Godard. 110 | 111 | 3 wolf moon plaid synth biodiesel selfies. Pickled mlkshk cardigan distillery, four loko fashion axe XOXO chambray American Apparel Vice Neutra fap bespoke forage Pinterest. XOXO fanny pack ugh kitsch, Thundercats Brooklyn paleo listicle photo booth literally Pinterest lo-fi. Typewriter literally authentic paleo organic. Tumblr mustache dreamcatcher Odd Future hella. Mixtape Tumblr Pinterest health goth migas tilde. Craft beer Intelligentsia literally, Bushwick farm-to-table twee yr asymmetrical. 112 | 113 | Pinterest PBR&B umami, YOLO Portland craft beer cronut food truck farm-to-table. Blog biodiesel meh fixie mlkshk. IPhone bespoke locavore Marfa. Deep v Helvetica lomo, freegan organic wayfarers viral cred occupy. Put a bird on it irony kale chips vinyl heirloom pour-over. Farm-to-table freegan quinoa fashion axe Odd Future Neutra selvage actually jean shorts mixtape. Blue Bottle kitsch crucifix, Neutra messenger bag gentrify heirloom distillery sustainable plaid.Fanny pack blog cred, bicycle rights roof party banjo synth chillwave kogi fashion axe lomo cold-pressed ennui meh distillery. Health goth Brooklyn fixie, actually VHS semiotics wayfarers tilde cardigan letterpress occupy Odd Future beard gluten-free. Echo Park bespoke Brooklyn Portland tilde. Thundercats paleo normcore Echo Park, swag four dollar toast wolf hella pop-up VHS brunch keffiyeh sriracha Neutra. 90's selfies Schlitz sustainable ethical. Before they sold out roof party Williamsburg fanny pack distillery, twee Bushwick. Godard selvage put a bird on it swag pork belly, tattooed forage High Life gentrify. 114 | 115 | Irony blog lumbersexual, sriracha banjo meggings taxidermy art party four loko plaid narwhal. Vinyl drinking vinegar listicle swag DIY master cleanse McSweeney's. Portland salvia scenester church-key plaid, brunch hashtag heirloom gentrify retro. Truffaut cliche farm-to-table, tousled quinoa street art XOXO fixie pork belly keytar four loko Godard tattooed blog authentic. Church-key try-hard +1 dreamcatcher yr, Blue Bottle lumbersexual Intelligentsia Helvetica. Vice Godard hella organic selfies. Meditation McSweeney's Odd Future deep v, crucifix XOXO whatever DIY Godard. 116 | 117 | 3 wolf moon plaid synth biodiesel selfies. Pickled mlkshk cardigan distillery, four loko fashion axe XOXO chambray American Apparel Vice Neutra fap bespoke forage Pinterest. XOXO fanny pack ugh kitsch, Thundercats Brooklyn paleo listicle photo booth literally Pinterest lo-fi. Typewriter literally authentic paleo organic. Tumblr mustache dreamcatcher Odd Future hella. Mixtape Tumblr Pinterest health goth migas tilde. Craft beer Intelligentsia literally, Bushwick farm-to-table twee yr asymmetrical. 118 | 119 | Pinterest PBR&B umami, YOLO Portland craft beer cronut food truck farm-to-table. Blog biodiesel meh fixie mlkshk. IPhone bespoke locavore Marfa. Deep v Helvetica lomo, freegan organic wayfarers viral cred occupy. Put a bird on it irony kale chips vinyl heirloom pour-over. Farm-to-table freegan quinoa fashion axe Odd Future Neutra selvage actually jean shorts mixtape. Blue Bottle kitsch crucifix, Neutra messenger bag gentrify heirloom distillery sustainable plaid.Fanny pack blog cred, bicycle rights roof party banjo synth chillwave kogi fashion axe lomo cold-pressed ennui meh distillery. Health goth Brooklyn fixie, actually VHS semiotics wayfarers tilde cardigan letterpress occupy Odd Future beard gluten-free. Echo Park bespoke Brooklyn Portland tilde. Thundercats paleo normcore Echo Park, swag four dollar toast wolf hella pop-up VHS brunch keffiyeh sriracha Neutra. 90's selfies Schlitz sustainable ethical. Before they sold out roof party Williamsburg fanny pack distillery, twee Bushwick. Godard selvage put a bird on it swag pork belly, tattooed forage High Life gentrify. 120 | 121 | Irony blog lumbersexual, sriracha banjo meggings taxidermy art party four loko plaid narwhal. Vinyl drinking vinegar listicle swag DIY master cleanse McSweeney's. Portland salvia scenester church-key plaid, brunch hashtag heirloom gentrify retro. Truffaut cliche farm-to-table, tousled quinoa street art XOXO fixie pork belly keytar four loko Godard tattooed blog authentic. Church-key try-hard +1 dreamcatcher yr, Blue Bottle lumbersexual Intelligentsia Helvetica. Vice Godard hella organic selfies. Meditation McSweeney's Odd Future deep v, crucifix XOXO whatever DIY Godard. 122 | 123 | 3 wolf moon plaid synth biodiesel selfies. Pickled mlkshk cardigan distillery, four loko fashion axe XOXO chambray American Apparel Vice Neutra fap bespoke forage Pinterest. XOXO fanny pack ugh kitsch, Thundercats Brooklyn paleo listicle photo booth literally Pinterest lo-fi. Typewriter literally authentic paleo organic. Tumblr mustache dreamcatcher Odd Future hella. Mixtape Tumblr Pinterest health goth migas tilde. Craft beer Intelligentsia literally, Bushwick farm-to-table twee yr asymmetrical. 124 | 125 | Pinterest PBR&B umami, YOLO Portland craft beer cronut food truck farm-to-table. Blog biodiesel meh fixie mlkshk. IPhone bespoke locavore Marfa. Deep v Helvetica lomo, freegan organic wayfarers viral cred occupy. Put a bird on it irony kale chips vinyl heirloom pour-over. Farm-to-table freegan quinoa fashion axe Odd Future Neutra selvage actually jean shorts mixtape. Blue Bottle kitsch crucifix, Neutra messenger bag gentrify heirloom distillery sustainable plaid.Fanny pack blog cred, bicycle rights roof party banjo synth chillwave kogi fashion axe lomo cold-pressed ennui meh distillery. Health goth Brooklyn fixie, actually VHS semiotics wayfarers tilde cardigan letterpress occupy Odd Future beard gluten-free. Echo Park bespoke Brooklyn Portland tilde. Thundercats paleo normcore Echo Park, swag four dollar toast wolf hella pop-up VHS brunch keffiyeh sriracha Neutra. 90's selfies Schlitz sustainable ethical. Before they sold out roof party Williamsburg fanny pack distillery, twee Bushwick. Godard selvage put a bird on it swag pork belly, tattooed forage High Life gentrify. 126 | 127 | Irony blog lumbersexual, sriracha banjo meggings taxidermy art party four loko plaid narwhal. Vinyl drinking vinegar listicle swag DIY master cleanse McSweeney's. Portland salvia scenester church-key plaid, brunch hashtag heirloom gentrify retro. Truffaut cliche farm-to-table, tousled quinoa street art XOXO fixie pork belly keytar four loko Godard tattooed blog authentic. Church-key try-hard +1 dreamcatcher yr, Blue Bottle lumbersexual Intelligentsia Helvetica. Vice Godard hella organic selfies. Meditation McSweeney's Odd Future deep v, crucifix XOXO whatever DIY Godard. 128 | 129 | 3 wolf moon plaid synth biodiesel selfies. Pickled mlkshk cardigan distillery, four loko fashion axe XOXO chambray American Apparel Vice Neutra fap bespoke forage Pinterest. XOXO fanny pack ugh kitsch, Thundercats Brooklyn paleo listicle photo booth literally Pinterest lo-fi. Typewriter literally authentic paleo organic. Tumblr mustache dreamcatcher Odd Future hella. Mixtape Tumblr Pinterest health goth migas tilde. Craft beer Intelligentsia literally, Bushwick farm-to-table twee yr asymmetrical. 130 | 131 | Pinterest PBR&B umami, YOLO Portland craft beer cronut food truck farm-to-table. Blog biodiesel meh fixie mlkshk. IPhone bespoke locavore Marfa. Deep v Helvetica lomo, freegan organic wayfarers viral cred occupy. Put a bird on it irony kale chips vinyl heirloom pour-over. Farm-to-table freegan quinoa fashion axe Odd Future Neutra selvage actually jean shorts mixtape. Blue Bottle kitsch crucifix, Neutra messenger bag gentrify heirloom distillery sustainable plaid. 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | -------------------------------------------------------------------------------- /KCCScrollViewContext/DemoTableCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // DemoTableCell.h 3 | // ScrollViewContext 4 | // 5 | // 6 | // Created by Steven Grace on 6/15/15. 7 | // Copyright (c) 2015 Steven Grace. All rights reserved. 8 | // 9 | 10 | 11 | #import 12 | 13 | @interface DemoTableCell : UITableViewCell 14 | 15 | @property (weak, nonatomic) IBOutlet UILabel *rowLabel; 16 | @property (weak, nonatomic) IBOutlet UIImageView *rowImageView; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /KCCScrollViewContext/DemoTableCell.m: -------------------------------------------------------------------------------- 1 | // 2 | // DemoTableCell.m 3 | // ScrollViewContext 4 | // 5 | // 6 | // Created by Steven Grace on 6/15/15. 7 | // Copyright (c) 2015 Steven Grace. All rights reserved. 8 | // 9 | 10 | 11 | #import "DemoTableCell.h" 12 | 13 | @implementation DemoTableCell 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /KCCScrollViewContext/DemoTableHeaderView.h: -------------------------------------------------------------------------------- 1 | // 2 | // DemoTableHeaderView.h 3 | // ScrollViewContext 4 | // 5 | // 6 | // Created by Steven Grace on 6/15/15. 7 | // Copyright (c) 2015 Steven Grace. All rights reserved. 8 | // 9 | 10 | 11 | #import 12 | 13 | @interface DemoTableHeaderView : UIView 14 | 15 | @property (weak, nonatomic) IBOutlet UILabel *sectionLabel; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /KCCScrollViewContext/DemoTableHeaderView.m: -------------------------------------------------------------------------------- 1 | // 2 | // DemoTableHeaderView.m 3 | // ScrollViewContext 4 | // 5 | // 6 | // Created by Steven Grace on 6/15/15. 7 | // Copyright (c) 2015 Steven Grace. All rights reserved. 8 | // 9 | 10 | 11 | #import "DemoTableHeaderView.h" 12 | 13 | @implementation DemoTableHeaderView 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /KCCScrollViewContext/DemoTableHeaderView.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /KCCScrollViewContext/DemoTableViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // ScrollViewContext 4 | // 5 | // 6 | // Created by Steven Grace on 6/15/15. 7 | // Copyright (c) 2015 Steven Grace. All rights reserved. 8 | // 9 | 10 | 11 | #import 12 | 13 | @interface DemoTableViewController : UITableViewController 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /KCCScrollViewContext/DemoTableViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // ScrollViewContext 4 | // 5 | // 6 | // Created by Steven Grace on 6/15/15. 7 | // Copyright (c) 2015 Steven Grace. All rights reserved. 8 | // 9 | 10 | 11 | #import "DemoTableViewController.h" 12 | #import "KCCScrollViewContext.h" 13 | #import "DemoTableCell.h" 14 | #import "DemoTableHeaderView.h" 15 | 16 | 17 | #define kUVCellActiveHeight 160.f 18 | #define kUVCellDefaultHeight 160.f 19 | #define kUVCellDragInterval 160.f 20 | #define kDragVelocityDampener .85 21 | 22 | 23 | @interface DemoTableViewController () 24 | 25 | @property (nonatomic, readwrite, strong)KCCScrollViewContext *context; 26 | 27 | @end 28 | 29 | @implementation DemoTableViewController 30 | 31 | - (void)viewDidLoad { 32 | [super viewDidLoad]; 33 | self.context = [[KCCScrollViewContext alloc]initWithScrollView:self.tableView andDelegate:self]; 34 | } 35 | 36 | #pragma mark - Datasource 37 | 38 | + (UIImage *)imageForIndexPath:(NSIndexPath *)indexPath { 39 | return [UIImage imageNamed:[NSString stringWithFormat:@"%li.jpg",indexPath.row%10]]; 40 | } 41 | 42 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{ 43 | return 3; 44 | } 45 | 46 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 47 | return 20; 48 | } 49 | 50 | - (UIView*)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section { 51 | 52 | DemoTableHeaderView *header = [[[UINib nibWithNibName:NSStringFromClass([DemoTableHeaderView class]) bundle:nil]instantiateWithOwner:self options:nil]objectAtIndex:0]; 53 | header.sectionLabel.text = [NSString stringWithFormat:@"%li",(long)section]; 54 | return header; 55 | } 56 | 57 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 58 | 59 | DemoTableCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([DemoTableCell class]) forIndexPath:indexPath]; 60 | cell.rowLabel.text = [NSString stringWithFormat:@"%li",(long)indexPath.row]; 61 | cell.rowImageView.image = [[self class]imageForIndexPath:indexPath]; 62 | return cell; 63 | } 64 | 65 | #pragma mark - UITableViewDelegate 66 | 67 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 68 | 69 | CGPoint offset = [tableView cellForRowAtIndexPath:indexPath].frame.origin; 70 | offset.y = offset.y - ([self.topLayoutGuide length]+CGRectGetHeight([tableView rectForHeaderInSection:indexPath.section])); 71 | 72 | __weak typeof(self) weakSelf = self; 73 | 74 | [self.context setContentOffset:offset animated:YES complete:^{ 75 | NSLog(@"Animation complete :%@",NSStringFromCGPoint(weakSelf.context.scrollView.contentOffset)); 76 | }]; 77 | } 78 | 79 | #pragma mark - KCCScrollViewContextDelegate 80 | 81 | - (void)scrollViewWillScroll:(KCCScrollViewContext *)context toContentEdge:(UIRectEdge)edge { 82 | NSLog(@"%s : %@",__PRETTY_FUNCTION__,KCC_NSStringFromUIRectEdge(edge)); 83 | } 84 | 85 | - (void)scrollViewDidScroll:(KCCScrollViewContext *)context toContentEdge:(UIRectEdge)edge { 86 | NSLog(@"%s : %@",__PRETTY_FUNCTION__,KCC_NSStringFromUIRectEdge(edge)); 87 | } 88 | 89 | - (void)scrollViewWillBounce:(KCCScrollViewContext*)context toEdge:(UIRectEdge)edge{ 90 | NSLog(@"%s : %@",__PRETTY_FUNCTION__,KCC_NSStringFromUIRectEdge(edge)); 91 | } 92 | 93 | - (void)scrollViewDidBounce:(KCCScrollViewContext*)context fromEdge:(UIRectEdge)edge{ 94 | NSLog(@"%s : %@",__PRETTY_FUNCTION__,KCC_NSStringFromUIRectEdge(edge)); 95 | } 96 | 97 | - (void)scrollViewWillScroll:(KCCScrollViewContext *)context toOffset:(CGPoint)offset { 98 | NSLog(@"%s :%@",__PRETTY_FUNCTION__,NSStringFromCGPoint(offset)); 99 | } 100 | 101 | - (void)scrollViewDidScroll:(KCCScrollViewContext *)context toOffset:(CGPoint)offset { 102 | NSLog(@"%s :%@",__PRETTY_FUNCTION__,NSStringFromCGPoint(offset)); 103 | } 104 | 105 | @end 106 | -------------------------------------------------------------------------------- /KCCScrollViewContext/DemoTextViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DemoTextViewController.h 3 | // ScrollViewContext 4 | // 5 | // 6 | // Created by Steven Grace on 6/15/15. 7 | // Copyright (c) 2015 Steven Grace. All rights reserved. 8 | // 9 | 10 | 11 | #import 12 | 13 | @interface DemoTextViewController : UIViewController 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /KCCScrollViewContext/DemoTextViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // DemoTextViewController.m 3 | // ScrollViewContext 4 | // 5 | // 6 | // Created by Steven Grace on 6/15/15. 7 | // Copyright (c) 2015 Steven Grace. All rights reserved. 8 | // 9 | 10 | 11 | #import "DemoTextViewController.h" 12 | #import "KCCScrollViewContext.h" 13 | 14 | @interface DemoTextViewController () 15 | 16 | @property (weak, nonatomic) IBOutlet UITextView *textView; 17 | @property (strong, nonatomic, readwrite)KCCScrollViewContext *scrollContext; 18 | 19 | @property (strong, nonatomic, readwrite) UIFont *font; 20 | @property (assign, nonatomic, readwrite) NSRange redRange; 21 | 22 | 23 | @end 24 | 25 | @implementation DemoTextViewController 26 | 27 | - (void)viewDidLoad { 28 | [super viewDidLoad]; 29 | self.font = self.textView.font; 30 | 31 | self.scrollContext = [[KCCScrollViewContext alloc]initWithScrollView:self.textView andDelegate:self]; 32 | } 33 | 34 | #pragma mark - UIScrollViewDelegate 35 | 36 | - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { 37 | 38 | NSLog(@"%s",__PRETTY_FUNCTION__); 39 | 40 | if (self.redRange.length==0) { 41 | return; 42 | } 43 | 44 | // reset text to black 45 | [self.textView.textStorage beginEditing]; 46 | [self.textView.textStorage setAttributes:@{NSForegroundColorAttributeName:[UIColor blackColor],NSFontAttributeName:self.font} range:self.redRange]; 47 | [self.textView.textStorage endEditing]; 48 | } 49 | 50 | #pragma mark - KCCScrollViewContextDelegate 51 | 52 | - (void)scrollViewWillScroll:(KCCScrollViewContext *)context toContentEdge:(UIRectEdge)edge { 53 | NSLog(@"%s : %@",__PRETTY_FUNCTION__,KCC_NSStringFromUIRectEdge(edge)); 54 | } 55 | 56 | - (void)scrollViewDidScroll:(KCCScrollViewContext *)context toContentEdge:(UIRectEdge)edge { 57 | NSLog(@"%s : %@",__PRETTY_FUNCTION__,KCC_NSStringFromUIRectEdge(edge)); 58 | } 59 | 60 | - (void)scrollViewWillBounce:(KCCScrollViewContext*)context toEdge:(UIRectEdge)edge{ 61 | NSLog(@"%s : %@",__PRETTY_FUNCTION__,KCC_NSStringFromUIRectEdge(edge)); 62 | } 63 | 64 | - (void)scrollViewDidBounce:(KCCScrollViewContext*)context fromEdge:(UIRectEdge)edge{ 65 | NSLog(@"%s : %@",__PRETTY_FUNCTION__,KCC_NSStringFromUIRectEdge(edge)); 66 | } 67 | 68 | - (void)scrollViewWillScroll:(KCCScrollViewContext *)context toOffset:(CGPoint)offset { 69 | 70 | NSLog(@"%s :%@",__PRETTY_FUNCTION__,NSStringFromCGPoint(offset)); 71 | 72 | CGPoint adjustedOffset = offset; 73 | adjustedOffset.y = offset.y +[self.view convertPoint:self.scrollContext.lastKnownTrackingPoint fromView:self.textView].y; 74 | 75 | CGFloat points = 0; 76 | NSUInteger charIndex = 77 | [self.textView.layoutManager characterIndexForPoint:adjustedOffset inTextContainer:self.textView.textContainer fractionOfDistanceBetweenInsertionPoints:&points]; 78 | 79 | __block NSRange lineRange = NSMakeRange(0,0); 80 | 81 | [self.textView.attributedText.string enumerateSubstringsInRange:NSMakeRange(0,[self.textView.attributedText length]) options:NSStringEnumerationBySentences usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) { 82 | 83 | if (NSIntersectionRange(substringRange,NSMakeRange(charIndex,1)).length>0) { 84 | 85 | lineRange = substringRange; 86 | *stop = YES; 87 | } 88 | 89 | }]; 90 | 91 | if (lineRange.length==0) { 92 | return; 93 | } 94 | 95 | self.redRange = lineRange; 96 | 97 | // set the range to Red 98 | [self.textView.textStorage beginEditing]; 99 | [self.textView.textStorage setAttributes:@{NSForegroundColorAttributeName:[UIColor redColor],NSFontAttributeName:self.font} range:self.redRange]; 100 | [self.textView.textStorage endEditing]; 101 | } 102 | @end 103 | -------------------------------------------------------------------------------- /KCCScrollViewContext/DemoZoomViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DemoZoomViewController.h 3 | // ScrollViewContext 4 | // 5 | // 6 | // Created by Steven Grace on 6/15/15. 7 | // Copyright (c) 2015 Steven Grace. All rights reserved. 8 | // 9 | 10 | 11 | #import 12 | 13 | @interface DemoZoomViewController : UIViewController 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /KCCScrollViewContext/DemoZoomViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // DemoZoomViewController.m 3 | // ScrollViewContext 4 | // 5 | // 6 | // Created by Steven Grace on 6/15/15. 7 | // Copyright (c) 2015 Steven Grace. All rights reserved. 8 | // 9 | 10 | 11 | #import "DemoZoomViewController.h" 12 | #import "KCCScrollViewContext.h" 13 | 14 | 15 | @interface DemoZoomViewController () 16 | 17 | @property (weak, nonatomic) IBOutlet UIScrollView *scrollView; 18 | @property (weak, nonatomic) IBOutlet UIImageView *imageView; 19 | @property (nonatomic, readwrite, strong) KCCScrollViewContext *context; 20 | 21 | 22 | @end 23 | 24 | @implementation DemoZoomViewController 25 | 26 | 27 | - (void)viewDidLoad { 28 | [super viewDidLoad]; 29 | self.context = [[KCCScrollViewContext alloc]initWithScrollView:self.scrollView andDelegate:self]; 30 | } 31 | 32 | #pragma mark - UIScrollViewDelegate 33 | 34 | - (UIView*)viewForZoomingInScrollView:(UIScrollView *)scrollView { 35 | return self.imageView; 36 | } 37 | 38 | - (void)scrollViewDidZoom:(UIScrollView *)scrollView { 39 | NSLog(@"%s : ZoomBegan: %f Current: %f",__PRETTY_FUNCTION__,self.context.zoomingBeganScale,self.context.scrollView.zoomScale); 40 | } 41 | 42 | - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale { 43 | self.imageView.alpha = 1; 44 | } 45 | 46 | #pragma mark - KCCScrollViewContextDelegate 47 | 48 | - (void)scrollViewWillBounce:(KCCScrollViewContext *)context toEdge:(UIRectEdge)edge { 49 | NSLog(@"%s : %@",__PRETTY_FUNCTION__,KCC_NSStringFromUIRectEdge(edge)); 50 | } 51 | 52 | - (void)scrollViewDidBounce:(KCCScrollViewContext *)context fromEdge:(UIRectEdge)edge { 53 | NSLog(@"%s : %@",__PRETTY_FUNCTION__,KCC_NSStringFromUIRectEdge(edge)); 54 | } 55 | 56 | - (void)scrollViewDidZoomPastMinimumScale:(KCCScrollViewContext *)context { 57 | NSLog(@"%s ZoomBegan: %f Current: %f ",__PRETTY_FUNCTION__,self.context.zoomingBeganScale,context.scrollView.zoomScale); 58 | self.imageView.alpha = context.scrollView.zoomScale/4; 59 | } 60 | 61 | - (void)scrollViewDidZoomPastMaximumScale:(KCCScrollViewContext *)context { 62 | NSLog(@"%s ZoomBegan: %f Current: %f ",__PRETTY_FUNCTION__,self.context.zoomingBeganScale,context.scrollView.zoomScale); 63 | } 64 | 65 | 66 | @end 67 | -------------------------------------------------------------------------------- /KCCScrollViewContext/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" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /KCCScrollViewContext/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | me.stevengrace.$(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 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /KCCScrollViewContext/demoImages/0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/00StevenG/KCCScrollViewContext/ae28e2ae88a35a2e22e6348fac3c9b49150a6229/KCCScrollViewContext/demoImages/0.jpg -------------------------------------------------------------------------------- /KCCScrollViewContext/demoImages/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/00StevenG/KCCScrollViewContext/ae28e2ae88a35a2e22e6348fac3c9b49150a6229/KCCScrollViewContext/demoImages/1.jpg -------------------------------------------------------------------------------- /KCCScrollViewContext/demoImages/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/00StevenG/KCCScrollViewContext/ae28e2ae88a35a2e22e6348fac3c9b49150a6229/KCCScrollViewContext/demoImages/2.jpg -------------------------------------------------------------------------------- /KCCScrollViewContext/demoImages/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/00StevenG/KCCScrollViewContext/ae28e2ae88a35a2e22e6348fac3c9b49150a6229/KCCScrollViewContext/demoImages/3.jpg -------------------------------------------------------------------------------- /KCCScrollViewContext/demoImages/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/00StevenG/KCCScrollViewContext/ae28e2ae88a35a2e22e6348fac3c9b49150a6229/KCCScrollViewContext/demoImages/4.jpg -------------------------------------------------------------------------------- /KCCScrollViewContext/demoImages/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/00StevenG/KCCScrollViewContext/ae28e2ae88a35a2e22e6348fac3c9b49150a6229/KCCScrollViewContext/demoImages/5.jpg -------------------------------------------------------------------------------- /KCCScrollViewContext/demoImages/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/00StevenG/KCCScrollViewContext/ae28e2ae88a35a2e22e6348fac3c9b49150a6229/KCCScrollViewContext/demoImages/6.jpg -------------------------------------------------------------------------------- /KCCScrollViewContext/demoImages/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/00StevenG/KCCScrollViewContext/ae28e2ae88a35a2e22e6348fac3c9b49150a6229/KCCScrollViewContext/demoImages/7.jpg -------------------------------------------------------------------------------- /KCCScrollViewContext/demoImages/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/00StevenG/KCCScrollViewContext/ae28e2ae88a35a2e22e6348fac3c9b49150a6229/KCCScrollViewContext/demoImages/8.jpg -------------------------------------------------------------------------------- /KCCScrollViewContext/demoImages/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/00StevenG/KCCScrollViewContext/ae28e2ae88a35a2e22e6348fac3c9b49150a6229/KCCScrollViewContext/demoImages/9.jpg -------------------------------------------------------------------------------- /KCCScrollViewContext/demoImages/zoom.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/00StevenG/KCCScrollViewContext/ae28e2ae88a35a2e22e6348fac3c9b49150a6229/KCCScrollViewContext/demoImages/zoom.jpg -------------------------------------------------------------------------------- /KCCScrollViewContext/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // KCCScrollViewContext 4 | // 5 | // Created by Developer on 6/15/15. 6 | // Copyright (c) 2015 Developer. 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 | -------------------------------------------------------------------------------- /KCCScrollViewContextTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | me.stevengrace.$(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 | -------------------------------------------------------------------------------- /KCCScrollViewContextTests/KCCScrollViewContextTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // KCCScrollViewContextTests.m 3 | // KCCScrollViewContextTests 4 | // 5 | // Created by Developer on 6/15/15. 6 | // Copyright (c) 2015 Developer. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface KCCScrollViewContextTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation KCCScrollViewContextTests 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 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Steven Grace 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 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # KCCScrollViewContext 2 | 3 | KCCScrollViewContext provides additional UIScrollView state and expands upon UIScrollViewDelegate. It’s simple to add and works with existing messaging from UIScrollViewDelegate and its extended protocols. It features: 4 | 5 | * accessors like isScrolling, isAnimating, and current scrolling direction (UIRectEdge)
 6 | * accessors to contentOffset values during scrolling events (scrollingBeganOffset , expectedScrollingEndOffset, scrollingEndedOffset)
 7 | * additional delegate callbacks with content offsets for ‘will scroll’ (calculated)  and ‘did scroll’ (actual), 
 8 | * additional delegate callbacks for ‘will scroll’ and ‘did scroll’ events with content edge detection (UIRectEdge) and scrollview bounce events.
 9 | * completion block handlers for UIScrollView’s built in animated methods (setContentOffset:animated: / scrollRectToVisible:animated:)
 10 | * additional zooming callbacks when the user initiates zooming at and past the minimum or maximum zoom scale.
 11 | * UIScrollViewDelegate and its extended protocols (UITableViewDelegate and so on) methods are forwarded to the original delegate (such as UITableViewController).
 12 | 13 | How to use: 14 | 15 | ``` 16 | - (void)viewDidLoad { 17 | [super viewDidLoad]; 18 | self.scrollContext = [[KCCScrollViewContext alloc]initWithScrollView:self.tableView andDelegate:self]; 19 | } 20 | ``` 21 | 22 | Respond to events: 23 | 24 | ``` 25 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 26 | // handle row selection as usual 27 | } 28 | 29 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView { 30 | // handle UIScrollView messages as usual 31 | } 32 | 33 | - (void)scrollViewWillScroll:(KCCScrollViewContext *)context toOffset:(CGPoint)offset { 34 | // do something 35 | } 36 | 37 | - (void)scrollViewDidBounce:(KCCScrollViewContext *)context fromEdge:(UIRectEdge)edge { 38 | // do something 39 | } 40 | ``` 41 | 42 | Brief explanation at : http://00steveng.github.io/KCCScrollViewContext 43 | 44 | --------------------------------------------------------------------------------