├── .DS_Store ├── .gitignore ├── DMLazyScrollViewExample ├── DMLazyScrollView │ ├── DMLazyScrollView.h │ └── DMLazyScrollView.m ├── DMLazyScrollViewExample.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ ├── daniele.xcuserdatad │ │ │ ├── UserInterfaceState.xcuserstate │ │ │ └── WorkspaceSettings.xcsettings │ │ │ └── jack.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ ├── daniele.xcuserdatad │ │ ├── xcdebugger │ │ │ └── Breakpoints.xcbkptlist │ │ └── xcschemes │ │ │ ├── DMLazyScrollViewExample.xcscheme │ │ │ └── xcschememanagement.plist │ │ └── jack.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ ├── DMLazyScrollViewExample.xcscheme │ │ └── xcschememanagement.plist └── DMLazyScrollViewExample │ ├── DMAppDelegate.h │ ├── DMAppDelegate.m │ ├── DMLazyScrollViewExample-Info.plist │ ├── DMLazyScrollViewExample-Prefix.pch │ ├── DMViewController.h │ ├── DMViewController.m │ ├── Default-568h@2x.png │ ├── Default.png │ ├── Default@2x.png │ ├── en.lproj │ ├── DMViewController_iPad.xib │ ├── DMViewController_iPhone.xib │ └── InfoPlist.strings │ └── main.m └── README.md /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malcommac/DMLazyScrollView/865bf3112b650bf83bcf125f82197256a7418252/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /DMLazyScrollViewExample/.DS_Store 2 | .DS_Store -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollView/DMLazyScrollView.h: -------------------------------------------------------------------------------- 1 | // 2 | // DMLazyScrollView.h 3 | // Lazy Loading UIScrollView for iOS 4 | // 5 | // Created by Daniele Margutti (me@danielemargutti.com) on 24/11/12. 6 | // Copyright (c) 2012 http://www.danielemargutti.com. All rights reserved. 7 | // Distribuited under MIT License 8 | // 9 | 10 | #import 11 | 12 | @class DMLazyScrollView; 13 | 14 | enum { 15 | DMLazyScrollViewDirectionHorizontal = 0, 16 | DMLazyScrollViewDirectionVertical = 1, 17 | };typedef NSUInteger DMLazyScrollViewDirection; 18 | 19 | enum { 20 | DMLazyScrollViewTransitionAuto = 0, 21 | DMLazyScrollViewTransitionForward = 1, 22 | DMLazyScrollViewTransitionBackward = 2 23 | }; typedef NSUInteger DMLazyScrollViewTransition; 24 | 25 | @protocol DMLazyScrollViewDelegate 26 | @optional 27 | - (void)lazyScrollViewWillBeginDragging:(DMLazyScrollView *)pagingView; 28 | //Called when it scrolls, except from as the result of self-driven animation. 29 | - (void)lazyScrollViewDidScroll:(DMLazyScrollView *)pagingView at:(CGPoint) visibleOffset; 30 | //Called whenever it scrolls: through user manipulation, setup, or self-driven animation. 31 | - (void)lazyScrollViewDidScroll:(DMLazyScrollView *)pagingView at:(CGPoint) visibleOffset withSelfDrivenAnimation:(BOOL)selfDrivenAnimation; 32 | - (void)lazyScrollViewDidEndDragging:(DMLazyScrollView *)pagingView; 33 | - (void)lazyScrollViewWillBeginDecelerating:(DMLazyScrollView *)pagingView; 34 | - (void)lazyScrollViewDidEndDecelerating:(DMLazyScrollView *)pagingView atPageIndex:(NSInteger)pageIndex; 35 | - (void)lazyScrollView:(DMLazyScrollView *)pagingView currentPageChanged:(NSInteger)currentPageIndex; 36 | @end 37 | 38 | typedef UIViewController*(^DMLazyScrollViewDataSource)(NSUInteger index); 39 | 40 | @interface DMLazyScrollView : UIScrollView 41 | 42 | @property (copy) DMLazyScrollViewDataSource dataSource; 43 | @property (nonatomic, assign) id controlDelegate; 44 | 45 | @property (nonatomic,assign) NSUInteger numberOfPages; 46 | @property (readonly) NSUInteger currentPage; 47 | @property (readonly) DMLazyScrollViewDirection direction; 48 | 49 | @property (nonatomic, assign) BOOL autoPlay; 50 | @property (nonatomic, assign) CGFloat autoPlayTime; //default 3 seconds 51 | 52 | - (id)initWithFrameAndDirection:(CGRect)frame 53 | direction:(DMLazyScrollViewDirection)direction 54 | circularScroll:(BOOL) circularScrolling; 55 | 56 | - (void)setEnableCircularScroll:(BOOL)circularScrolling; 57 | - (BOOL)circularScrollEnabled; 58 | 59 | - (void) reloadData; 60 | 61 | - (void) setPage:(NSInteger) index animated:(BOOL) animated; 62 | - (void) setPage:(NSInteger) newIndex transition:(DMLazyScrollViewTransition) transition animated:(BOOL) animated; 63 | - (void) moveByPages:(NSInteger) offset animated:(BOOL) animated; 64 | 65 | - (UIViewController *) visibleViewController; 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollView/DMLazyScrollView.m: -------------------------------------------------------------------------------- 1 | // 2 | // DMLazyScrollView.m 3 | // Lazy Loading UIScrollView for iOS 4 | // 5 | // Created by Daniele Margutti (me@danielemargutti.com) on 24/11/12. 6 | // Copyright (c) 2012 http://www.danielemargutti.com. All rights reserved. 7 | // Distribuited under MIT License 8 | // 9 | 10 | #import "DMLazyScrollView.h" 11 | 12 | enum { 13 | DMLazyScrollViewScrollDirectionBackward = 0, 14 | DMLazyScrollViewScrollDirectionForward = 1 15 | }; typedef NSUInteger DMLazyScrollViewScrollDirection; 16 | 17 | #define kDMLazyScrollViewTransitionDuration 0.4 18 | 19 | @interface DMLazyScrollView() { 20 | NSUInteger numberOfPages; 21 | NSUInteger currentPage; 22 | BOOL isManualAnimating; 23 | BOOL circularScrollEnabled; 24 | } 25 | @property (nonatomic, strong) NSTimer* timer_autoPlay; 26 | @end 27 | 28 | @implementation DMLazyScrollView 29 | 30 | @synthesize numberOfPages,currentPage; 31 | @synthesize dataSource,controlDelegate; 32 | @synthesize autoPlay = _autoPlay; 33 | @synthesize timer_autoPlay = _timer_autoPlay; 34 | @synthesize autoPlayTime = _autoPlayTime; 35 | 36 | - (id)init { 37 | return [self initWithFrame:CGRectZero]; 38 | } 39 | 40 | - (id)initWithFrame:(CGRect)frame 41 | { 42 | return [self initWithFrameAndDirection:frame direction:DMLazyScrollViewDirectionHorizontal circularScroll:NO]; 43 | } 44 | 45 | - (id)initWithFrameAndDirection:(CGRect)frame 46 | direction:(DMLazyScrollViewDirection)direction 47 | circularScroll:(BOOL) circularScrolling { 48 | 49 | self = [super initWithFrame:frame]; 50 | if (self) { 51 | _direction = direction; 52 | circularScrollEnabled = circularScrolling; 53 | _autoPlayTime = 3; 54 | [self initializeControl]; 55 | } 56 | return self; 57 | } 58 | 59 | - (void)setAutoPlay:(BOOL)autoPlay 60 | { 61 | _autoPlay = autoPlay; 62 | if(self.numberOfPages) 63 | { 64 | [self reloadData]; 65 | } 66 | } 67 | 68 | - (BOOL)hasMultiplePages { 69 | return numberOfPages > 1; 70 | } 71 | 72 | - (void)resetAutoPlay 73 | { 74 | if(_autoPlay) 75 | { 76 | if(_timer_autoPlay) 77 | { 78 | [_timer_autoPlay invalidate]; 79 | _timer_autoPlay = nil; 80 | } 81 | _timer_autoPlay = [NSTimer scheduledTimerWithTimeInterval:_autoPlayTime target:self selector:@selector(autoPlayHanlde:) userInfo:nil repeats:YES]; 82 | } 83 | else 84 | { 85 | if(_timer_autoPlay) 86 | { 87 | [_timer_autoPlay invalidate]; 88 | _timer_autoPlay = nil; 89 | } 90 | } 91 | } 92 | 93 | - (void)autoPlayHanlde:(id)timer 94 | { 95 | if ([self hasMultiplePages]) { 96 | [self autoPlayGoToNextPage]; 97 | } 98 | } 99 | 100 | - (void)autoPlayGoToNextPage 101 | { 102 | NSInteger nextPage = self.currentPage+1; 103 | if(nextPage >= self.numberOfPages) 104 | { 105 | nextPage = 0; 106 | } 107 | [self setPage:nextPage animated:YES]; 108 | } 109 | 110 | - (void)autoPlayPause 111 | { 112 | if(_timer_autoPlay) 113 | { 114 | [_timer_autoPlay invalidate]; 115 | _timer_autoPlay = nil; 116 | } 117 | } 118 | 119 | - (void)autoPlayResume 120 | { 121 | [self resetAutoPlay]; 122 | } 123 | 124 | - (void)setEnableCircularScroll:(BOOL)circularScrolling 125 | { 126 | circularScrollEnabled = circularScrolling; 127 | } 128 | 129 | - (BOOL)circularScrollEnabled 130 | { 131 | return circularScrollEnabled; 132 | } 133 | 134 | - (void) awakeFromNib { 135 | [self initializeControl]; 136 | } 137 | 138 | - (void) initializeControl { 139 | self.showsHorizontalScrollIndicator = NO; 140 | self.showsVerticalScrollIndicator = NO; 141 | self.pagingEnabled = YES; 142 | self.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; 143 | self.delegate = self; 144 | self.contentSize = CGSizeMake(self.frame.size.width, self.contentSize.height); 145 | currentPage = NSNotFound; 146 | } 147 | 148 | - (void) setNumberOfPages:(NSUInteger)pages { 149 | if (pages != numberOfPages) { 150 | numberOfPages = pages; 151 | int offset = [self hasMultiplePages] ? numberOfPages + 2 : 1; 152 | if (_direction == DMLazyScrollViewDirectionHorizontal) { 153 | self.contentSize = CGSizeMake(self.frame.size.width * offset, 154 | self.contentSize.height); 155 | } else { 156 | self.contentSize = CGSizeMake(self.frame.size.width, 157 | self.frame.size.height * offset); 158 | } 159 | [self reloadData]; 160 | } 161 | } 162 | 163 | - (void) reloadData { 164 | [self setCurrentViewController:0]; 165 | [self resetAutoPlay]; 166 | } 167 | 168 | - (void) layoutSubviews { 169 | [super layoutSubviews]; 170 | } 171 | 172 | - (CGRect) visibleRect { 173 | CGRect visibleRect; 174 | visibleRect.origin = self.contentOffset; 175 | visibleRect.size = self.bounds.size; 176 | return visibleRect; 177 | } 178 | 179 | - (CGPoint) createPoint:(CGFloat) size { 180 | if (_direction == DMLazyScrollViewDirectionHorizontal) { 181 | return CGPointMake(size, 0); 182 | } else { 183 | return CGPointMake(0, size); 184 | } 185 | } 186 | 187 | -(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{ 188 | self.bounces = YES; 189 | if (nil != controlDelegate && [controlDelegate respondsToSelector:@selector(lazyScrollViewDidEndDragging:)]) 190 | [controlDelegate lazyScrollViewDidEndDragging:self]; 191 | [self autoPlayResume]; 192 | } 193 | 194 | 195 | - (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { 196 | [self autoPlayPause]; 197 | if (nil != controlDelegate && [controlDelegate respondsToSelector:@selector(lazyScrollViewWillBeginDragging:)]) 198 | [controlDelegate lazyScrollViewWillBeginDragging:self]; 199 | } 200 | 201 | - (void) scrollViewDidScroll:(UIScrollView *)scrollView { 202 | if (isManualAnimating) { 203 | if (nil != controlDelegate && [controlDelegate respondsToSelector:@selector(lazyScrollViewDidScroll:at:withSelfDrivenAnimation:)]) { 204 | [controlDelegate lazyScrollViewDidScroll:self at:[self visibleRect].origin withSelfDrivenAnimation:YES]; 205 | } 206 | return; 207 | } 208 | 209 | CGFloat offset = (_direction==DMLazyScrollViewDirectionHorizontal) ? scrollView.contentOffset.x : scrollView.contentOffset.y; 210 | CGFloat size =(_direction==DMLazyScrollViewDirectionHorizontal) ? self.frame.size.width : self.frame.size.height; 211 | 212 | 213 | // with two pages only scrollview you can only go forward 214 | // (this prevents us to have a glitch with the next UIView (it can't be placed in two positions at the same time) 215 | DMLazyScrollViewScrollDirection proposedScroll = (offset <= (size*2) ? 216 | DMLazyScrollViewScrollDirectionBackward : // we're moving back 217 | DMLazyScrollViewScrollDirectionForward); // we're moving forward 218 | 219 | // you can go back if circular mode is enabled or your current page is not the first page 220 | BOOL canScrollBackward = (circularScrollEnabled || (!circularScrollEnabled && self.currentPage != 0)); 221 | // you can go forward if circular mode is enabled and current page is not the last page 222 | BOOL canScrollForward = (circularScrollEnabled || (!circularScrollEnabled && self.currentPage < (self.numberOfPages-1))); 223 | 224 | NSInteger prevPage = [self pageIndexByAdding:-1 from:self.currentPage]; 225 | NSInteger nextPage = [self pageIndexByAdding:+1 from:self.currentPage]; 226 | if (prevPage == nextPage) { 227 | // This happends when our scrollview have only two and we should have the same prev/next page at left/right 228 | // A single UIView instance can't be in two different location at the same moment so we need to place it 229 | // loooking at proposed direction 230 | [self loadControllerAtIndex:prevPage andPlaceAtIndex:(proposedScroll == DMLazyScrollViewScrollDirectionBackward ? -1 : 1)]; 231 | } 232 | 233 | if ( (proposedScroll == DMLazyScrollViewScrollDirectionBackward && !canScrollBackward) || 234 | (proposedScroll == DMLazyScrollViewScrollDirectionForward && !canScrollForward)) { 235 | self.bounces = NO; 236 | [scrollView setContentOffset:[self createPoint:size*2] animated:NO]; 237 | return; 238 | } else self.bounces = YES; 239 | 240 | NSInteger newPageIndex = currentPage; 241 | 242 | if (offset <= size) 243 | newPageIndex = [self pageIndexByAdding:-1 from:currentPage]; 244 | else if (offset >= (size*3)) 245 | newPageIndex = [self pageIndexByAdding:+1 from:currentPage]; 246 | 247 | [self setCurrentViewController:newPageIndex]; 248 | 249 | // alert delegate 250 | if (nil != controlDelegate && [controlDelegate respondsToSelector:@selector(lazyScrollViewDidScroll:at:withSelfDrivenAnimation:)]) { 251 | [controlDelegate lazyScrollViewDidScroll:self at:[self visibleRect].origin withSelfDrivenAnimation:NO]; 252 | } 253 | else if (nil != controlDelegate && [controlDelegate respondsToSelector:@selector(lazyScrollViewDidScroll:at:)]) { 254 | [controlDelegate lazyScrollViewDidScroll:self at:[self visibleRect].origin]; 255 | } 256 | } 257 | 258 | - (void) setCurrentViewController:(NSInteger) index { 259 | if (index == currentPage) return; 260 | currentPage = index; 261 | 262 | [self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; 263 | 264 | NSInteger prevPage = [self pageIndexByAdding:-1 from:currentPage]; 265 | NSInteger nextPage = [self pageIndexByAdding:+1 from:currentPage]; 266 | 267 | [self loadControllerAtIndex:index andPlaceAtIndex:0]; 268 | // Pre-load the content for the adjacent pages if multiple pages are to be displayed 269 | if ([self hasMultiplePages]) { 270 | [self loadControllerAtIndex:prevPage andPlaceAtIndex:-1]; // load previous page 271 | [self loadControllerAtIndex:nextPage andPlaceAtIndex:1]; // load next page 272 | } 273 | 274 | CGFloat size =(_direction==DMLazyScrollViewDirectionHorizontal) ? self.frame.size.width : self.frame.size.height; 275 | 276 | self.contentOffset = [self createPoint:size * ([self hasMultiplePages] ? 2 : 0)]; // recenter 277 | 278 | if ([self.controlDelegate respondsToSelector:@selector(lazyScrollView:currentPageChanged:)]) 279 | [self.controlDelegate lazyScrollView:self currentPageChanged:self.currentPage]; 280 | } 281 | 282 | - (UIViewController *) visibleViewController { 283 | __block UIView *visibleView = nil; 284 | [self.subviews enumerateObjectsUsingBlock:^(UIView *subView, NSUInteger idx, BOOL *stop) { 285 | if (CGRectIntersectsRect([self visibleRect], subView.frame)) { 286 | visibleView = subView; 287 | *stop = YES; 288 | } 289 | }]; 290 | if (visibleView == nil) return nil; 291 | return [self viewControllerFromView:visibleView]; 292 | } 293 | 294 | - (UIViewController *) viewControllerFromView:(UIView*) targetView { 295 | return (UIViewController *)[self traverseResponderChainForUIViewController:targetView]; 296 | } 297 | 298 | - (id) traverseResponderChainForUIViewController:(UIView *) targetView { 299 | id nextResponder = [targetView nextResponder]; 300 | if ([nextResponder isKindOfClass:[UIViewController class]]) { 301 | return nextResponder; 302 | } else if ([nextResponder isKindOfClass:[UIView class]]) { 303 | return [nextResponder traverseResponderChainForUIViewController:targetView]; 304 | } else { 305 | return nil; 306 | } 307 | } 308 | 309 | - (NSInteger) pageIndexByAdding:(NSInteger) offset from:(NSInteger) index { 310 | // Complicated stuff with negative modulo 311 | while (offset<0) offset += numberOfPages; 312 | return (numberOfPages+index+offset) % numberOfPages; 313 | 314 | } 315 | 316 | - (void) moveByPages:(NSInteger) offset animated:(BOOL) animated { 317 | NSUInteger finalIndex = [self pageIndexByAdding:offset from:self.currentPage]; 318 | DMLazyScrollViewTransition transition = (offset >= 0 ? DMLazyScrollViewTransitionForward : 319 | DMLazyScrollViewTransitionBackward); 320 | [self setPage:finalIndex transition:transition animated:animated]; 321 | } 322 | 323 | - (void) setPage:(NSInteger) newIndex animated:(BOOL) animated { 324 | [self setPage:newIndex transition:DMLazyScrollViewTransitionForward animated:animated]; 325 | } 326 | 327 | - (void) setPage:(NSInteger) newIndex transition:(DMLazyScrollViewTransition) transition animated:(BOOL) animated { 328 | if (newIndex == currentPage) return; 329 | 330 | if (animated) { 331 | //BOOL isOnePageMove = (abs(self.currentPage-newIndex) == 1); 332 | CGPoint finalOffset; 333 | 334 | if (transition == DMLazyScrollViewTransitionAuto) { 335 | if (newIndex > self.currentPage) transition = DMLazyScrollViewTransitionForward; 336 | else if (newIndex < self.currentPage) transition = DMLazyScrollViewTransitionBackward; 337 | } 338 | 339 | CGFloat size =(_direction==DMLazyScrollViewDirectionHorizontal) ? self.frame.size.width : self.frame.size.height; 340 | 341 | if (transition == DMLazyScrollViewTransitionForward) { 342 | //if (!isOnePageMove) 343 | //[self loadControllerAtIndex:newIndex andPlaceAtIndex:2]; 344 | [self loadControllerAtIndex:newIndex andPlaceAtIndex:1]; 345 | 346 | //finalOffset = [self createPoint:(size*(isOnePageMove ? 3 : 4))]; 347 | finalOffset = [self createPoint:(size*3)]; 348 | } else { 349 | //if (!isOnePageMove) 350 | //[self loadControllerAtIndex:newIndex andPlaceAtIndex:-2]; 351 | [self loadControllerAtIndex:newIndex andPlaceAtIndex:-1]; 352 | 353 | //finalOffset = [self createPoint:(size*(isOnePageMove ? 1 : 0))]; 354 | finalOffset = [self createPoint:(size*1)]; 355 | } 356 | isManualAnimating = YES; 357 | 358 | [UIView animateWithDuration:kDMLazyScrollViewTransitionDuration 359 | delay:0.0 360 | options:UIViewAnimationOptionCurveEaseInOut 361 | animations:^{ 362 | self.contentOffset = finalOffset; 363 | } completion:^(BOOL finished) { 364 | if (!finished) return; 365 | [self setCurrentViewController:newIndex]; 366 | isManualAnimating = NO; 367 | }]; 368 | } else { 369 | [self setCurrentViewController:newIndex]; 370 | } 371 | } 372 | 373 | - (void) setCurrentPage:(NSUInteger)newCurrentPage { 374 | [self setCurrentViewController:newCurrentPage]; 375 | } 376 | 377 | - (UIViewController *) loadControllerAtIndex:(NSInteger) index andPlaceAtIndex:(NSInteger) destIndex { 378 | UIViewController *viewController = dataSource(index); 379 | viewController.view.tag = 0; 380 | 381 | CGRect viewFrame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.height); 382 | int offset = [self hasMultiplePages] ? 2 : 0; 383 | if (_direction == DMLazyScrollViewDirectionHorizontal) { 384 | viewFrame = CGRectOffset(viewFrame, self.frame.size.width * (destIndex + offset), 0); 385 | } else { 386 | viewFrame = CGRectOffset(viewFrame, 0, self.frame.size.height * (destIndex + offset)); 387 | } 388 | viewController.view.frame = viewFrame; 389 | 390 | [self addSubview:viewController.view]; 391 | return viewController; 392 | } 393 | 394 | 395 | - (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView { 396 | if (nil != controlDelegate && [controlDelegate respondsToSelector:@selector(lazyScrollViewWillBeginDecelerating:)]) 397 | [controlDelegate lazyScrollViewWillBeginDecelerating:self]; 398 | } 399 | 400 | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 401 | if (nil != controlDelegate && [controlDelegate respondsToSelector:@selector(lazyScrollViewDidEndDecelerating:atPageIndex:)]) 402 | [controlDelegate lazyScrollViewDidEndDecelerating:self atPageIndex:self.currentPage]; 403 | } 404 | 405 | 406 | @end 407 | -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollViewExample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 64E7A2831660D05F00DB5D9E /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 64E7A2821660D05F00DB5D9E /* UIKit.framework */; }; 11 | 64E7A2851660D05F00DB5D9E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 64E7A2841660D05F00DB5D9E /* Foundation.framework */; }; 12 | 64E7A2871660D05F00DB5D9E /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 64E7A2861660D05F00DB5D9E /* CoreGraphics.framework */; }; 13 | 64E7A28D1660D05F00DB5D9E /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 64E7A28B1660D05F00DB5D9E /* InfoPlist.strings */; }; 14 | 64E7A28F1660D05F00DB5D9E /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 64E7A28E1660D05F00DB5D9E /* main.m */; }; 15 | 64E7A2931660D06000DB5D9E /* DMAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 64E7A2921660D06000DB5D9E /* DMAppDelegate.m */; }; 16 | 64E7A2951660D06000DB5D9E /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 64E7A2941660D06000DB5D9E /* Default.png */; }; 17 | 64E7A2971660D06000DB5D9E /* Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 64E7A2961660D06000DB5D9E /* Default@2x.png */; }; 18 | 64E7A2991660D06000DB5D9E /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 64E7A2981660D06000DB5D9E /* Default-568h@2x.png */; }; 19 | 64E7A29C1660D06000DB5D9E /* DMViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 64E7A29B1660D06000DB5D9E /* DMViewController.m */; }; 20 | 64E7A29F1660D06000DB5D9E /* DMViewController_iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = 64E7A29D1660D06000DB5D9E /* DMViewController_iPhone.xib */; }; 21 | 64E7A2A21660D06000DB5D9E /* DMViewController_iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 64E7A2A01660D06000DB5D9E /* DMViewController_iPad.xib */; }; 22 | 64E7A2AA1660D06F00DB5D9E /* DMLazyScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = 64E7A2A91660D06F00DB5D9E /* DMLazyScrollView.m */; }; 23 | /* End PBXBuildFile section */ 24 | 25 | /* Begin PBXFileReference section */ 26 | 64E7A27E1660D05F00DB5D9E /* DMLazyScrollViewExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DMLazyScrollViewExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 27 | 64E7A2821660D05F00DB5D9E /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 28 | 64E7A2841660D05F00DB5D9E /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 29 | 64E7A2861660D05F00DB5D9E /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 30 | 64E7A28A1660D05F00DB5D9E /* DMLazyScrollViewExample-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "DMLazyScrollViewExample-Info.plist"; sourceTree = ""; }; 31 | 64E7A28C1660D05F00DB5D9E /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 32 | 64E7A28E1660D05F00DB5D9E /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 33 | 64E7A2901660D06000DB5D9E /* DMLazyScrollViewExample-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "DMLazyScrollViewExample-Prefix.pch"; sourceTree = ""; }; 34 | 64E7A2911660D06000DB5D9E /* DMAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DMAppDelegate.h; sourceTree = ""; }; 35 | 64E7A2921660D06000DB5D9E /* DMAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DMAppDelegate.m; sourceTree = ""; }; 36 | 64E7A2941660D06000DB5D9E /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = ""; }; 37 | 64E7A2961660D06000DB5D9E /* Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default@2x.png"; sourceTree = ""; }; 38 | 64E7A2981660D06000DB5D9E /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 39 | 64E7A29A1660D06000DB5D9E /* DMViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DMViewController.h; sourceTree = ""; }; 40 | 64E7A29B1660D06000DB5D9E /* DMViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DMViewController.m; sourceTree = ""; }; 41 | 64E7A29E1660D06000DB5D9E /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/DMViewController_iPhone.xib; sourceTree = ""; }; 42 | 64E7A2A11660D06000DB5D9E /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/DMViewController_iPad.xib; sourceTree = ""; }; 43 | 64E7A2A81660D06F00DB5D9E /* DMLazyScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DMLazyScrollView.h; path = DMLazyScrollView/DMLazyScrollView.h; sourceTree = ""; }; 44 | 64E7A2A91660D06F00DB5D9E /* DMLazyScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DMLazyScrollView.m; path = DMLazyScrollView/DMLazyScrollView.m; sourceTree = ""; }; 45 | /* End PBXFileReference section */ 46 | 47 | /* Begin PBXFrameworksBuildPhase section */ 48 | 64E7A27B1660D05F00DB5D9E /* Frameworks */ = { 49 | isa = PBXFrameworksBuildPhase; 50 | buildActionMask = 2147483647; 51 | files = ( 52 | 64E7A2831660D05F00DB5D9E /* UIKit.framework in Frameworks */, 53 | 64E7A2851660D05F00DB5D9E /* Foundation.framework in Frameworks */, 54 | 64E7A2871660D05F00DB5D9E /* CoreGraphics.framework in Frameworks */, 55 | ); 56 | runOnlyForDeploymentPostprocessing = 0; 57 | }; 58 | /* End PBXFrameworksBuildPhase section */ 59 | 60 | /* Begin PBXGroup section */ 61 | 64E7A2731660D05F00DB5D9E = { 62 | isa = PBXGroup; 63 | children = ( 64 | 64E7A2881660D05F00DB5D9E /* DMLazyScrollViewExample */, 65 | 64E7A2811660D05F00DB5D9E /* Frameworks */, 66 | 64E7A27F1660D05F00DB5D9E /* Products */, 67 | ); 68 | sourceTree = ""; 69 | }; 70 | 64E7A27F1660D05F00DB5D9E /* Products */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | 64E7A27E1660D05F00DB5D9E /* DMLazyScrollViewExample.app */, 74 | ); 75 | name = Products; 76 | sourceTree = ""; 77 | }; 78 | 64E7A2811660D05F00DB5D9E /* Frameworks */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 64E7A2821660D05F00DB5D9E /* UIKit.framework */, 82 | 64E7A2841660D05F00DB5D9E /* Foundation.framework */, 83 | 64E7A2861660D05F00DB5D9E /* CoreGraphics.framework */, 84 | ); 85 | name = Frameworks; 86 | sourceTree = ""; 87 | }; 88 | 64E7A2881660D05F00DB5D9E /* DMLazyScrollViewExample */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | 64E7A2911660D06000DB5D9E /* DMAppDelegate.h */, 92 | 64E7A2921660D06000DB5D9E /* DMAppDelegate.m */, 93 | 64E7A2C0166182AE00DB5D9E /* View Controller */, 94 | 64E7A2BF166182A400DB5D9E /* DMLazyScrollView */, 95 | 64E7A2891660D05F00DB5D9E /* Supporting Files */, 96 | ); 97 | path = DMLazyScrollViewExample; 98 | sourceTree = ""; 99 | }; 100 | 64E7A2891660D05F00DB5D9E /* Supporting Files */ = { 101 | isa = PBXGroup; 102 | children = ( 103 | 64E7A28A1660D05F00DB5D9E /* DMLazyScrollViewExample-Info.plist */, 104 | 64E7A28B1660D05F00DB5D9E /* InfoPlist.strings */, 105 | 64E7A28E1660D05F00DB5D9E /* main.m */, 106 | 64E7A2901660D06000DB5D9E /* DMLazyScrollViewExample-Prefix.pch */, 107 | 64E7A2941660D06000DB5D9E /* Default.png */, 108 | 64E7A2961660D06000DB5D9E /* Default@2x.png */, 109 | 64E7A2981660D06000DB5D9E /* Default-568h@2x.png */, 110 | ); 111 | name = "Supporting Files"; 112 | sourceTree = ""; 113 | }; 114 | 64E7A2BF166182A400DB5D9E /* DMLazyScrollView */ = { 115 | isa = PBXGroup; 116 | children = ( 117 | 64E7A2A81660D06F00DB5D9E /* DMLazyScrollView.h */, 118 | 64E7A2A91660D06F00DB5D9E /* DMLazyScrollView.m */, 119 | ); 120 | name = DMLazyScrollView; 121 | path = ..; 122 | sourceTree = ""; 123 | }; 124 | 64E7A2C0166182AE00DB5D9E /* View Controller */ = { 125 | isa = PBXGroup; 126 | children = ( 127 | 64E7A29A1660D06000DB5D9E /* DMViewController.h */, 128 | 64E7A29B1660D06000DB5D9E /* DMViewController.m */, 129 | 64E7A29D1660D06000DB5D9E /* DMViewController_iPhone.xib */, 130 | 64E7A2A01660D06000DB5D9E /* DMViewController_iPad.xib */, 131 | ); 132 | name = "View Controller"; 133 | sourceTree = ""; 134 | }; 135 | /* End PBXGroup section */ 136 | 137 | /* Begin PBXNativeTarget section */ 138 | 64E7A27D1660D05F00DB5D9E /* DMLazyScrollViewExample */ = { 139 | isa = PBXNativeTarget; 140 | buildConfigurationList = 64E7A2A51660D06000DB5D9E /* Build configuration list for PBXNativeTarget "DMLazyScrollViewExample" */; 141 | buildPhases = ( 142 | 64E7A27A1660D05F00DB5D9E /* Sources */, 143 | 64E7A27B1660D05F00DB5D9E /* Frameworks */, 144 | 64E7A27C1660D05F00DB5D9E /* Resources */, 145 | ); 146 | buildRules = ( 147 | ); 148 | dependencies = ( 149 | ); 150 | name = DMLazyScrollViewExample; 151 | productName = DMLazyScrollViewExample; 152 | productReference = 64E7A27E1660D05F00DB5D9E /* DMLazyScrollViewExample.app */; 153 | productType = "com.apple.product-type.application"; 154 | }; 155 | /* End PBXNativeTarget section */ 156 | 157 | /* Begin PBXProject section */ 158 | 64E7A2751660D05F00DB5D9E /* Project object */ = { 159 | isa = PBXProject; 160 | attributes = { 161 | CLASSPREFIX = DM; 162 | LastUpgradeCheck = 0450; 163 | ORGANIZATIONNAME = daniele; 164 | }; 165 | buildConfigurationList = 64E7A2781660D05F00DB5D9E /* Build configuration list for PBXProject "DMLazyScrollViewExample" */; 166 | compatibilityVersion = "Xcode 3.2"; 167 | developmentRegion = English; 168 | hasScannedForEncodings = 0; 169 | knownRegions = ( 170 | en, 171 | ); 172 | mainGroup = 64E7A2731660D05F00DB5D9E; 173 | productRefGroup = 64E7A27F1660D05F00DB5D9E /* Products */; 174 | projectDirPath = ""; 175 | projectRoot = ""; 176 | targets = ( 177 | 64E7A27D1660D05F00DB5D9E /* DMLazyScrollViewExample */, 178 | ); 179 | }; 180 | /* End PBXProject section */ 181 | 182 | /* Begin PBXResourcesBuildPhase section */ 183 | 64E7A27C1660D05F00DB5D9E /* Resources */ = { 184 | isa = PBXResourcesBuildPhase; 185 | buildActionMask = 2147483647; 186 | files = ( 187 | 64E7A28D1660D05F00DB5D9E /* InfoPlist.strings in Resources */, 188 | 64E7A2951660D06000DB5D9E /* Default.png in Resources */, 189 | 64E7A2971660D06000DB5D9E /* Default@2x.png in Resources */, 190 | 64E7A2991660D06000DB5D9E /* Default-568h@2x.png in Resources */, 191 | 64E7A29F1660D06000DB5D9E /* DMViewController_iPhone.xib in Resources */, 192 | 64E7A2A21660D06000DB5D9E /* DMViewController_iPad.xib in Resources */, 193 | ); 194 | runOnlyForDeploymentPostprocessing = 0; 195 | }; 196 | /* End PBXResourcesBuildPhase section */ 197 | 198 | /* Begin PBXSourcesBuildPhase section */ 199 | 64E7A27A1660D05F00DB5D9E /* Sources */ = { 200 | isa = PBXSourcesBuildPhase; 201 | buildActionMask = 2147483647; 202 | files = ( 203 | 64E7A28F1660D05F00DB5D9E /* main.m in Sources */, 204 | 64E7A2931660D06000DB5D9E /* DMAppDelegate.m in Sources */, 205 | 64E7A29C1660D06000DB5D9E /* DMViewController.m in Sources */, 206 | 64E7A2AA1660D06F00DB5D9E /* DMLazyScrollView.m in Sources */, 207 | ); 208 | runOnlyForDeploymentPostprocessing = 0; 209 | }; 210 | /* End PBXSourcesBuildPhase section */ 211 | 212 | /* Begin PBXVariantGroup section */ 213 | 64E7A28B1660D05F00DB5D9E /* InfoPlist.strings */ = { 214 | isa = PBXVariantGroup; 215 | children = ( 216 | 64E7A28C1660D05F00DB5D9E /* en */, 217 | ); 218 | name = InfoPlist.strings; 219 | sourceTree = ""; 220 | }; 221 | 64E7A29D1660D06000DB5D9E /* DMViewController_iPhone.xib */ = { 222 | isa = PBXVariantGroup; 223 | children = ( 224 | 64E7A29E1660D06000DB5D9E /* en */, 225 | ); 226 | name = DMViewController_iPhone.xib; 227 | sourceTree = ""; 228 | }; 229 | 64E7A2A01660D06000DB5D9E /* DMViewController_iPad.xib */ = { 230 | isa = PBXVariantGroup; 231 | children = ( 232 | 64E7A2A11660D06000DB5D9E /* en */, 233 | ); 234 | name = DMViewController_iPad.xib; 235 | sourceTree = ""; 236 | }; 237 | /* End PBXVariantGroup section */ 238 | 239 | /* Begin XCBuildConfiguration section */ 240 | 64E7A2A31660D06000DB5D9E /* Debug */ = { 241 | isa = XCBuildConfiguration; 242 | buildSettings = { 243 | ALWAYS_SEARCH_USER_PATHS = NO; 244 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 245 | CLANG_CXX_LIBRARY = "libc++"; 246 | CLANG_ENABLE_OBJC_ARC = YES; 247 | CLANG_WARN_EMPTY_BODY = YES; 248 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 249 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 250 | COPY_PHASE_STRIP = NO; 251 | GCC_C_LANGUAGE_STANDARD = gnu99; 252 | GCC_DYNAMIC_NO_PIC = NO; 253 | GCC_OPTIMIZATION_LEVEL = 0; 254 | GCC_PREPROCESSOR_DEFINITIONS = ( 255 | "DEBUG=1", 256 | "$(inherited)", 257 | ); 258 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 259 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 260 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 261 | GCC_WARN_UNUSED_VARIABLE = YES; 262 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 263 | ONLY_ACTIVE_ARCH = YES; 264 | SDKROOT = iphoneos; 265 | TARGETED_DEVICE_FAMILY = "1,2"; 266 | }; 267 | name = Debug; 268 | }; 269 | 64E7A2A41660D06000DB5D9E /* Release */ = { 270 | isa = XCBuildConfiguration; 271 | buildSettings = { 272 | ALWAYS_SEARCH_USER_PATHS = NO; 273 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 274 | CLANG_CXX_LIBRARY = "libc++"; 275 | CLANG_ENABLE_OBJC_ARC = YES; 276 | CLANG_WARN_EMPTY_BODY = YES; 277 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 278 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 279 | COPY_PHASE_STRIP = YES; 280 | GCC_C_LANGUAGE_STANDARD = gnu99; 281 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 282 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 283 | GCC_WARN_UNUSED_VARIABLE = YES; 284 | IPHONEOS_DEPLOYMENT_TARGET = 6.0; 285 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 286 | SDKROOT = iphoneos; 287 | TARGETED_DEVICE_FAMILY = "1,2"; 288 | VALIDATE_PRODUCT = YES; 289 | }; 290 | name = Release; 291 | }; 292 | 64E7A2A61660D06000DB5D9E /* Debug */ = { 293 | isa = XCBuildConfiguration; 294 | buildSettings = { 295 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 296 | GCC_PREFIX_HEADER = "DMLazyScrollViewExample/DMLazyScrollViewExample-Prefix.pch"; 297 | INFOPLIST_FILE = "DMLazyScrollViewExample/DMLazyScrollViewExample-Info.plist"; 298 | PRODUCT_NAME = "$(TARGET_NAME)"; 299 | WRAPPER_EXTENSION = app; 300 | }; 301 | name = Debug; 302 | }; 303 | 64E7A2A71660D06000DB5D9E /* Release */ = { 304 | isa = XCBuildConfiguration; 305 | buildSettings = { 306 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 307 | GCC_PREFIX_HEADER = "DMLazyScrollViewExample/DMLazyScrollViewExample-Prefix.pch"; 308 | INFOPLIST_FILE = "DMLazyScrollViewExample/DMLazyScrollViewExample-Info.plist"; 309 | PRODUCT_NAME = "$(TARGET_NAME)"; 310 | WRAPPER_EXTENSION = app; 311 | }; 312 | name = Release; 313 | }; 314 | /* End XCBuildConfiguration section */ 315 | 316 | /* Begin XCConfigurationList section */ 317 | 64E7A2781660D05F00DB5D9E /* Build configuration list for PBXProject "DMLazyScrollViewExample" */ = { 318 | isa = XCConfigurationList; 319 | buildConfigurations = ( 320 | 64E7A2A31660D06000DB5D9E /* Debug */, 321 | 64E7A2A41660D06000DB5D9E /* Release */, 322 | ); 323 | defaultConfigurationIsVisible = 0; 324 | defaultConfigurationName = Release; 325 | }; 326 | 64E7A2A51660D06000DB5D9E /* Build configuration list for PBXNativeTarget "DMLazyScrollViewExample" */ = { 327 | isa = XCConfigurationList; 328 | buildConfigurations = ( 329 | 64E7A2A61660D06000DB5D9E /* Debug */, 330 | 64E7A2A71660D06000DB5D9E /* Release */, 331 | ); 332 | defaultConfigurationIsVisible = 0; 333 | }; 334 | /* End XCConfigurationList section */ 335 | }; 336 | rootObject = 64E7A2751660D05F00DB5D9E /* Project object */; 337 | } 338 | -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollViewExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollViewExample.xcodeproj/project.xcworkspace/xcuserdata/daniele.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malcommac/DMLazyScrollView/865bf3112b650bf83bcf125f82197256a7418252/DMLazyScrollViewExample/DMLazyScrollViewExample.xcodeproj/project.xcworkspace/xcuserdata/daniele.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollViewExample.xcodeproj/project.xcworkspace/xcuserdata/daniele.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 6 | 7 | SnapshotAutomaticallyBeforeSignificantChanges 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollViewExample.xcodeproj/project.xcworkspace/xcuserdata/jack.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malcommac/DMLazyScrollView/865bf3112b650bf83bcf125f82197256a7418252/DMLazyScrollViewExample/DMLazyScrollViewExample.xcodeproj/project.xcworkspace/xcuserdata/jack.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollViewExample.xcodeproj/xcuserdata/daniele.xcuserdatad/xcdebugger/Breakpoints.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollViewExample.xcodeproj/xcuserdata/daniele.xcuserdatad/xcschemes/DMLazyScrollViewExample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollViewExample.xcodeproj/xcuserdata/daniele.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | DMLazyScrollViewExample.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 64E7A27D1660D05F00DB5D9E 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollViewExample.xcodeproj/xcuserdata/jack.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollViewExample.xcodeproj/xcuserdata/jack.xcuserdatad/xcschemes/DMLazyScrollViewExample.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 51 | 52 | 58 | 59 | 60 | 61 | 62 | 63 | 69 | 70 | 76 | 77 | 78 | 79 | 81 | 82 | 85 | 86 | 87 | -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollViewExample.xcodeproj/xcuserdata/jack.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | DMLazyScrollViewExample.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 64E7A27D1660D05F00DB5D9E 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollViewExample/DMAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // DMAppDelegate.h 3 | // DMLazyScrollViewExample 4 | // 5 | // Created by Daniele Margutti (me@danielemargutti.com) on 24/11/12. 6 | // Copyright (c) 2012 http://www.danielemargutti.com. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class DMViewController; 12 | 13 | @interface DMAppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | 17 | @property (strong, nonatomic) DMViewController *viewController; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollViewExample/DMAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // DMAppDelegate.m 3 | // DMLazyScrollViewExample 4 | // 5 | // Created by Daniele Margutti (me@danielemargutti.com) on 24/11/12. 6 | // Copyright (c) 2012 http://www.danielemargutti.com. All rights reserved. 7 | // 8 | 9 | #import "DMAppDelegate.h" 10 | 11 | #import "DMViewController.h" 12 | 13 | @implementation DMAppDelegate 14 | 15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 16 | { 17 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 18 | // Override point for customization after application launch. 19 | if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { 20 | self.viewController = [[DMViewController alloc] initWithNibName:@"DMViewController_iPhone" bundle:nil]; 21 | } else { 22 | self.viewController = [[DMViewController alloc] initWithNibName:@"DMViewController_iPad" bundle:nil]; 23 | } 24 | self.window.rootViewController = self.viewController; 25 | [self.window makeKeyAndVisible]; 26 | return YES; 27 | } 28 | 29 | - (void)applicationWillResignActive:(UIApplication *)application 30 | { 31 | // 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. 32 | // 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. 33 | } 34 | 35 | - (void)applicationDidEnterBackground:(UIApplication *)application 36 | { 37 | // 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. 38 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 39 | } 40 | 41 | - (void)applicationWillEnterForeground:(UIApplication *)application 42 | { 43 | // 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. 44 | } 45 | 46 | - (void)applicationDidBecomeActive:(UIApplication *)application 47 | { 48 | // 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. 49 | } 50 | 51 | - (void)applicationWillTerminate:(UIApplication *)application 52 | { 53 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 54 | } 55 | 56 | @end 57 | -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollViewExample/DMLazyScrollViewExample-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | danielemargutti.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollViewExample/DMLazyScrollViewExample-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'DMLazyScrollViewExample' target in the 'DMLazyScrollViewExample' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_4_0 8 | #warning "This project uses features only available in iOS SDK 4.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollViewExample/DMViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // DMViewController.h 3 | // DMLazyScrollViewExample 4 | // 5 | // Created by Daniele Margutti (me@danielemargutti.com) on 24/11/12. 6 | // Copyright (c) 2012 http://www.danielemargutti.com. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DMViewController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollViewExample/DMViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // DMViewController.m 3 | // DMLazyScrollViewExample 4 | // 5 | // Created by Daniele Margutti (me@danielemargutti.com) on 24/11/12. 6 | // Copyright (c) 2012 http://www.danielemargutti.com. All rights reserved. 7 | // 8 | 9 | #import "DMViewController.h" 10 | #import "DMLazyScrollView.h" 11 | 12 | #define ARC4RANDOM_MAX 0x100000000 13 | 14 | 15 | @interface DMViewController () { 16 | DMLazyScrollView* lazyScrollView; 17 | NSMutableArray* viewControllerArray; 18 | } 19 | @end 20 | 21 | @implementation DMViewController 22 | 23 | - (void)viewDidLoad { 24 | [super viewDidLoad]; 25 | 26 | // PREPARE PAGES 27 | NSUInteger numberOfPages = 10; 28 | viewControllerArray = [[NSMutableArray alloc] initWithCapacity:numberOfPages]; 29 | for (NSUInteger k = 0; k < numberOfPages; ++k) { 30 | [viewControllerArray addObject:[NSNull null]]; 31 | } 32 | 33 | // PREPARE LAZY VIEW 34 | CGRect rect = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height-50); 35 | lazyScrollView = [[DMLazyScrollView alloc] initWithFrame:rect]; 36 | [lazyScrollView setEnableCircularScroll:YES]; 37 | [lazyScrollView setAutoPlay:YES]; 38 | 39 | __weak __typeof(&*self)weakSelf = self; 40 | lazyScrollView.dataSource = ^(NSUInteger index) { 41 | return [weakSelf controllerAtIndex:index]; 42 | }; 43 | lazyScrollView.numberOfPages = numberOfPages; 44 | // lazyScrollView.controlDelegate = self; 45 | [self.view addSubview:lazyScrollView]; 46 | 47 | // MOVE BY 3 FORWARD 48 | UIButton*btn_moveForward = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 49 | [btn_moveForward setTitle:@"MOVE BY 3" forState:UIControlStateNormal]; 50 | [btn_moveForward addTarget:self action:@selector(btn_moveForward:) forControlEvents:UIControlEventTouchUpInside]; 51 | [btn_moveForward setFrame:CGRectMake(self.view.frame.size.width/2.0f,lazyScrollView.frame.origin.y+lazyScrollView.frame.size.height+5, 320/2.0f,40)]; 52 | [self.view addSubview:btn_moveForward]; 53 | 54 | // MOVE BY -3 BACKWARD 55 | UIButton*btn_moveBackward = [UIButton buttonWithType:UIButtonTypeRoundedRect]; 56 | [btn_moveBackward setTitle:@"MOVE BY -3" forState:UIControlStateNormal]; 57 | [btn_moveBackward addTarget:self action:@selector(btn_moveBack:) forControlEvents:UIControlEventTouchUpInside]; 58 | [btn_moveBackward setFrame:CGRectMake(0,lazyScrollView.frame.origin.y+lazyScrollView.frame.size.height+5, 320/2.0f,40)]; 59 | [self.view addSubview:btn_moveBackward]; 60 | // Do any additional setup after loading the view, typically from a nib. 61 | } 62 | 63 | - (void) btn_moveBack:(id) sender { 64 | [lazyScrollView moveByPages:-3 animated:YES]; 65 | } 66 | 67 | - (void) btn_moveForward:(id) sender { 68 | [lazyScrollView moveByPages:3 animated:YES]; 69 | } 70 | 71 | - (void)didReceiveMemoryWarning { 72 | [super didReceiveMemoryWarning]; 73 | // Dispose of any resources that can be recreated. 74 | 75 | 76 | } 77 | 78 | - (UIViewController *) controllerAtIndex:(NSInteger) index { 79 | if (index > viewControllerArray.count || index < 0) return nil; 80 | id res = [viewControllerArray objectAtIndex:index]; 81 | if (res == [NSNull null]) { 82 | UIViewController *contr = [[UIViewController alloc] init]; 83 | contr.view.backgroundColor = [UIColor colorWithRed: (CGFloat)arc4random()/ARC4RANDOM_MAX 84 | green: (CGFloat)arc4random()/ARC4RANDOM_MAX 85 | blue: (CGFloat)arc4random()/ARC4RANDOM_MAX 86 | alpha: 1.0f]; 87 | 88 | UILabel* label = [[UILabel alloc] initWithFrame:contr.view.bounds]; 89 | label.backgroundColor = [UIColor clearColor]; 90 | label.text = [NSString stringWithFormat:@"%d",index]; 91 | label.textAlignment = NSTextAlignmentCenter; 92 | label.font = [UIFont boldSystemFontOfSize:50]; 93 | [contr.view addSubview:label]; 94 | 95 | [viewControllerArray replaceObjectAtIndex:index withObject:contr]; 96 | return contr; 97 | } 98 | return res; 99 | } 100 | 101 | /* 102 | - (void)lazyScrollViewDidEndDragging:(DMLazyScrollView *)pagingView { 103 | NSLog(@"Now visible: %@",lazyScrollView.visibleViewController); 104 | } 105 | */ 106 | @end 107 | -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollViewExample/Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malcommac/DMLazyScrollView/865bf3112b650bf83bcf125f82197256a7418252/DMLazyScrollViewExample/DMLazyScrollViewExample/Default-568h@2x.png -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollViewExample/Default.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malcommac/DMLazyScrollView/865bf3112b650bf83bcf125f82197256a7418252/DMLazyScrollViewExample/DMLazyScrollViewExample/Default.png -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollViewExample/Default@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/malcommac/DMLazyScrollView/865bf3112b650bf83bcf125f82197256a7418252/DMLazyScrollViewExample/DMLazyScrollViewExample/Default@2x.png -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollViewExample/en.lproj/DMViewController_iPad.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1536 5 | 12A206j 6 | 2519 7 | 1172.1 8 | 613.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 1856 12 | 13 | 14 | IBProxyObject 15 | IBUIView 16 | 17 | 18 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 19 | 20 | 21 | PluginDependencyRecalculationVersion 22 | 23 | 24 | 25 | 26 | IBFilesOwner 27 | IBIPadFramework 28 | 29 | 30 | IBFirstResponder 31 | IBIPadFramework 32 | 33 | 34 | 35 | 274 36 | {{0, 20}, {768, 1004}} 37 | 38 | 39 | 40 | 3 41 | MQA 42 | 43 | 2 44 | 45 | 46 | 47 | 2 48 | 49 | IBIPadFramework 50 | 51 | 52 | 53 | 54 | 55 | 56 | view 57 | 58 | 59 | 60 | 3 61 | 62 | 63 | 64 | 65 | 66 | 0 67 | 68 | 69 | 70 | 71 | 72 | -1 73 | 74 | 75 | File's Owner 76 | 77 | 78 | -2 79 | 80 | 81 | 82 | 83 | 2 84 | 85 | 86 | 87 | 88 | 89 | 90 | DMViewController 91 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 92 | UIResponder 93 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 94 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 95 | 96 | 97 | 98 | 99 | 100 | 3 101 | 102 | 103 | 104 | 105 | DMViewController 106 | UIViewController 107 | 108 | IBProjectSource 109 | ./Classes/DMViewController.h 110 | 111 | 112 | 113 | 114 | 0 115 | IBIPadFramework 116 | YES 117 | 3 118 | YES 119 | 1856 120 | 121 | 122 | -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollViewExample/en.lproj/DMViewController_iPhone.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 1536 5 | 12A269 6 | 2835 7 | 1187 8 | 624.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 1919 12 | 13 | 14 | IBProxyObject 15 | IBUIView 16 | 17 | 18 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 19 | 20 | 21 | PluginDependencyRecalculationVersion 22 | 23 | 24 | 25 | 26 | IBFilesOwner 27 | IBCocoaTouchFramework 28 | 29 | 30 | IBFirstResponder 31 | IBCocoaTouchFramework 32 | 33 | 34 | 35 | 274 36 | {{0, 20}, {320, 548}} 37 | 38 | 39 | 40 | 41 | 3 42 | MC43NQA 43 | 44 | 2 45 | 46 | 47 | NO 48 | 49 | 50 | IBUIScreenMetrics 51 | 52 | YES 53 | 54 | 55 | 56 | 57 | 58 | {320, 568} 59 | {568, 320} 60 | 61 | 62 | IBCocoaTouchFramework 63 | Retina 4 Full Screen 64 | 2 65 | 66 | IBCocoaTouchFramework 67 | 68 | 69 | 70 | 71 | 72 | 73 | view 74 | 75 | 76 | 77 | 7 78 | 79 | 80 | 81 | 82 | 83 | 0 84 | 85 | 86 | 87 | 88 | 89 | -1 90 | 91 | 92 | File's Owner 93 | 94 | 95 | -2 96 | 97 | 98 | 99 | 100 | 6 101 | 102 | 103 | 104 | 105 | 106 | 107 | DMViewController 108 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 109 | UIResponder 110 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 111 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 112 | 113 | 114 | 115 | 116 | 117 | 7 118 | 119 | 120 | 121 | 122 | DMViewController 123 | UIViewController 124 | 125 | IBProjectSource 126 | ./Classes/DMViewController.h 127 | 128 | 129 | 130 | 131 | 0 132 | IBCocoaTouchFramework 133 | YES 134 | 3 135 | YES 136 | 1919 137 | 138 | 139 | -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollViewExample/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /DMLazyScrollViewExample/DMLazyScrollViewExample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // DMLazyScrollViewExample 4 | // 5 | // Created by Daniele Margutti (me@danielemargutti.com) on 24/11/12. 6 | // Copyright (c) 2012 http://www.danielemargutti.com. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "DMAppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([DMAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DMLazyScrollView : Lazy Loading UIScrollView (with infinite page scrolling) 2 | ================ 3 | 4 | DMLazyScrollView for iOS (with support for infinite scrolling) allows you to create and endless (in both horizontal and vertical direction) UIScrollView organized in pages and load UIViews dynamically only when needed by reducing time and memory consumption. 5 | 6 | When you have lots of UIViews to show inside a scroll view you don't want to waste memory and time by creating a big UIScrollView content view, load all subviews at the same time and show them; it does not make sense and it's slow on older devices. 7 | 8 | DMLazyScrollView allows you to load lazily UIViews and animate page scrolling easily. You can use it to load images or entire views without pain. 9 | 10 | ![DMLazyScrollView Example Project](http://i.imgur.com/lhmdn.png) 11 | 12 | 13 | ## Donations 14 | 15 | If you found this project useful, please donate. 16 | There’s no expected amount and I don’t require you to. 17 | [MAKE YOUR DONATION](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=GS3DBQ69ZBKWJ) 18 | 19 | ## License (MIT) 20 | 21 | Copyright (c) 2012 Daniele Margutti 22 | 23 | Permission is hereby granted, free of charge, to any person 24 | obtaining a copy of this software and associated documentation 25 | files (the "Software"), to deal in the Software without 26 | restriction, including without limitation the rights to use, 27 | copy, modify, merge, publish, distribute, sublicense, and/or sell 28 | copies of the Software, and to permit persons to whom the 29 | Software is furnished to do so, subject to the following 30 | conditions: 31 | 32 | The above copyright notice and this permission notice shall be 33 | included in all copies or substantial portions of the Software. 34 | 35 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 36 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 37 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 38 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 39 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 40 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 41 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 42 | OTHER DEALINGS IN THE SOFTWARE. 43 | --------------------------------------------------------------------------------