├── .gitignore ├── LICENSE ├── PagedView.xcodeproj └── project.pbxproj ├── PagedView ├── DTLazyImageView.h ├── DTLazyImageView.m ├── JSONKit.h ├── JSONKit.m ├── PagedView-Info.plist ├── PagedView-Prefix.pch ├── PagedViewAppDelegate.h ├── PagedViewAppDelegate.m ├── PagedViewViewController.h ├── PagedViewViewController.m ├── RTSPagedView.h ├── RTSPagedView.m ├── en.lproj │ ├── InfoPlist.strings │ ├── MainWindow.xib │ └── PagedViewViewController.xib └── main.m └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | PagedView.xcodeproj/project.xcworkspace/contents.xcworkspacedata 3 | PagedView.xcodeproj/project.xcworkspace/xcuserdata/rits.xcuserdatad/UserInterfaceState.xcuserstate 4 | PagedView.xcodeproj/xcuserdata/rits.xcuserdatad/xcschemes/PagedView.xcscheme 5 | PagedView.xcodeproj/xcuserdata/rits.xcuserdatad/xcschemes/xcschememanagement.plist 6 | PagedView.xcodeproj/project.xcworkspace/xcuserdata/rits.xcuserdatad/WorkspaceSettings.xcsettings 7 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2011 Rits Plasman. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without modification, are 4 | permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this list of 7 | conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, this list 10 | of conditions and the following disclaimer in the documentation and/or other materials 11 | provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR IMPLIED 14 | WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 15 | FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 16 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 17 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 18 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 19 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 20 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 21 | ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 | 23 | The views and conclusions contained in the software and documentation are those of the 24 | authors and should not be interpreted as representing official policies, either expressed 25 | or implied, of the copyright holder. -------------------------------------------------------------------------------- /PagedView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 550D4043138A68EF005F5F30 /* JSONKit.m in Sources */ = {isa = PBXBuildFile; fileRef = 550D4042138A68EE005F5F30 /* JSONKit.m */; }; 11 | 550D4047138A7277005F5F30 /* DTLazyImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = 550D4046138A7277005F5F30 /* DTLazyImageView.m */; }; 12 | 55D33A621389C50900245167 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55D33A611389C50900245167 /* UIKit.framework */; }; 13 | 55D33A641389C50900245167 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55D33A631389C50900245167 /* Foundation.framework */; }; 14 | 55D33A661389C50900245167 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 55D33A651389C50900245167 /* CoreGraphics.framework */; }; 15 | 55D33A6C1389C50900245167 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 55D33A6A1389C50900245167 /* InfoPlist.strings */; }; 16 | 55D33A6F1389C50900245167 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 55D33A6E1389C50900245167 /* main.m */; }; 17 | 55D33A721389C50900245167 /* PagedViewAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 55D33A711389C50900245167 /* PagedViewAppDelegate.m */; }; 18 | 55D33A751389C50900245167 /* MainWindow.xib in Resources */ = {isa = PBXBuildFile; fileRef = 55D33A731389C50900245167 /* MainWindow.xib */; }; 19 | 55D33A781389C50900245167 /* PagedViewViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 55D33A771389C50900245167 /* PagedViewViewController.m */; }; 20 | 55D33A7B1389C50900245167 /* PagedViewViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 55D33A791389C50900245167 /* PagedViewViewController.xib */; }; 21 | 55D33A8B1389C58500245167 /* RTSPagedView.m in Sources */ = {isa = PBXBuildFile; fileRef = 55D33A8A1389C58500245167 /* RTSPagedView.m */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXFileReference section */ 25 | 550D4041138A68EE005F5F30 /* JSONKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSONKit.h; sourceTree = ""; }; 26 | 550D4042138A68EE005F5F30 /* JSONKit.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = JSONKit.m; sourceTree = ""; }; 27 | 550D4045138A7277005F5F30 /* DTLazyImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DTLazyImageView.h; sourceTree = ""; }; 28 | 550D4046138A7277005F5F30 /* DTLazyImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DTLazyImageView.m; sourceTree = ""; }; 29 | 55D33A5D1389C50900245167 /* PagedView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PagedView.app; sourceTree = BUILT_PRODUCTS_DIR; }; 30 | 55D33A611389C50900245167 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 31 | 55D33A631389C50900245167 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 32 | 55D33A651389C50900245167 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 33 | 55D33A691389C50900245167 /* PagedView-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "PagedView-Info.plist"; sourceTree = ""; }; 34 | 55D33A6B1389C50900245167 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 35 | 55D33A6D1389C50900245167 /* PagedView-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "PagedView-Prefix.pch"; sourceTree = ""; }; 36 | 55D33A6E1389C50900245167 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 37 | 55D33A701389C50900245167 /* PagedViewAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PagedViewAppDelegate.h; sourceTree = ""; }; 38 | 55D33A711389C50900245167 /* PagedViewAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PagedViewAppDelegate.m; sourceTree = ""; }; 39 | 55D33A741389C50900245167 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MainWindow.xib; sourceTree = ""; }; 40 | 55D33A761389C50900245167 /* PagedViewViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PagedViewViewController.h; sourceTree = ""; }; 41 | 55D33A771389C50900245167 /* PagedViewViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PagedViewViewController.m; sourceTree = ""; }; 42 | 55D33A7A1389C50900245167 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/PagedViewViewController.xib; sourceTree = ""; }; 43 | 55D33A891389C58500245167 /* RTSPagedView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RTSPagedView.h; sourceTree = ""; }; 44 | 55D33A8A1389C58500245167 /* RTSPagedView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RTSPagedView.m; sourceTree = ""; }; 45 | /* End PBXFileReference section */ 46 | 47 | /* Begin PBXFrameworksBuildPhase section */ 48 | 55D33A5A1389C50900245167 /* Frameworks */ = { 49 | isa = PBXFrameworksBuildPhase; 50 | buildActionMask = 2147483647; 51 | files = ( 52 | 55D33A621389C50900245167 /* UIKit.framework in Frameworks */, 53 | 55D33A641389C50900245167 /* Foundation.framework in Frameworks */, 54 | 55D33A661389C50900245167 /* CoreGraphics.framework in Frameworks */, 55 | ); 56 | runOnlyForDeploymentPostprocessing = 0; 57 | }; 58 | /* End PBXFrameworksBuildPhase section */ 59 | 60 | /* Begin PBXGroup section */ 61 | 55D33A521389C50900245167 = { 62 | isa = PBXGroup; 63 | children = ( 64 | 55D33A671389C50900245167 /* PagedView */, 65 | 55D33A601389C50900245167 /* Frameworks */, 66 | 55D33A5E1389C50900245167 /* Products */, 67 | ); 68 | sourceTree = ""; 69 | }; 70 | 55D33A5E1389C50900245167 /* Products */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | 55D33A5D1389C50900245167 /* PagedView.app */, 74 | ); 75 | name = Products; 76 | sourceTree = ""; 77 | }; 78 | 55D33A601389C50900245167 /* Frameworks */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 55D33A611389C50900245167 /* UIKit.framework */, 82 | 55D33A631389C50900245167 /* Foundation.framework */, 83 | 55D33A651389C50900245167 /* CoreGraphics.framework */, 84 | ); 85 | name = Frameworks; 86 | sourceTree = ""; 87 | }; 88 | 55D33A671389C50900245167 /* PagedView */ = { 89 | isa = PBXGroup; 90 | children = ( 91 | 55D33A701389C50900245167 /* PagedViewAppDelegate.h */, 92 | 55D33A711389C50900245167 /* PagedViewAppDelegate.m */, 93 | 55D33A891389C58500245167 /* RTSPagedView.h */, 94 | 55D33A8A1389C58500245167 /* RTSPagedView.m */, 95 | 550D4041138A68EE005F5F30 /* JSONKit.h */, 96 | 550D4042138A68EE005F5F30 /* JSONKit.m */, 97 | 550D4045138A7277005F5F30 /* DTLazyImageView.h */, 98 | 550D4046138A7277005F5F30 /* DTLazyImageView.m */, 99 | 55D33A731389C50900245167 /* MainWindow.xib */, 100 | 55D33A761389C50900245167 /* PagedViewViewController.h */, 101 | 55D33A771389C50900245167 /* PagedViewViewController.m */, 102 | 55D33A791389C50900245167 /* PagedViewViewController.xib */, 103 | 55D33A681389C50900245167 /* Supporting Files */, 104 | ); 105 | path = PagedView; 106 | sourceTree = ""; 107 | }; 108 | 55D33A681389C50900245167 /* Supporting Files */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | 55D33A691389C50900245167 /* PagedView-Info.plist */, 112 | 55D33A6A1389C50900245167 /* InfoPlist.strings */, 113 | 55D33A6D1389C50900245167 /* PagedView-Prefix.pch */, 114 | 55D33A6E1389C50900245167 /* main.m */, 115 | ); 116 | name = "Supporting Files"; 117 | sourceTree = ""; 118 | }; 119 | /* End PBXGroup section */ 120 | 121 | /* Begin PBXNativeTarget section */ 122 | 55D33A5C1389C50900245167 /* PagedView */ = { 123 | isa = PBXNativeTarget; 124 | buildConfigurationList = 55D33A7E1389C50900245167 /* Build configuration list for PBXNativeTarget "PagedView" */; 125 | buildPhases = ( 126 | 55D33A591389C50900245167 /* Sources */, 127 | 55D33A5A1389C50900245167 /* Frameworks */, 128 | 55D33A5B1389C50900245167 /* Resources */, 129 | ); 130 | buildRules = ( 131 | ); 132 | dependencies = ( 133 | ); 134 | name = PagedView; 135 | productName = PagedView; 136 | productReference = 55D33A5D1389C50900245167 /* PagedView.app */; 137 | productType = "com.apple.product-type.application"; 138 | }; 139 | /* End PBXNativeTarget section */ 140 | 141 | /* Begin PBXProject section */ 142 | 55D33A541389C50900245167 /* Project object */ = { 143 | isa = PBXProject; 144 | attributes = { 145 | ORGANIZATIONNAME = Taplicity; 146 | }; 147 | buildConfigurationList = 55D33A571389C50900245167 /* Build configuration list for PBXProject "PagedView" */; 148 | compatibilityVersion = "Xcode 3.2"; 149 | developmentRegion = English; 150 | hasScannedForEncodings = 0; 151 | knownRegions = ( 152 | en, 153 | ); 154 | mainGroup = 55D33A521389C50900245167; 155 | productRefGroup = 55D33A5E1389C50900245167 /* Products */; 156 | projectDirPath = ""; 157 | projectRoot = ""; 158 | targets = ( 159 | 55D33A5C1389C50900245167 /* PagedView */, 160 | ); 161 | }; 162 | /* End PBXProject section */ 163 | 164 | /* Begin PBXResourcesBuildPhase section */ 165 | 55D33A5B1389C50900245167 /* Resources */ = { 166 | isa = PBXResourcesBuildPhase; 167 | buildActionMask = 2147483647; 168 | files = ( 169 | 55D33A6C1389C50900245167 /* InfoPlist.strings in Resources */, 170 | 55D33A751389C50900245167 /* MainWindow.xib in Resources */, 171 | 55D33A7B1389C50900245167 /* PagedViewViewController.xib in Resources */, 172 | ); 173 | runOnlyForDeploymentPostprocessing = 0; 174 | }; 175 | /* End PBXResourcesBuildPhase section */ 176 | 177 | /* Begin PBXSourcesBuildPhase section */ 178 | 55D33A591389C50900245167 /* Sources */ = { 179 | isa = PBXSourcesBuildPhase; 180 | buildActionMask = 2147483647; 181 | files = ( 182 | 55D33A6F1389C50900245167 /* main.m in Sources */, 183 | 55D33A721389C50900245167 /* PagedViewAppDelegate.m in Sources */, 184 | 55D33A781389C50900245167 /* PagedViewViewController.m in Sources */, 185 | 55D33A8B1389C58500245167 /* RTSPagedView.m in Sources */, 186 | 550D4043138A68EF005F5F30 /* JSONKit.m in Sources */, 187 | 550D4047138A7277005F5F30 /* DTLazyImageView.m in Sources */, 188 | ); 189 | runOnlyForDeploymentPostprocessing = 0; 190 | }; 191 | /* End PBXSourcesBuildPhase section */ 192 | 193 | /* Begin PBXVariantGroup section */ 194 | 55D33A6A1389C50900245167 /* InfoPlist.strings */ = { 195 | isa = PBXVariantGroup; 196 | children = ( 197 | 55D33A6B1389C50900245167 /* en */, 198 | ); 199 | name = InfoPlist.strings; 200 | sourceTree = ""; 201 | }; 202 | 55D33A731389C50900245167 /* MainWindow.xib */ = { 203 | isa = PBXVariantGroup; 204 | children = ( 205 | 55D33A741389C50900245167 /* en */, 206 | ); 207 | name = MainWindow.xib; 208 | sourceTree = ""; 209 | }; 210 | 55D33A791389C50900245167 /* PagedViewViewController.xib */ = { 211 | isa = PBXVariantGroup; 212 | children = ( 213 | 55D33A7A1389C50900245167 /* en */, 214 | ); 215 | name = PagedViewViewController.xib; 216 | sourceTree = ""; 217 | }; 218 | /* End PBXVariantGroup section */ 219 | 220 | /* Begin XCBuildConfiguration section */ 221 | 55D33A7C1389C50900245167 /* Debug */ = { 222 | isa = XCBuildConfiguration; 223 | buildSettings = { 224 | ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; 225 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 226 | GCC_C_LANGUAGE_STANDARD = gnu99; 227 | GCC_OPTIMIZATION_LEVEL = 0; 228 | GCC_PREPROCESSOR_DEFINITIONS = DEBUG; 229 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 230 | GCC_VERSION = com.apple.compilers.llvmgcc42; 231 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 232 | GCC_WARN_UNUSED_VARIABLE = YES; 233 | IPHONEOS_DEPLOYMENT_TARGET = 4.3; 234 | SDKROOT = iphoneos; 235 | TARGETED_DEVICE_FAMILY = 2; 236 | }; 237 | name = Debug; 238 | }; 239 | 55D33A7D1389C50900245167 /* Release */ = { 240 | isa = XCBuildConfiguration; 241 | buildSettings = { 242 | ARCHS = "$(ARCHS_UNIVERSAL_IPHONE_OS)"; 243 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 244 | GCC_C_LANGUAGE_STANDARD = gnu99; 245 | GCC_VERSION = com.apple.compilers.llvmgcc42; 246 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 247 | GCC_WARN_UNUSED_VARIABLE = YES; 248 | IPHONEOS_DEPLOYMENT_TARGET = 4.3; 249 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 250 | SDKROOT = iphoneos; 251 | TARGETED_DEVICE_FAMILY = 2; 252 | }; 253 | name = Release; 254 | }; 255 | 55D33A7F1389C50900245167 /* Debug */ = { 256 | isa = XCBuildConfiguration; 257 | buildSettings = { 258 | ALWAYS_SEARCH_USER_PATHS = NO; 259 | COPY_PHASE_STRIP = NO; 260 | GCC_DYNAMIC_NO_PIC = NO; 261 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 262 | GCC_PREFIX_HEADER = "PagedView/PagedView-Prefix.pch"; 263 | INFOPLIST_FILE = "PagedView/PagedView-Info.plist"; 264 | PRODUCT_NAME = "$(TARGET_NAME)"; 265 | WRAPPER_EXTENSION = app; 266 | }; 267 | name = Debug; 268 | }; 269 | 55D33A801389C50900245167 /* Release */ = { 270 | isa = XCBuildConfiguration; 271 | buildSettings = { 272 | ALWAYS_SEARCH_USER_PATHS = NO; 273 | COPY_PHASE_STRIP = YES; 274 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 275 | GCC_PREFIX_HEADER = "PagedView/PagedView-Prefix.pch"; 276 | INFOPLIST_FILE = "PagedView/PagedView-Info.plist"; 277 | PRODUCT_NAME = "$(TARGET_NAME)"; 278 | VALIDATE_PRODUCT = YES; 279 | WRAPPER_EXTENSION = app; 280 | }; 281 | name = Release; 282 | }; 283 | /* End XCBuildConfiguration section */ 284 | 285 | /* Begin XCConfigurationList section */ 286 | 55D33A571389C50900245167 /* Build configuration list for PBXProject "PagedView" */ = { 287 | isa = XCConfigurationList; 288 | buildConfigurations = ( 289 | 55D33A7C1389C50900245167 /* Debug */, 290 | 55D33A7D1389C50900245167 /* Release */, 291 | ); 292 | defaultConfigurationIsVisible = 0; 293 | defaultConfigurationName = Release; 294 | }; 295 | 55D33A7E1389C50900245167 /* Build configuration list for PBXNativeTarget "PagedView" */ = { 296 | isa = XCConfigurationList; 297 | buildConfigurations = ( 298 | 55D33A7F1389C50900245167 /* Debug */, 299 | 55D33A801389C50900245167 /* Release */, 300 | ); 301 | defaultConfigurationIsVisible = 0; 302 | defaultConfigurationName = Release; 303 | }; 304 | /* End XCConfigurationList section */ 305 | }; 306 | rootObject = 55D33A541389C50900245167 /* Project object */; 307 | } 308 | -------------------------------------------------------------------------------- /PagedView/DTLazyImageView.h: -------------------------------------------------------------------------------- 1 | // 2 | // DTLazyImageView.h 3 | // PagingTextScroller 4 | // 5 | // Created by Oliver Drobnik on 5/20/11. 6 | // Copyright 2011 Cocoanetics. All rights reserved. 7 | // 8 | // 9 | // Copyright (c) 2011, Oliver Drobnik All rights reserved. 10 | // 11 | // Redistribution and use in source and binary forms, with or without 12 | // modification, are permitted provided that the following conditions are met: 13 | // 14 | // - Redistributions of source code must retain the above copyright notice, this 15 | // list of conditions and the following disclaimer. 16 | // 17 | // - Redistributions in binary form must reproduce the above copyright notice, 18 | // this list of conditions and the following disclaimer in the documentation 19 | // and/or other materials provided with the distribution. 20 | // 21 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 25 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | #import 33 | 34 | 35 | @interface DTLazyImageView : UIImageView 36 | { 37 | NSURL *_url; 38 | 39 | NSURLConnection *_connection; 40 | NSMutableData *_receivedData; 41 | } 42 | 43 | @property (nonatomic, retain) NSURL *url; 44 | 45 | - (void)cancelLoading; 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /PagedView/DTLazyImageView.m: -------------------------------------------------------------------------------- 1 | // 2 | // DTLazyImageView.m 3 | // PagingTextScroller 4 | // 5 | // Created by Oliver Drobnik on 5/20/11. 6 | // Copyright 2011 Cocoanetics. All rights reserved. 7 | // 8 | // 9 | // Copyright (c) 2011, Oliver Drobnik All rights reserved. 10 | // 11 | // Redistribution and use in source and binary forms, with or without 12 | // modification, are permitted provided that the following conditions are met: 13 | // 14 | // - Redistributions of source code must retain the above copyright notice, this 15 | // list of conditions and the following disclaimer. 16 | // 17 | // - Redistributions in binary form must reproduce the above copyright notice, 18 | // this list of conditions and the following disclaimer in the documentation 19 | // and/or other materials provided with the distribution. 20 | // 21 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 22 | // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23 | // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 24 | // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 25 | // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26 | // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 27 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 28 | // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 29 | // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | 32 | #import "DTLazyImageView.h" 33 | 34 | 35 | @implementation DTLazyImageView 36 | 37 | - (void)dealloc 38 | { 39 | self.image = nil; 40 | [_url release]; 41 | 42 | [_receivedData release]; 43 | [_connection cancel]; 44 | [_connection release]; 45 | 46 | [super dealloc]; 47 | } 48 | 49 | - (void)loadImageAtURL:(NSURL *)url 50 | { 51 | NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:10.0]; 52 | 53 | _connection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO]; 54 | [_connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; 55 | [_connection start]; 56 | 57 | [request release]; 58 | } 59 | 60 | - (void)didMoveToSuperview 61 | { 62 | if (!self.image && _url && !_connection) 63 | { 64 | [self loadImageAtURL:_url]; 65 | } 66 | } 67 | 68 | - (void)cancelLoading 69 | { 70 | [_connection cancel]; 71 | [_connection release], _connection = nil; 72 | 73 | [_receivedData release], _receivedData = nil; 74 | } 75 | 76 | #pragma mark NSURL Loading 77 | 78 | - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 79 | { 80 | // every time we get an response it might be a forward, so we discard what data we have 81 | [_receivedData release], _receivedData = nil; 82 | 83 | // does not fire for local file URLs 84 | if ([response isKindOfClass:[NSHTTPURLResponse class]]) 85 | { 86 | NSHTTPURLResponse *httpResponse = (id)response; 87 | 88 | if (![[httpResponse MIMEType] hasPrefix:@"image"]) 89 | { 90 | [self cancelLoading]; 91 | } 92 | } 93 | 94 | _receivedData = [[NSMutableData alloc] init]; 95 | } 96 | 97 | - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 98 | { 99 | [_receivedData appendData:data]; 100 | } 101 | 102 | - (void)connectionDidFinishLoading:(NSURLConnection *)connection 103 | { 104 | if (_receivedData) 105 | { 106 | UIImage *image = [[UIImage alloc] initWithData:_receivedData]; 107 | 108 | self.image = image; 109 | 110 | [image release]; 111 | 112 | [_receivedData release], _receivedData = nil; 113 | } 114 | 115 | [_connection release], _connection = nil; 116 | } 117 | 118 | - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 119 | { 120 | NSLog(@"Failed to load image at %@, %@", _url, [error localizedDescription]); 121 | 122 | [_connection release], _connection = nil; 123 | [_receivedData release], _receivedData = nil; 124 | } 125 | 126 | 127 | #pragma mark Properties 128 | 129 | @synthesize url = _url; 130 | 131 | @end 132 | -------------------------------------------------------------------------------- /PagedView/JSONKit.h: -------------------------------------------------------------------------------- 1 | // 2 | // JSONKit.h 3 | // http://github.com/johnezang/JSONKit 4 | // Dual licensed under either the terms of the BSD License, or alternatively 5 | // under the terms of the Apache License, Version 2.0, as specified below. 6 | // 7 | 8 | /* 9 | Copyright (c) 2011, John Engelhart 10 | 11 | All rights reserved. 12 | 13 | Redistribution and use in source and binary forms, with or without 14 | modification, are permitted provided that the following conditions are met: 15 | 16 | * Redistributions of source code must retain the above copyright 17 | notice, this list of conditions and the following disclaimer. 18 | 19 | * Redistributions in binary form must reproduce the above copyright 20 | notice, this list of conditions and the following disclaimer in the 21 | documentation and/or other materials provided with the distribution. 22 | 23 | * Neither the name of the Zang Industries nor the names of its 24 | contributors may be used to endorse or promote products derived from 25 | this software without specific prior written permission. 26 | 27 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 28 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 29 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 30 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 31 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 32 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 33 | TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 34 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 35 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 36 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 37 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 38 | */ 39 | 40 | /* 41 | Copyright 2011 John Engelhart 42 | 43 | Licensed under the Apache License, Version 2.0 (the "License"); 44 | you may not use this file except in compliance with the License. 45 | You may obtain a copy of the License at 46 | 47 | http://www.apache.org/licenses/LICENSE-2.0 48 | 49 | Unless required by applicable law or agreed to in writing, software 50 | distributed under the License is distributed on an "AS IS" BASIS, 51 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 52 | See the License for the specific language governing permissions and 53 | limitations under the License. 54 | */ 55 | 56 | #include 57 | #include 58 | #include 59 | #include 60 | #include 61 | 62 | #ifdef __OBJC__ 63 | #import 64 | #import 65 | #import 66 | #import 67 | #import 68 | #import 69 | #endif // __OBJC__ 70 | 71 | #ifdef __cplusplus 72 | extern "C" { 73 | #endif 74 | 75 | 76 | // For Mac OS X < 10.5. 77 | #ifndef NSINTEGER_DEFINED 78 | #define NSINTEGER_DEFINED 79 | #if defined(__LP64__) || defined(NS_BUILD_32_LIKE_64) 80 | typedef long NSInteger; 81 | typedef unsigned long NSUInteger; 82 | #define NSIntegerMin LONG_MIN 83 | #define NSIntegerMax LONG_MAX 84 | #define NSUIntegerMax ULONG_MAX 85 | #else // defined(__LP64__) || defined(NS_BUILD_32_LIKE_64) 86 | typedef int NSInteger; 87 | typedef unsigned int NSUInteger; 88 | #define NSIntegerMin INT_MIN 89 | #define NSIntegerMax INT_MAX 90 | #define NSUIntegerMax UINT_MAX 91 | #endif // defined(__LP64__) || defined(NS_BUILD_32_LIKE_64) 92 | #endif // NSINTEGER_DEFINED 93 | 94 | 95 | #ifndef _JSONKIT_H_ 96 | #define _JSONKIT_H_ 97 | 98 | #if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__APPLE_CC__) && (__APPLE_CC__ >= 5465) 99 | #define JK_DEPRECATED_ATTRIBUTE __attribute__((deprecated)) 100 | #else 101 | #define JK_DEPRECATED_ATTRIBUTE 102 | #endif 103 | 104 | #define JSONKIT_VERSION_MAJOR 1 105 | #define JSONKIT_VERSION_MINOR 4 106 | 107 | typedef NSUInteger JKFlags; 108 | 109 | /* 110 | JKParseOptionComments : Allow C style // and /_* ... *_/ (without a _, obviously) comments in JSON. 111 | JKParseOptionUnicodeNewlines : Allow Unicode recommended (?:\r\n|[\n\v\f\r\x85\p{Zl}\p{Zp}]) newlines. 112 | JKParseOptionLooseUnicode : Normally the decoder will stop with an error at any malformed Unicode. 113 | This option allows JSON with malformed Unicode to be parsed without reporting an error. 114 | Any malformed Unicode is replaced with \uFFFD, or "REPLACEMENT CHARACTER". 115 | */ 116 | 117 | enum { 118 | JKParseOptionNone = 0, 119 | JKParseOptionStrict = 0, 120 | JKParseOptionComments = (1 << 0), 121 | JKParseOptionUnicodeNewlines = (1 << 1), 122 | JKParseOptionLooseUnicode = (1 << 2), 123 | JKParseOptionPermitTextAfterValidJSON = (1 << 3), 124 | JKParseOptionValidFlags = (JKParseOptionComments | JKParseOptionUnicodeNewlines | JKParseOptionLooseUnicode | JKParseOptionPermitTextAfterValidJSON), 125 | }; 126 | typedef JKFlags JKParseOptionFlags; 127 | 128 | enum { 129 | JKSerializeOptionNone = 0, 130 | JKSerializeOptionPretty = (1 << 0), 131 | JKSerializeOptionEscapeUnicode = (1 << 1), 132 | JKSerializeOptionEscapeForwardSlashes = (1 << 4), 133 | JKSerializeOptionValidFlags = (JKSerializeOptionPretty | JKSerializeOptionEscapeUnicode | JKSerializeOptionEscapeForwardSlashes), 134 | }; 135 | typedef JKFlags JKSerializeOptionFlags; 136 | 137 | #ifdef __OBJC__ 138 | 139 | typedef struct JKParseState JKParseState; // Opaque internal, private type. 140 | 141 | // As a general rule of thumb, if you use a method that doesn't accept a JKParseOptionFlags argument, it defaults to JKParseOptionStrict 142 | 143 | @interface JSONDecoder : NSObject { 144 | JKParseState *parseState; 145 | } 146 | + (id)decoder; 147 | + (id)decoderWithParseOptions:(JKParseOptionFlags)parseOptionFlags; 148 | - (id)initWithParseOptions:(JKParseOptionFlags)parseOptionFlags; 149 | - (void)clearCache; 150 | 151 | // The parse... methods were deprecated in v1.4 in favor of the v1.4 objectWith... methods. 152 | - (id)parseUTF8String:(const unsigned char *)string length:(size_t)length JK_DEPRECATED_ATTRIBUTE; // Deprecated in JSONKit v1.4. Use objectWithUTF8String:length: instead. 153 | - (id)parseUTF8String:(const unsigned char *)string length:(size_t)length error:(NSError **)error JK_DEPRECATED_ATTRIBUTE; // Deprecated in JSONKit v1.4. Use objectWithUTF8String:length:error: instead. 154 | // The NSData MUST be UTF8 encoded JSON. 155 | - (id)parseJSONData:(NSData *)jsonData JK_DEPRECATED_ATTRIBUTE; // Deprecated in JSONKit v1.4. Use objectWithData: instead. 156 | - (id)parseJSONData:(NSData *)jsonData error:(NSError **)error JK_DEPRECATED_ATTRIBUTE; // Deprecated in JSONKit v1.4. Use objectWithData:error: instead. 157 | 158 | // Methods that return immutable collection objects. 159 | - (id)objectWithUTF8String:(const unsigned char *)string length:(NSUInteger)length; 160 | - (id)objectWithUTF8String:(const unsigned char *)string length:(NSUInteger)length error:(NSError **)error; 161 | // The NSData MUST be UTF8 encoded JSON. 162 | - (id)objectWithData:(NSData *)jsonData; 163 | - (id)objectWithData:(NSData *)jsonData error:(NSError **)error; 164 | 165 | // Methods that return mutable collection objects. 166 | - (id)mutableObjectWithUTF8String:(const unsigned char *)string length:(NSUInteger)length; 167 | - (id)mutableObjectWithUTF8String:(const unsigned char *)string length:(NSUInteger)length error:(NSError **)error; 168 | // The NSData MUST be UTF8 encoded JSON. 169 | - (id)mutableObjectWithData:(NSData *)jsonData; 170 | - (id)mutableObjectWithData:(NSData *)jsonData error:(NSError **)error; 171 | 172 | @end 173 | 174 | //////////// 175 | #pragma mark Deserializing methods 176 | //////////// 177 | 178 | @interface NSString (JSONKitDeserializing) 179 | - (id)objectFromJSONString; 180 | - (id)objectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags; 181 | - (id)objectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error; 182 | - (id)mutableObjectFromJSONString; 183 | - (id)mutableObjectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags; 184 | - (id)mutableObjectFromJSONStringWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error; 185 | @end 186 | 187 | @interface NSData (JSONKitDeserializing) 188 | // The NSData MUST be UTF8 encoded JSON. 189 | - (id)objectFromJSONData; 190 | - (id)objectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags; 191 | - (id)objectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error; 192 | - (id)mutableObjectFromJSONData; 193 | - (id)mutableObjectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags; 194 | - (id)mutableObjectFromJSONDataWithParseOptions:(JKParseOptionFlags)parseOptionFlags error:(NSError **)error; 195 | @end 196 | 197 | //////////// 198 | #pragma mark Serializing methods 199 | //////////// 200 | 201 | @interface NSString (JSONKitSerializing) 202 | // Convenience methods for those that need to serialize the receiving NSString (i.e., instead of having to serialize a NSArray with a single NSString, you can "serialize to JSON" just the NSString). 203 | // Normally, a string that is serialized to JSON has quotation marks surrounding it, which you may or may not want when serializing a single string, and can be controlled with includeQuotes: 204 | // includeQuotes:YES `a "test"...` -> `"a \"test\"..."` 205 | // includeQuotes:NO `a "test"...` -> `a \"test\"...` 206 | - (NSData *)JSONData; // Invokes JSONDataWithOptions:JKSerializeOptionNone includeQuotes:YES 207 | - (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions includeQuotes:(BOOL)includeQuotes error:(NSError **)error; 208 | - (NSString *)JSONString; // Invokes JSONStringWithOptions:JKSerializeOptionNone includeQuotes:YES 209 | - (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions includeQuotes:(BOOL)includeQuotes error:(NSError **)error; 210 | @end 211 | 212 | @interface NSArray (JSONKitSerializing) 213 | - (NSData *)JSONData; 214 | - (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error; 215 | - (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingDelegate:(id)delegate selector:(SEL)selector error:(NSError **)error; 216 | - (NSString *)JSONString; 217 | - (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error; 218 | - (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingDelegate:(id)delegate selector:(SEL)selector error:(NSError **)error; 219 | @end 220 | 221 | @interface NSDictionary (JSONKitSerializing) 222 | - (NSData *)JSONData; 223 | - (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error; 224 | - (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingDelegate:(id)delegate selector:(SEL)selector error:(NSError **)error; 225 | - (NSString *)JSONString; 226 | - (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions error:(NSError **)error; 227 | - (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingDelegate:(id)delegate selector:(SEL)selector error:(NSError **)error; 228 | @end 229 | 230 | #ifdef __BLOCKS__ 231 | 232 | @interface NSArray (JSONKitSerializingBlockAdditions) 233 | - (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingBlock:(id(^)(id object))block error:(NSError **)error; 234 | - (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingBlock:(id(^)(id object))block error:(NSError **)error; 235 | @end 236 | 237 | @interface NSDictionary (JSONKitSerializingBlockAdditions) 238 | - (NSData *)JSONDataWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingBlock:(id(^)(id object))block error:(NSError **)error; 239 | - (NSString *)JSONStringWithOptions:(JKSerializeOptionFlags)serializeOptions serializeUnsupportedClassesUsingBlock:(id(^)(id object))block error:(NSError **)error; 240 | @end 241 | 242 | #endif 243 | 244 | 245 | #endif // __OBJC__ 246 | 247 | #endif // _JSONKIT_H_ 248 | 249 | #ifdef __cplusplus 250 | } // extern "C" 251 | #endif 252 | -------------------------------------------------------------------------------- /PagedView/PagedView-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIconFile 12 | 13 | CFBundleIdentifier 14 | com.taplicity.${PRODUCT_NAME:rfc1034identifier} 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | ${PRODUCT_NAME} 19 | CFBundlePackageType 20 | APPL 21 | CFBundleShortVersionString 22 | 1.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleVersion 26 | 1.0 27 | LSRequiresIPhoneOS 28 | 29 | NSMainNibFile 30 | MainWindow 31 | UISupportedInterfaceOrientations~ipad 32 | 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /PagedView/PagedView-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'PagedView' target in the 'PagedView' project 3 | // 4 | 5 | #import 6 | 7 | #ifndef __IPHONE_3_0 8 | #warning "This project uses features only available in iPhone SDK 3.0 and later." 9 | #endif 10 | 11 | #ifdef __OBJC__ 12 | #import 13 | #import 14 | #endif 15 | 16 | #ifdef DEBUG 17 | # define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__); 18 | #else 19 | # define DLog(...) 20 | #endif -------------------------------------------------------------------------------- /PagedView/PagedViewAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // PagedViewAppDelegate.h 3 | // PagedView 4 | // 5 | // Created by Rits Plasman on 23-05-11. 6 | // Copyright 2011 Taplicity. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class PagedViewViewController; 12 | 13 | @interface PagedViewAppDelegate : NSObject { 14 | 15 | } 16 | 17 | @property (nonatomic, retain) IBOutlet UIWindow *window; 18 | 19 | @property (nonatomic, retain) IBOutlet PagedViewViewController *viewController; 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /PagedView/PagedViewAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // PagedViewAppDelegate.m 3 | // PagedView 4 | // 5 | // Created by Rits Plasman on 23-05-11. 6 | // Copyright 2011 Taplicity. All rights reserved. 7 | // 8 | 9 | #import "PagedViewAppDelegate.h" 10 | 11 | #import "PagedViewViewController.h" 12 | 13 | @implementation PagedViewAppDelegate 14 | 15 | 16 | @synthesize window=_window; 17 | 18 | @synthesize viewController=_viewController; 19 | 20 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 21 | { 22 | // Override point for customization after application launch. 23 | 24 | self.window.rootViewController = self.viewController; 25 | [self.window makeKeyAndVisible]; 26 | return YES; 27 | } 28 | 29 | - (void)applicationWillResignActive:(UIApplication *)application 30 | { 31 | /* 32 | 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. 33 | 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. 34 | */ 35 | } 36 | 37 | - (void)applicationDidEnterBackground:(UIApplication *)application 38 | { 39 | /* 40 | 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. 41 | If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 42 | */ 43 | } 44 | 45 | - (void)applicationWillEnterForeground:(UIApplication *)application 46 | { 47 | /* 48 | 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. 49 | */ 50 | } 51 | 52 | - (void)applicationDidBecomeActive:(UIApplication *)application 53 | { 54 | /* 55 | 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. 56 | */ 57 | } 58 | 59 | - (void)applicationWillTerminate:(UIApplication *)application 60 | { 61 | /* 62 | Called when the application is about to terminate. 63 | Save data if appropriate. 64 | See also applicationDidEnterBackground:. 65 | */ 66 | } 67 | 68 | - (void)dealloc 69 | { 70 | [_window release]; 71 | [_viewController release]; 72 | [super dealloc]; 73 | } 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /PagedView/PagedViewViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // PagedViewViewController.h 3 | // PagedView 4 | // 5 | // Created by Rits Plasman on 23-05-11. 6 | // Copyright 2011 Taplicity. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class RTSPagedView; 12 | 13 | @interface PagedViewViewController : UIViewController 14 | 15 | @property (nonatomic, retain) IBOutlet RTSPagedView *pagedView; 16 | 17 | @end -------------------------------------------------------------------------------- /PagedView/PagedViewViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // PagedViewViewController.m 3 | // PagedView 4 | // 5 | // Created by Rits Plasman on 23-05-11. 6 | // Copyright 2011 Taplicity. All rights reserved. 7 | // 8 | 9 | #import "PagedViewViewController.h" 10 | #import "RTSPagedView.h" 11 | #import "JSONKit.h" 12 | #import "DTLazyImageView.h" 13 | 14 | @interface PagedViewViewController () 15 | 16 | @property (nonatomic, retain) NSMutableData *receivedData; 17 | @property (nonatomic, retain) NSArray *items; 18 | 19 | @end 20 | 21 | @implementation PagedViewViewController 22 | 23 | @synthesize pagedView = _pagedView; 24 | @synthesize receivedData = _receivedData; 25 | @synthesize items = _items; 26 | 27 | #pragma mark - Paged view delegate 28 | 29 | - (NSUInteger)numberOfPagesInPagedView:(RTSPagedView *)pagedView 30 | { 31 | return [_items count]; 32 | } 33 | 34 | - (UIView *)pagedView:(RTSPagedView *)pagedView viewForPageAtIndex:(NSUInteger)index 35 | { 36 | // Making use of Oliver Drobnik's DTLazyImageView for asynchronous image loading 37 | DTLazyImageView *imageView = (DTLazyImageView *) [pagedView dequeueReusableViewWithTag:0]; 38 | 39 | if (imageView == nil) { 40 | imageView = [[[DTLazyImageView alloc] initWithFrame:CGRectInset(pagedView.bounds, 4.0, 4.0)] autorelease]; 41 | imageView.contentMode = UIViewContentModeScaleAspectFit; 42 | } 43 | 44 | [imageView cancelLoading]; 45 | 46 | NSDictionary *item = [_items objectAtIndex:index]; 47 | imageView.image = nil; 48 | imageView.url = [NSURL URLWithString:[[item objectForKey:@"media"] objectForKey:@"m"]]; 49 | 50 | return imageView; 51 | } 52 | 53 | - (void)pagedView:(RTSPagedView *)pagedView didScrollToPageAtIndex:(NSUInteger)index 54 | { 55 | // Optional 56 | } 57 | 58 | #pragma mark - View lifecycle 59 | 60 | - (void)viewDidLoad 61 | { 62 | [super viewDidLoad]; 63 | 64 | // Endless scrolling 65 | _pagedView.continuous = YES; 66 | _pagedView.clipsToBounds = YES; 67 | 68 | // Load Flickr feed 69 | self.receivedData = [NSMutableData data]; 70 | 71 | NSURL *URL = [NSURL URLWithString:@"http://api.flickr.com/services/feeds/photos_public.gne?lang=en-us&format=json&nojsoncallback=1"]; 72 | NSURLRequest *request = [NSURLRequest requestWithURL:URL]; 73 | [NSURLConnection connectionWithRequest:request delegate:self]; 74 | } 75 | 76 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 77 | { 78 | // Rotation not supported yet 79 | return interfaceOrientation == UIInterfaceOrientationLandscapeRight; 80 | } 81 | 82 | - (void)dealloc 83 | { 84 | [_pagedView release]; 85 | [super dealloc]; 86 | } 87 | 88 | #pragma mark - URL loading 89 | 90 | - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 91 | { 92 | self.receivedData = [NSMutableData data]; 93 | } 94 | 95 | - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 96 | { 97 | [_receivedData appendData:data]; 98 | } 99 | 100 | - (void)connectionDidFinishLoading:(NSURLConnection *)connection 101 | { 102 | NSString *receivedString = [[NSString alloc] initWithData:_receivedData encoding:NSUTF8StringEncoding]; 103 | 104 | // Flickr returns invalid JSON 105 | NSString *JSONString = [receivedString stringByReplacingOccurrencesOfString:@"\\'" withString:@"'"]; 106 | 107 | // Parse using John Engelhart's JSONKit 108 | NSDictionary *dictionary = [JSONString objectFromJSONString]; 109 | [receivedString release]; 110 | 111 | // Set items 112 | self.items = [dictionary objectForKey:@"items"]; 113 | 114 | // Reload paged view 115 | [_pagedView reloadData]; 116 | } 117 | 118 | @end -------------------------------------------------------------------------------- /PagedView/RTSPagedView.h: -------------------------------------------------------------------------------- 1 | // 2 | // RTSPagedView.h 3 | // PagedView 4 | // http://github.com/rplasman/RTSPagedView 5 | // 6 | // Created by Rits Plasman on 22-05-11. 7 | // Copyright 2011 Rits Plasman. All rights reserved. 8 | // 9 | // Redistribution and use in source and binary forms, with or without modification, are 10 | // permitted provided that the following conditions are met: 11 | // 12 | // 1. Redistributions of source code must retain the above copyright notice, this list of 13 | // conditions and the following disclaimer. 14 | // 15 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 16 | // of conditions and the following disclaimer in the documentation and/or other materials 17 | // provided with the distribution. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR IMPLIED 20 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 21 | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 22 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 27 | // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // The views and conclusions contained in the software and documentation are those of the 30 | // authors and should not be interpreted as representing official policies, either expressed 31 | // or implied, of the copyright holder. 32 | 33 | #import 34 | 35 | @protocol RTSPagedViewDelegate; 36 | 37 | @interface RTSPagedView : UIScrollView 38 | 39 | @property (nonatomic, assign) IBOutlet id delegate; 40 | @property (nonatomic, assign) NSUInteger currentPage; 41 | @property (nonatomic, readonly) NSUInteger numberOfPages; 42 | @property (nonatomic, assign) BOOL continuous; 43 | 44 | - (UIView *)dequeueReusableViewWithTag:(NSInteger)tag; 45 | - (UIView *)viewForPageAtIndex:(NSUInteger)index; 46 | - (void)scrollToPageAtIndex:(NSUInteger)index animated:(BOOL)animated; 47 | - (void)reloadData; 48 | - (void)reloadPageAtIndex:(NSUInteger)index; 49 | - (NSUInteger)indexForView:(UIView *)view; 50 | 51 | @end 52 | 53 | @protocol RTSPagedViewDelegate 54 | 55 | - (NSUInteger)numberOfPagesInPagedView:(RTSPagedView *)pagedView; 56 | - (UIView *)pagedView:(RTSPagedView *)pagedView viewForPageAtIndex:(NSUInteger)index; 57 | 58 | @optional 59 | 60 | - (void)pagedView:(RTSPagedView *)pagedView didScrollToPageAtIndex:(NSUInteger)index; 61 | 62 | @end -------------------------------------------------------------------------------- /PagedView/RTSPagedView.m: -------------------------------------------------------------------------------- 1 | // 2 | // RTSPagedView.m 3 | // PagedView 4 | // http://github.com/rplasman/RTSPagedView 5 | // 6 | // Created by Rits Plasman on 22-05-11. 7 | // Copyright 2011 Rits Plasman. All rights reserved. 8 | // 9 | // Redistribution and use in source and binary forms, with or without modification, are 10 | // permitted provided that the following conditions are met: 11 | // 12 | // 1. Redistributions of source code must retain the above copyright notice, this list of 13 | // conditions and the following disclaimer. 14 | // 15 | // 2. Redistributions in binary form must reproduce the above copyright notice, this list 16 | // of conditions and the following disclaimer in the documentation and/or other materials 17 | // provided with the distribution. 18 | // 19 | // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER ``AS IS'' AND ANY EXPRESS OR IMPLIED 20 | // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 21 | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 22 | // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 | // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 | // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 25 | // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 26 | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 27 | // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | // 29 | // The views and conclusions contained in the software and documentation are those of the 30 | // authors and should not be interpreted as representing official policies, either expressed 31 | // or implied, of the copyright holder. 32 | 33 | #import "RTSPagedView.h" 34 | 35 | @interface RTSPagedView () 36 | 37 | @property (nonatomic, retain) NSMutableArray *views; 38 | @property (nonatomic, retain) NSMutableDictionary *queues; 39 | @property (nonatomic, readonly) NSInteger actualPage; 40 | @property (nonatomic, readonly) NSUInteger numberOfActualPages; 41 | @property (nonatomic, readonly) NSUInteger otherVisiblePage; 42 | 43 | - (void)setUp; 44 | - (CGPoint)centerForViewForPageAtIndex:(NSInteger)index; 45 | - (NSMutableArray *)queueWithTag:(NSInteger)tag; 46 | - (void)queueView:(UIView *)view; 47 | - (void)queueExistingViews; 48 | - (void)loadNewViews; 49 | - (void)correctContentOffset; 50 | 51 | @end 52 | 53 | @implementation RTSPagedView 54 | 55 | #pragma mark - Properties 56 | 57 | @synthesize views = _views; 58 | @synthesize queues = _queues; 59 | @synthesize currentPage = _currentPage; 60 | @synthesize actualPage = _actualPage; 61 | @synthesize numberOfPages = _numberOfPages; 62 | @synthesize continuous = _continuous; 63 | @synthesize numberOfActualPages = _numberOfActualPages; 64 | @synthesize otherVisiblePage = _otherVisiblePage; 65 | 66 | - (id )delegate 67 | { 68 | return (id ) [super delegate]; 69 | } 70 | 71 | - (void)setDelegate:(id)delegate 72 | { 73 | [super setDelegate:delegate]; 74 | } 75 | 76 | - (void)setCurrentPage:(NSUInteger)currentPage 77 | { 78 | if (_currentPage == currentPage) { 79 | return; 80 | } 81 | 82 | [self scrollToPageAtIndex:currentPage animated:NO]; 83 | } 84 | 85 | #pragma mark - Object lifecycle 86 | 87 | - (id)init 88 | { 89 | self = [self initWithFrame:CGRectZero]; 90 | return self; 91 | } 92 | 93 | - (id)initWithFrame:(CGRect)frame 94 | { 95 | self = [super initWithFrame:frame]; 96 | if (self) { 97 | [self setUp]; 98 | } 99 | return self; 100 | } 101 | 102 | - (id)initWithCoder:(NSCoder *)aDecoder 103 | { 104 | self = [super initWithCoder:aDecoder]; 105 | if (self) { 106 | [self setUp]; 107 | } 108 | return self; 109 | } 110 | 111 | - (void)setUp 112 | { 113 | _actualPage = NSNotFound; 114 | _currentPage = NSNotFound; 115 | _numberOfPages = NSNotFound; 116 | _numberOfActualPages = NSNotFound; 117 | _otherVisiblePage = NSNotFound; 118 | 119 | // Set default scrollview properties 120 | self.pagingEnabled = YES; 121 | self.showsHorizontalScrollIndicator = NO; 122 | self.showsVerticalScrollIndicator = NO; 123 | self.alwaysBounceHorizontal = YES; 124 | 125 | _views = [[NSMutableArray alloc] init]; 126 | _queues = [[NSMutableDictionary alloc] init]; 127 | } 128 | 129 | - (void)reloadData 130 | { 131 | _actualPage = NSNotFound; 132 | _currentPage = NSNotFound; 133 | _numberOfPages = NSNotFound; 134 | _numberOfActualPages = NSNotFound; 135 | 136 | for (UIView *view in _views) { 137 | if ([view isKindOfClass:[UIView class]]) { 138 | [view removeFromSuperview]; 139 | } 140 | } 141 | 142 | [_views removeAllObjects]; 143 | [_queues removeAllObjects]; 144 | 145 | self.contentOffset = CGPointZero; 146 | 147 | [self setNeedsLayout]; 148 | } 149 | 150 | - (void)reloadPageAtIndex:(NSUInteger)index 151 | { 152 | NSMutableArray *views = self.views; 153 | UIView *previousView = [views objectAtIndex:index]; 154 | CGPoint previousCenter = previousView.center; 155 | [previousView removeFromSuperview]; 156 | 157 | UIView *view = [self.delegate pagedView:self viewForPageAtIndex:index]; 158 | [views replaceObjectAtIndex:index withObject:view]; 159 | view.center = previousCenter; 160 | [self addSubview:view]; 161 | } 162 | 163 | - (void)dealloc 164 | { 165 | [_views release]; 166 | [_queues release]; 167 | [super dealloc]; 168 | } 169 | 170 | #pragma mark - Queueing 171 | 172 | - (NSMutableArray *)queueWithTag:(NSInteger)tag 173 | { 174 | NSNumber *key = [NSNumber numberWithInt:tag]; 175 | NSMutableArray *queue = [_queues objectForKey:key]; 176 | 177 | // Create a queue if none exists 178 | if (!queue) { 179 | queue = [NSMutableArray array]; 180 | [_queues setObject:queue forKey:key]; 181 | } 182 | 183 | return queue; 184 | } 185 | 186 | - (UIView *)dequeueReusableViewWithTag:(NSInteger)tag 187 | { 188 | NSMutableArray *queue = [self queueWithTag:tag]; 189 | 190 | // No queued view available 191 | if ([queue count] == 0) { 192 | return nil; 193 | } 194 | 195 | // Remove view from queue and return it 196 | UIView *view = [[[queue objectAtIndex:0] retain] autorelease]; 197 | [queue removeObjectAtIndex:0]; 198 | 199 | return view; 200 | } 201 | 202 | - (void)queueView:(UIView *)view 203 | { 204 | // Add view to queue 205 | NSMutableArray *queue = [self queueWithTag:view.tag]; 206 | [queue addObject:view]; 207 | } 208 | 209 | - (void)queueExistingViews 210 | { 211 | // Create index set for visible views 212 | NSMutableIndexSet *indexSet = [NSMutableIndexSet indexSetWithIndex:_currentPage]; 213 | 214 | // Add index of view to the left 215 | NSInteger leftIndex = _currentPage - 1; 216 | if (leftIndex >= 0 || _continuous) { 217 | if (leftIndex < 0) { 218 | leftIndex += _numberOfPages; 219 | } 220 | [indexSet addIndex:leftIndex]; 221 | } 222 | 223 | // Add index of view to the right 224 | NSInteger rightIndex = _currentPage + 1; 225 | if (rightIndex < _numberOfPages || _continuous) { 226 | if (rightIndex >= _numberOfPages) { 227 | rightIndex -= _numberOfPages; 228 | } 229 | [indexSet addIndex:rightIndex]; 230 | } 231 | 232 | for (NSInteger i = 0; i < [_views count]; i++) { 233 | UIView *view = [_views objectAtIndex:i]; 234 | 235 | // If this object is not a view, don't queue it 236 | if (![view isKindOfClass:[UIView class]]) { 237 | continue; 238 | } 239 | 240 | // If this is a visible view, don't queue it 241 | if ([indexSet containsIndex:i]) { 242 | continue; 243 | } 244 | 245 | // Remove view from superview and add it to queue for later reuse 246 | [view removeFromSuperview]; 247 | [self queueView:view]; 248 | [_views replaceObjectAtIndex:i withObject:[NSNull null]]; 249 | } 250 | } 251 | 252 | #pragma mark - Subview handling 253 | 254 | - (CGPoint)centerForViewForPageAtIndex:(NSInteger)index 255 | { 256 | CGPoint point = CGPointMake((index + 0.5) * self.bounds.size.width, self.bounds.size.height / 2.0); 257 | return point; 258 | } 259 | 260 | - (UIView *)viewForPageAtIndex:(NSUInteger)index 261 | { 262 | UIView *view = [_views objectAtIndex:index]; 263 | 264 | // If no queued view available, return nil 265 | if (![view isKindOfClass:[UIView class]]) { 266 | return nil; 267 | } 268 | 269 | return view; 270 | } 271 | 272 | - (void)loadNewViews 273 | { 274 | for (NSInteger i = _actualPage - 1; i < _actualPage + 2; i++) { 275 | NSInteger index = i; 276 | 277 | // Get correct view index for this page 278 | if (_continuous) { 279 | if (i < 0) { 280 | index += _numberOfPages; 281 | } else if (i >= _numberOfPages) { 282 | index -= _numberOfPages; 283 | } 284 | } else if (i < 0 || i >= _numberOfPages) { 285 | continue; 286 | } 287 | 288 | // No view for this index 289 | if (index >= [_views count]) { 290 | continue; 291 | } 292 | 293 | UIView *view = [_views objectAtIndex:index]; 294 | 295 | // This view is already visible, reposition it and continue 296 | if ([view isKindOfClass:[UIView class]]) { 297 | if (_continuous && _numberOfPages == 2) { 298 | if (i != _actualPage) { 299 | view.center = [self centerForViewForPageAtIndex:_otherVisiblePage]; 300 | continue; 301 | } 302 | } 303 | 304 | // Always position view at first page when there's only one page 305 | if (_continuous && _numberOfPages == 1) { 306 | view.center = [self centerForViewForPageAtIndex:0]; 307 | continue; 308 | } 309 | 310 | view.center = [self centerForViewForPageAtIndex:i]; 311 | continue; 312 | } 313 | 314 | // Get view for this page 315 | view = [self.delegate pagedView:self viewForPageAtIndex:index]; 316 | view.center = [self centerForViewForPageAtIndex:i]; 317 | if (_continuous && _numberOfPages == 2 && i != _actualPage) { 318 | view.center = [self centerForViewForPageAtIndex:_otherVisiblePage]; 319 | } 320 | [_views replaceObjectAtIndex:index withObject:view]; 321 | [self addSubview:view]; 322 | } 323 | } 324 | 325 | - (void)layoutSubviews 326 | { 327 | if (_numberOfPages == NSNotFound) { 328 | // This is executed only once 329 | _numberOfPages = [self.delegate numberOfPagesInPagedView:self]; 330 | _numberOfActualPages = _numberOfPages; 331 | 332 | if (_continuous && _numberOfPages > 1) { 333 | _numberOfActualPages++; 334 | } 335 | 336 | // Prepopulate views array 337 | while ([_views count] < _numberOfPages) { 338 | [_views addObject:[NSNull null]]; 339 | } 340 | } 341 | 342 | self.contentSize = CGSizeMake(self.bounds.size.width * _numberOfActualPages, self.bounds.size.height); 343 | 344 | [self correctContentOffset]; 345 | 346 | NSInteger actualPage = round(self.contentOffset.x / self.bounds.size.width); 347 | NSInteger otherVisiblePage; 348 | if (actualPage == floor(self.contentOffset.x / self.bounds.size.width)) { 349 | otherVisiblePage = actualPage + 1; 350 | } else { 351 | otherVisiblePage = actualPage - 1; 352 | } 353 | 354 | // If there's only one page, never change page 355 | if (_numberOfPages == 1) { 356 | actualPage = 0; 357 | } 358 | 359 | // If page hasn't changed, nothing to do 360 | if (_actualPage == actualPage && _otherVisiblePage == otherVisiblePage) { 361 | return; 362 | } 363 | 364 | _actualPage = actualPage; 365 | _otherVisiblePage = otherVisiblePage; 366 | 367 | // Calculate current page when continuous scrolling is enabled 368 | NSInteger currentPage = actualPage; 369 | if (_continuous) { 370 | if (currentPage >= _numberOfPages) { 371 | currentPage -= _numberOfPages; 372 | } else if (currentPage < 0) { 373 | currentPage += _numberOfPages; 374 | } 375 | } else { 376 | currentPage = MIN(MAX(0, currentPage), _numberOfPages - 1); 377 | } 378 | 379 | // Only notify delegate if current page has changed 380 | BOOL notifyDelegate = NO; 381 | if (_currentPage != currentPage) { 382 | notifyDelegate = YES; 383 | _currentPage = currentPage; 384 | } 385 | 386 | [self queueExistingViews]; 387 | [self loadNewViews]; 388 | 389 | if (notifyDelegate && [self.delegate respondsToSelector:@selector(pagedView:didScrollToPageAtIndex:)]) { 390 | [self.delegate pagedView:self didScrollToPageAtIndex:_currentPage]; 391 | } 392 | } 393 | 394 | - (NSUInteger)indexForView:(UIView *)view 395 | { 396 | return [_views indexOfObject:view]; 397 | } 398 | 399 | #pragma mark - Scrolling behavior 400 | 401 | - (void)correctContentOffset 402 | { 403 | // Correct content offset for continuous scrolling with multiple pages 404 | if (_continuous && _numberOfPages > 1) { 405 | if (self.contentOffset.x >= _numberOfPages * self.bounds.size.width) { 406 | self.contentOffset = CGPointMake(self.contentOffset.x - (_numberOfPages * self.bounds.size.width), 0.0); 407 | } else if (self.contentOffset.x < 0.0) { 408 | self.contentOffset = CGPointMake(self.contentOffset.x + (_numberOfPages * self.bounds.size.width), 0.0); 409 | } 410 | } 411 | } 412 | 413 | - (void)scrollToPageAtIndex:(NSUInteger)index animated:(BOOL)animated 414 | { 415 | CGPoint contentOffset = CGPointMake(index * self.bounds.size.width, 0.0); 416 | [self setContentOffset:contentOffset animated:animated]; 417 | } 418 | 419 | @end -------------------------------------------------------------------------------- /PagedView/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /PagedView/en.lproj/MainWindow.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 800 5 | 10D540 6 | 760 7 | 1038.29 8 | 460.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 81 12 | 13 | 14 | YES 15 | 16 | 17 | 18 | YES 19 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 20 | 21 | 22 | YES 23 | 24 | YES 25 | 26 | 27 | YES 28 | 29 | 30 | 31 | YES 32 | 33 | IBFilesOwner 34 | IBCocoaTouchFramework 35 | 36 | 37 | IBFirstResponder 38 | IBCocoaTouchFramework 39 | 40 | 41 | 42 | 292 43 | {768, 1024} 44 | 45 | 46 | 1 47 | MSAxIDEAA 48 | 49 | NO 50 | NO 51 | 52 | 2 53 | 54 | IBIPadFramework 55 | YES 56 | 57 | 58 | IBIPadFramework 59 | 60 | 61 | PagedViewViewController 62 | 63 | IBIPadFramework 64 | 65 | 66 | 67 | 68 | YES 69 | 70 | 71 | viewController 72 | 73 | 74 | 75 | 8 76 | 77 | 78 | 79 | delegate 80 | 81 | 82 | 83 | 9 84 | 85 | 86 | 87 | window 88 | 89 | 90 | 91 | 10 92 | 93 | 94 | 95 | 96 | YES 97 | 98 | 0 99 | 100 | 101 | 102 | 103 | 104 | -1 105 | 106 | 107 | File's Owner 108 | 109 | 110 | -2 111 | 112 | 113 | 114 | 115 | 2 116 | 117 | 118 | 119 | 120 | 6 121 | 122 | 123 | PagedView App Delegate 124 | 125 | 126 | 7 127 | 128 | 129 | 130 | 131 | 132 | 133 | YES 134 | 135 | YES 136 | -1.CustomClassName 137 | -2.CustomClassName 138 | 2.IBEditorWindowLastContentRect 139 | 2.IBPluginDependency 140 | 6.CustomClassName 141 | 6.IBPluginDependency 142 | 7.CustomClassName 143 | 7.IBEditorWindowLastContentRect 144 | 7.IBPluginDependency 145 | 146 | 147 | YES 148 | UIApplication 149 | UIResponder 150 | {{200, 57}, {783, 799}} 151 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 152 | PagedViewAppDelegate 153 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 154 | PagedViewViewController 155 | {{512, 351}, {320, 480}} 156 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 157 | 158 | 159 | 160 | YES 161 | 162 | 163 | YES 164 | 165 | 166 | 167 | 168 | YES 169 | 170 | 171 | YES 172 | 173 | 174 | 175 | 10 176 | 177 | 178 | 179 | YES 180 | 181 | PagedViewAppDelegate 182 | NSObject 183 | 184 | YES 185 | 186 | YES 187 | viewController 188 | window 189 | 190 | 191 | YES 192 | PagedViewViewController 193 | UIWindow 194 | 195 | 196 | 197 | IBProjectSource 198 | PagedViewAppDelegate.h 199 | 200 | 201 | 202 | PagedViewViewController 203 | UIViewController 204 | 205 | IBProjectSource 206 | PagedViewViewController.h 207 | 208 | 209 | 210 | 211 | YES 212 | 213 | NSObject 214 | 215 | IBFrameworkSource 216 | Foundation.framework/Headers/NSError.h 217 | 218 | 219 | 220 | NSObject 221 | 222 | IBFrameworkSource 223 | Foundation.framework/Headers/NSFileManager.h 224 | 225 | 226 | 227 | NSObject 228 | 229 | IBFrameworkSource 230 | Foundation.framework/Headers/NSKeyValueCoding.h 231 | 232 | 233 | 234 | NSObject 235 | 236 | IBFrameworkSource 237 | Foundation.framework/Headers/NSKeyValueObserving.h 238 | 239 | 240 | 241 | NSObject 242 | 243 | IBFrameworkSource 244 | Foundation.framework/Headers/NSKeyedArchiver.h 245 | 246 | 247 | 248 | NSObject 249 | 250 | IBFrameworkSource 251 | Foundation.framework/Headers/NSNetServices.h 252 | 253 | 254 | 255 | NSObject 256 | 257 | IBFrameworkSource 258 | Foundation.framework/Headers/NSObject.h 259 | 260 | 261 | 262 | NSObject 263 | 264 | IBFrameworkSource 265 | Foundation.framework/Headers/NSPort.h 266 | 267 | 268 | 269 | NSObject 270 | 271 | IBFrameworkSource 272 | Foundation.framework/Headers/NSRunLoop.h 273 | 274 | 275 | 276 | NSObject 277 | 278 | IBFrameworkSource 279 | Foundation.framework/Headers/NSStream.h 280 | 281 | 282 | 283 | NSObject 284 | 285 | IBFrameworkSource 286 | Foundation.framework/Headers/NSThread.h 287 | 288 | 289 | 290 | NSObject 291 | 292 | IBFrameworkSource 293 | Foundation.framework/Headers/NSURL.h 294 | 295 | 296 | 297 | NSObject 298 | 299 | IBFrameworkSource 300 | Foundation.framework/Headers/NSURLConnection.h 301 | 302 | 303 | 304 | NSObject 305 | 306 | IBFrameworkSource 307 | Foundation.framework/Headers/NSXMLParser.h 308 | 309 | 310 | 311 | NSObject 312 | 313 | IBFrameworkSource 314 | UIKit.framework/Headers/UIAccessibility.h 315 | 316 | 317 | 318 | NSObject 319 | 320 | IBFrameworkSource 321 | UIKit.framework/Headers/UINibLoading.h 322 | 323 | 324 | 325 | NSObject 326 | 327 | IBFrameworkSource 328 | UIKit.framework/Headers/UIResponder.h 329 | 330 | 331 | 332 | UIApplication 333 | UIResponder 334 | 335 | IBFrameworkSource 336 | UIKit.framework/Headers/UIApplication.h 337 | 338 | 339 | 340 | UIResponder 341 | NSObject 342 | 343 | 344 | 345 | UIResponder 346 | 347 | IBFrameworkSource 348 | UIKit.framework/Headers/UITextInput.h 349 | 350 | 351 | 352 | UISearchBar 353 | UIView 354 | 355 | IBFrameworkSource 356 | UIKit.framework/Headers/UISearchBar.h 357 | 358 | 359 | 360 | UISearchDisplayController 361 | NSObject 362 | 363 | IBFrameworkSource 364 | UIKit.framework/Headers/UISearchDisplayController.h 365 | 366 | 367 | 368 | UIView 369 | 370 | IBFrameworkSource 371 | UIKit.framework/Headers/UITextField.h 372 | 373 | 374 | 375 | UIView 376 | UIResponder 377 | 378 | IBFrameworkSource 379 | UIKit.framework/Headers/UIView.h 380 | 381 | 382 | 383 | UIViewController 384 | 385 | IBFrameworkSource 386 | UIKit.framework/Headers/UINavigationController.h 387 | 388 | 389 | 390 | UIViewController 391 | 392 | IBFrameworkSource 393 | UIKit.framework/Headers/UISplitViewController.h 394 | 395 | 396 | 397 | UIViewController 398 | 399 | IBFrameworkSource 400 | UIKit.framework/Headers/UITabBarController.h 401 | 402 | 403 | 404 | UIViewController 405 | UIResponder 406 | 407 | IBFrameworkSource 408 | UIKit.framework/Headers/UIViewController.h 409 | 410 | 411 | 412 | UIWindow 413 | UIView 414 | 415 | IBFrameworkSource 416 | UIKit.framework/Headers/UIWindow.h 417 | 418 | 419 | 420 | 421 | 0 422 | IBIPadFramework 423 | 424 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS 425 | 426 | 427 | 428 | com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 429 | 430 | 431 | YES 432 | PagedView.xcodeproj 433 | 3 434 | 81 435 | 436 | 437 | -------------------------------------------------------------------------------- /PagedView/en.lproj/PagedViewViewController.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 800 5 | 10J869 6 | 1306 7 | 1038.35 8 | 461.00 9 | 10 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 11 | 301 12 | 13 | 14 | YES 15 | IBProxyObject 16 | IBUIView 17 | 18 | 19 | YES 20 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 21 | 22 | 23 | YES 24 | 25 | YES 26 | 27 | 28 | 29 | 30 | YES 31 | 32 | IBFilesOwner 33 | IBIPadFramework 34 | 35 | 36 | IBFirstResponder 37 | IBIPadFramework 38 | 39 | 40 | 41 | 274 42 | 43 | YES 44 | 45 | 46 | 256 47 | {{312, 118}, {400, 512}} 48 | 49 | 50 | 51 | 3 52 | MCAwAA 53 | 54 | IBIPadFramework 55 | 56 | 57 | {{0, 20}, {1024, 748}} 58 | 59 | 60 | 61 | 62 | 3 63 | MAA 64 | 65 | 66 | 2 67 | 68 | 69 | 3 70 | 3 71 | 72 | IBIPadFramework 73 | 74 | 75 | 76 | 77 | YES 78 | 79 | 80 | view 81 | 82 | 83 | 84 | 3 85 | 86 | 87 | 88 | delegate 89 | 90 | 91 | 92 | 5 93 | 94 | 95 | 96 | pagedView 97 | 98 | 99 | 100 | 6 101 | 102 | 103 | 104 | 105 | YES 106 | 107 | 0 108 | 109 | 110 | 111 | 112 | 113 | -1 114 | 115 | 116 | File's Owner 117 | 118 | 119 | -2 120 | 121 | 122 | 123 | 124 | 2 125 | 126 | 127 | YES 128 | 129 | 130 | 131 | 132 | 133 | 4 134 | 135 | 136 | 137 | 138 | 139 | 140 | YES 141 | 142 | YES 143 | -1.CustomClassName 144 | -2.CustomClassName 145 | 2.IBEditorWindowLastContentRect 146 | 2.IBPluginDependency 147 | 4.CustomClassName 148 | 4.IBPluginDependency 149 | 150 | 151 | YES 152 | PagedViewViewController 153 | UIResponder 154 | {{513, 0}, {783, 856}} 155 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 156 | RTSPagedView 157 | com.apple.InterfaceBuilder.IBCocoaTouchPlugin 158 | 159 | 160 | 161 | YES 162 | 163 | 164 | 165 | 166 | 167 | YES 168 | 169 | 170 | 171 | 172 | 6 173 | 174 | 175 | 176 | YES 177 | 178 | PagedViewViewController 179 | UIViewController 180 | 181 | pagedView 182 | RTSPagedView 183 | 184 | 185 | pagedView 186 | 187 | pagedView 188 | RTSPagedView 189 | 190 | 191 | 192 | IBProjectSource 193 | ./Classes/PagedViewViewController.h 194 | 195 | 196 | 197 | RTSPagedView 198 | UIScrollView 199 | 200 | delegate 201 | id 202 | 203 | 204 | delegate 205 | 206 | delegate 207 | id 208 | 209 | 210 | 211 | IBProjectSource 212 | ./Classes/RTSPagedView.h 213 | 214 | 215 | 216 | 217 | 0 218 | IBIPadFramework 219 | 220 | com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS 221 | 222 | 223 | 224 | com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3 225 | 226 | 227 | YES 228 | 3 229 | 301 230 | 231 | 232 | -------------------------------------------------------------------------------- /PagedView/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // PagedView 4 | // 5 | // Created by Rits Plasman on 23-05-11. 6 | // Copyright 2011 Taplicity. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 14 | int retVal = UIApplicationMain(argc, argv, nil, nil); 15 | [pool release]; 16 | return retVal; 17 | } 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # RTSPagedView 2 | 3 | `RTSPagedView` is a lazy-loading paging `UIScrollView` subclass with support for endless scrolling. It works in a way similar to `UITableView`. The sample project included loads a Flickr feed and displays the images lazily. 4 | 5 | `RTSPagedView` gets its subviews from its delegate (`RTSPagedViewDelegate`). The delegate should implement two methods: 6 | 7 | - (NSUInteger)numberOfPagesInPagedView:(RTSPagedView *)pagedView; 8 | - (UIView *)pagedView:(RTSPagedView *)pagedView viewForPageAtIndex:(NSUInteger)index; 9 | 10 | Views are queued internally by `RTSPagedView`, and identified by their `tag` property. You can dequeue views using this method of `RTSPagedView`: 11 | 12 | - (UIView *)dequeueReusableViewWithTag:(NSInteger)tag; 13 | 14 | RTSPagedView is licensed under the terms of the FreeBSD license. Copyright 2011 Rits Plasman. --------------------------------------------------------------------------------