├── .gitignore ├── DWTagList.podspec ├── DWTagList.xcodeproj └── project.pbxproj ├── DWTagList ├── AppDelegate.h ├── AppDelegate.m ├── Classes │ ├── DWTagList.h │ └── DWTagList.m ├── DWTagList-Info.plist ├── DWTagList-Prefix.pch ├── ViewController.h ├── ViewController.m ├── en.lproj │ ├── InfoPlist.strings │ ├── ViewController_iPad.xib │ └── ViewController_iPhone.xib └── main.m ├── Default-568h@2x.png ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | build/* 3 | *.pbxuser 4 | !default.pbxuser 5 | *.mode1v3 6 | !default.mode1v3 7 | *.mode2v3 8 | !default.mode2v3 9 | *.perspectivev3 10 | !default.perspectivev3 11 | *.xcworkspace 12 | !default.xcworkspace 13 | xcuserdata 14 | profile 15 | *.moved-aside 16 | .DS_Store -------------------------------------------------------------------------------- /DWTagList.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "DWTagList" 3 | s.version = "0.0.7" 4 | s.summary = "Create a list of tags from an NSArray to be show in a view with customisable fonts, colors etc." 5 | s.homepage = "https://github.com/domness/DWTagList" 6 | s.license = 'MIT' 7 | s.author = { "Dominic Wroblewski" => "domness@gmail.com" } 8 | s.source = { :git => "https://github.com/domness/DWTagList.git", :tag => "0.0.7" } 9 | s.platform = :ios, '5.0' 10 | s.source_files = 'DWTagList/Classes/*.{h,m}' 11 | s.requires_arc = true 12 | s.frameworks = 'QuartzCore' 13 | end 14 | -------------------------------------------------------------------------------- /DWTagList.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 04DEC60715A897B80034CA79 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04DEC60615A897B70034CA79 /* UIKit.framework */; }; 11 | 04DEC60915A897B80034CA79 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04DEC60815A897B80034CA79 /* Foundation.framework */; }; 12 | 04DEC60B15A897B80034CA79 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04DEC60A15A897B80034CA79 /* CoreGraphics.framework */; }; 13 | 04DEC61115A897B80034CA79 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 04DEC60F15A897B80034CA79 /* InfoPlist.strings */; }; 14 | 04DEC61315A897B80034CA79 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 04DEC61215A897B80034CA79 /* main.m */; }; 15 | 04DEC61715A897B80034CA79 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 04DEC61615A897B80034CA79 /* AppDelegate.m */; }; 16 | 04DEC61A15A897B80034CA79 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 04DEC61915A897B80034CA79 /* ViewController.m */; }; 17 | 04DEC61D15A897B80034CA79 /* ViewController_iPhone.xib in Resources */ = {isa = PBXBuildFile; fileRef = 04DEC61B15A897B80034CA79 /* ViewController_iPhone.xib */; }; 18 | 04DEC62015A897B80034CA79 /* ViewController_iPad.xib in Resources */ = {isa = PBXBuildFile; fileRef = 04DEC61E15A897B80034CA79 /* ViewController_iPad.xib */; }; 19 | 04DEC62915A8988A0034CA79 /* DWTagList.m in Sources */ = {isa = PBXBuildFile; fileRef = 04DEC62815A8988A0034CA79 /* DWTagList.m */; }; 20 | 04DEC62B15A898EF0034CA79 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 04DEC62A15A898EF0034CA79 /* QuartzCore.framework */; }; 21 | 2D195BD416FBAC890069A5E3 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2D195BD316FBAC890069A5E3 /* Default-568h@2x.png */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXFileReference section */ 25 | 04DEC60215A897B70034CA79 /* DWTagList.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DWTagList.app; sourceTree = BUILT_PRODUCTS_DIR; }; 26 | 04DEC60615A897B70034CA79 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 27 | 04DEC60815A897B80034CA79 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 28 | 04DEC60A15A897B80034CA79 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 29 | 04DEC60E15A897B80034CA79 /* DWTagList-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "DWTagList-Info.plist"; sourceTree = ""; }; 30 | 04DEC61015A897B80034CA79 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 31 | 04DEC61215A897B80034CA79 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 32 | 04DEC61415A897B80034CA79 /* DWTagList-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "DWTagList-Prefix.pch"; sourceTree = ""; }; 33 | 04DEC61515A897B80034CA79 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 34 | 04DEC61615A897B80034CA79 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 35 | 04DEC61815A897B80034CA79 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 36 | 04DEC61915A897B80034CA79 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 37 | 04DEC61C15A897B80034CA79 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController_iPhone.xib; sourceTree = ""; }; 38 | 04DEC61F15A897B80034CA79 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/ViewController_iPad.xib; sourceTree = ""; }; 39 | 04DEC62715A8988A0034CA79 /* DWTagList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DWTagList.h; sourceTree = ""; }; 40 | 04DEC62815A8988A0034CA79 /* DWTagList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DWTagList.m; sourceTree = ""; }; 41 | 04DEC62A15A898EF0034CA79 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 42 | 2D195BD316FBAC890069A5E3 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = ""; }; 43 | /* End PBXFileReference section */ 44 | 45 | /* Begin PBXFrameworksBuildPhase section */ 46 | 04DEC5FF15A897B70034CA79 /* Frameworks */ = { 47 | isa = PBXFrameworksBuildPhase; 48 | buildActionMask = 2147483647; 49 | files = ( 50 | 04DEC62B15A898EF0034CA79 /* QuartzCore.framework in Frameworks */, 51 | 04DEC60715A897B80034CA79 /* UIKit.framework in Frameworks */, 52 | 04DEC60915A897B80034CA79 /* Foundation.framework in Frameworks */, 53 | 04DEC60B15A897B80034CA79 /* CoreGraphics.framework in Frameworks */, 54 | ); 55 | runOnlyForDeploymentPostprocessing = 0; 56 | }; 57 | /* End PBXFrameworksBuildPhase section */ 58 | 59 | /* Begin PBXGroup section */ 60 | 04DEC5F715A897B70034CA79 = { 61 | isa = PBXGroup; 62 | children = ( 63 | 2D195BD316FBAC890069A5E3 /* Default-568h@2x.png */, 64 | 04DEC60C15A897B80034CA79 /* DWTagList */, 65 | 04DEC60515A897B70034CA79 /* Frameworks */, 66 | 04DEC60315A897B70034CA79 /* Products */, 67 | ); 68 | sourceTree = ""; 69 | }; 70 | 04DEC60315A897B70034CA79 /* Products */ = { 71 | isa = PBXGroup; 72 | children = ( 73 | 04DEC60215A897B70034CA79 /* DWTagList.app */, 74 | ); 75 | name = Products; 76 | sourceTree = ""; 77 | }; 78 | 04DEC60515A897B70034CA79 /* Frameworks */ = { 79 | isa = PBXGroup; 80 | children = ( 81 | 04DEC62A15A898EF0034CA79 /* QuartzCore.framework */, 82 | 04DEC60615A897B70034CA79 /* UIKit.framework */, 83 | 04DEC60815A897B80034CA79 /* Foundation.framework */, 84 | 04DEC60A15A897B80034CA79 /* CoreGraphics.framework */, 85 | ); 86 | name = Frameworks; 87 | sourceTree = ""; 88 | }; 89 | 04DEC60C15A897B80034CA79 /* DWTagList */ = { 90 | isa = PBXGroup; 91 | children = ( 92 | 04DEC62615A8988A0034CA79 /* Classes */, 93 | 04DEC61515A897B80034CA79 /* AppDelegate.h */, 94 | 04DEC61615A897B80034CA79 /* AppDelegate.m */, 95 | 04DEC61815A897B80034CA79 /* ViewController.h */, 96 | 04DEC61915A897B80034CA79 /* ViewController.m */, 97 | 04DEC61B15A897B80034CA79 /* ViewController_iPhone.xib */, 98 | 04DEC61E15A897B80034CA79 /* ViewController_iPad.xib */, 99 | 04DEC60D15A897B80034CA79 /* Supporting Files */, 100 | ); 101 | path = DWTagList; 102 | sourceTree = ""; 103 | }; 104 | 04DEC60D15A897B80034CA79 /* Supporting Files */ = { 105 | isa = PBXGroup; 106 | children = ( 107 | 04DEC60E15A897B80034CA79 /* DWTagList-Info.plist */, 108 | 04DEC60F15A897B80034CA79 /* InfoPlist.strings */, 109 | 04DEC61215A897B80034CA79 /* main.m */, 110 | 04DEC61415A897B80034CA79 /* DWTagList-Prefix.pch */, 111 | ); 112 | name = "Supporting Files"; 113 | sourceTree = ""; 114 | }; 115 | 04DEC62615A8988A0034CA79 /* Classes */ = { 116 | isa = PBXGroup; 117 | children = ( 118 | 04DEC62715A8988A0034CA79 /* DWTagList.h */, 119 | 04DEC62815A8988A0034CA79 /* DWTagList.m */, 120 | ); 121 | path = Classes; 122 | sourceTree = ""; 123 | }; 124 | /* End PBXGroup section */ 125 | 126 | /* Begin PBXNativeTarget section */ 127 | 04DEC60115A897B70034CA79 /* DWTagList */ = { 128 | isa = PBXNativeTarget; 129 | buildConfigurationList = 04DEC62315A897B80034CA79 /* Build configuration list for PBXNativeTarget "DWTagList" */; 130 | buildPhases = ( 131 | 04DEC5FE15A897B70034CA79 /* Sources */, 132 | 04DEC5FF15A897B70034CA79 /* Frameworks */, 133 | 04DEC60015A897B70034CA79 /* Resources */, 134 | ); 135 | buildRules = ( 136 | ); 137 | dependencies = ( 138 | ); 139 | name = DWTagList; 140 | productName = DWTagList; 141 | productReference = 04DEC60215A897B70034CA79 /* DWTagList.app */; 142 | productType = "com.apple.product-type.application"; 143 | }; 144 | /* End PBXNativeTarget section */ 145 | 146 | /* Begin PBXProject section */ 147 | 04DEC5F915A897B70034CA79 /* Project object */ = { 148 | isa = PBXProject; 149 | attributes = { 150 | LastUpgradeCheck = 0700; 151 | ORGANIZATIONNAME = "Terracoding LTD"; 152 | }; 153 | buildConfigurationList = 04DEC5FC15A897B70034CA79 /* Build configuration list for PBXProject "DWTagList" */; 154 | compatibilityVersion = "Xcode 3.2"; 155 | developmentRegion = English; 156 | hasScannedForEncodings = 0; 157 | knownRegions = ( 158 | en, 159 | ); 160 | mainGroup = 04DEC5F715A897B70034CA79; 161 | productRefGroup = 04DEC60315A897B70034CA79 /* Products */; 162 | projectDirPath = ""; 163 | projectRoot = ""; 164 | targets = ( 165 | 04DEC60115A897B70034CA79 /* DWTagList */, 166 | ); 167 | }; 168 | /* End PBXProject section */ 169 | 170 | /* Begin PBXResourcesBuildPhase section */ 171 | 04DEC60015A897B70034CA79 /* Resources */ = { 172 | isa = PBXResourcesBuildPhase; 173 | buildActionMask = 2147483647; 174 | files = ( 175 | 04DEC61115A897B80034CA79 /* InfoPlist.strings in Resources */, 176 | 04DEC61D15A897B80034CA79 /* ViewController_iPhone.xib in Resources */, 177 | 04DEC62015A897B80034CA79 /* ViewController_iPad.xib in Resources */, 178 | 2D195BD416FBAC890069A5E3 /* Default-568h@2x.png in Resources */, 179 | ); 180 | runOnlyForDeploymentPostprocessing = 0; 181 | }; 182 | /* End PBXResourcesBuildPhase section */ 183 | 184 | /* Begin PBXSourcesBuildPhase section */ 185 | 04DEC5FE15A897B70034CA79 /* Sources */ = { 186 | isa = PBXSourcesBuildPhase; 187 | buildActionMask = 2147483647; 188 | files = ( 189 | 04DEC61315A897B80034CA79 /* main.m in Sources */, 190 | 04DEC61715A897B80034CA79 /* AppDelegate.m in Sources */, 191 | 04DEC61A15A897B80034CA79 /* ViewController.m in Sources */, 192 | 04DEC62915A8988A0034CA79 /* DWTagList.m in Sources */, 193 | ); 194 | runOnlyForDeploymentPostprocessing = 0; 195 | }; 196 | /* End PBXSourcesBuildPhase section */ 197 | 198 | /* Begin PBXVariantGroup section */ 199 | 04DEC60F15A897B80034CA79 /* InfoPlist.strings */ = { 200 | isa = PBXVariantGroup; 201 | children = ( 202 | 04DEC61015A897B80034CA79 /* en */, 203 | ); 204 | name = InfoPlist.strings; 205 | sourceTree = ""; 206 | }; 207 | 04DEC61B15A897B80034CA79 /* ViewController_iPhone.xib */ = { 208 | isa = PBXVariantGroup; 209 | children = ( 210 | 04DEC61C15A897B80034CA79 /* en */, 211 | ); 212 | name = ViewController_iPhone.xib; 213 | sourceTree = ""; 214 | }; 215 | 04DEC61E15A897B80034CA79 /* ViewController_iPad.xib */ = { 216 | isa = PBXVariantGroup; 217 | children = ( 218 | 04DEC61F15A897B80034CA79 /* en */, 219 | ); 220 | name = ViewController_iPad.xib; 221 | sourceTree = ""; 222 | }; 223 | /* End PBXVariantGroup section */ 224 | 225 | /* Begin XCBuildConfiguration section */ 226 | 04DEC62115A897B80034CA79 /* Debug */ = { 227 | isa = XCBuildConfiguration; 228 | buildSettings = { 229 | ALWAYS_SEARCH_USER_PATHS = NO; 230 | CLANG_ENABLE_OBJC_ARC = YES; 231 | CLANG_WARN_BOOL_CONVERSION = YES; 232 | CLANG_WARN_CONSTANT_CONVERSION = YES; 233 | CLANG_WARN_EMPTY_BODY = YES; 234 | CLANG_WARN_ENUM_CONVERSION = YES; 235 | CLANG_WARN_INT_CONVERSION = YES; 236 | CLANG_WARN_UNREACHABLE_CODE = YES; 237 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 238 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 239 | COPY_PHASE_STRIP = NO; 240 | ENABLE_STRICT_OBJC_MSGSEND = YES; 241 | ENABLE_TESTABILITY = YES; 242 | GCC_C_LANGUAGE_STANDARD = gnu99; 243 | GCC_DYNAMIC_NO_PIC = NO; 244 | GCC_NO_COMMON_BLOCKS = YES; 245 | GCC_OPTIMIZATION_LEVEL = 0; 246 | GCC_PREPROCESSOR_DEFINITIONS = ( 247 | "DEBUG=1", 248 | "$(inherited)", 249 | ); 250 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 251 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 252 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 253 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 254 | GCC_WARN_UNDECLARED_SELECTOR = YES; 255 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 256 | GCC_WARN_UNUSED_FUNCTION = YES; 257 | GCC_WARN_UNUSED_VARIABLE = YES; 258 | IPHONEOS_DEPLOYMENT_TARGET = 5.1; 259 | ONLY_ACTIVE_ARCH = YES; 260 | SDKROOT = iphoneos; 261 | TARGETED_DEVICE_FAMILY = "1,2"; 262 | }; 263 | name = Debug; 264 | }; 265 | 04DEC62215A897B80034CA79 /* Release */ = { 266 | isa = XCBuildConfiguration; 267 | buildSettings = { 268 | ALWAYS_SEARCH_USER_PATHS = NO; 269 | CLANG_ENABLE_OBJC_ARC = YES; 270 | CLANG_WARN_BOOL_CONVERSION = YES; 271 | CLANG_WARN_CONSTANT_CONVERSION = YES; 272 | CLANG_WARN_EMPTY_BODY = YES; 273 | CLANG_WARN_ENUM_CONVERSION = YES; 274 | CLANG_WARN_INT_CONVERSION = YES; 275 | CLANG_WARN_UNREACHABLE_CODE = YES; 276 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 277 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 278 | COPY_PHASE_STRIP = YES; 279 | ENABLE_STRICT_OBJC_MSGSEND = YES; 280 | GCC_C_LANGUAGE_STANDARD = gnu99; 281 | GCC_NO_COMMON_BLOCKS = YES; 282 | GCC_VERSION = com.apple.compilers.llvm.clang.1_0; 283 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 284 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 285 | GCC_WARN_UNDECLARED_SELECTOR = YES; 286 | GCC_WARN_UNINITIALIZED_AUTOS = YES; 287 | GCC_WARN_UNUSED_FUNCTION = YES; 288 | GCC_WARN_UNUSED_VARIABLE = YES; 289 | IPHONEOS_DEPLOYMENT_TARGET = 5.1; 290 | OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; 291 | SDKROOT = iphoneos; 292 | TARGETED_DEVICE_FAMILY = "1,2"; 293 | VALIDATE_PRODUCT = YES; 294 | }; 295 | name = Release; 296 | }; 297 | 04DEC62415A897B80034CA79 /* Debug */ = { 298 | isa = XCBuildConfiguration; 299 | buildSettings = { 300 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 301 | GCC_PREFIX_HEADER = "DWTagList/DWTagList-Prefix.pch"; 302 | INFOPLIST_FILE = "DWTagList/DWTagList-Info.plist"; 303 | PRODUCT_BUNDLE_IDENTIFIER = "com.companyname.${PRODUCT_NAME:rfc1034identifier}"; 304 | PRODUCT_NAME = "$(TARGET_NAME)"; 305 | WRAPPER_EXTENSION = app; 306 | }; 307 | name = Debug; 308 | }; 309 | 04DEC62515A897B80034CA79 /* Release */ = { 310 | isa = XCBuildConfiguration; 311 | buildSettings = { 312 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 313 | GCC_PREFIX_HEADER = "DWTagList/DWTagList-Prefix.pch"; 314 | INFOPLIST_FILE = "DWTagList/DWTagList-Info.plist"; 315 | PRODUCT_BUNDLE_IDENTIFIER = "com.companyname.${PRODUCT_NAME:rfc1034identifier}"; 316 | PRODUCT_NAME = "$(TARGET_NAME)"; 317 | WRAPPER_EXTENSION = app; 318 | }; 319 | name = Release; 320 | }; 321 | /* End XCBuildConfiguration section */ 322 | 323 | /* Begin XCConfigurationList section */ 324 | 04DEC5FC15A897B70034CA79 /* Build configuration list for PBXProject "DWTagList" */ = { 325 | isa = XCConfigurationList; 326 | buildConfigurations = ( 327 | 04DEC62115A897B80034CA79 /* Debug */, 328 | 04DEC62215A897B80034CA79 /* Release */, 329 | ); 330 | defaultConfigurationIsVisible = 0; 331 | defaultConfigurationName = Release; 332 | }; 333 | 04DEC62315A897B80034CA79 /* Build configuration list for PBXNativeTarget "DWTagList" */ = { 334 | isa = XCConfigurationList; 335 | buildConfigurations = ( 336 | 04DEC62415A897B80034CA79 /* Debug */, 337 | 04DEC62515A897B80034CA79 /* Release */, 338 | ); 339 | defaultConfigurationIsVisible = 0; 340 | defaultConfigurationName = Release; 341 | }; 342 | /* End XCConfigurationList section */ 343 | }; 344 | rootObject = 04DEC5F915A897B70034CA79 /* Project object */; 345 | } 346 | -------------------------------------------------------------------------------- /DWTagList/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // DWTagList 4 | // 5 | // Created by Dominic Wroblewski on 07/07/2012. 6 | // Copyright (c) 2012 Terracoding LTD. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class ViewController; 12 | 13 | @interface AppDelegate : UIResponder 14 | 15 | @property (strong, nonatomic) UIWindow *window; 16 | 17 | @property (strong, nonatomic) ViewController *viewController; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /DWTagList/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // DWTagList 4 | // 5 | // Created by Dominic Wroblewski on 07/07/2012. 6 | // Copyright (c) 2012 Terracoding LTD. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | #import "ViewController.h" 12 | 13 | @implementation AppDelegate 14 | 15 | @synthesize window = _window; 16 | @synthesize viewController = _viewController; 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 19 | { 20 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 21 | // Override point for customization after application launch. 22 | if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { 23 | self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPhone" bundle:nil]; 24 | } else { 25 | self.viewController = [[ViewController alloc] initWithNibName:@"ViewController_iPad" bundle:nil]; 26 | } 27 | self.window.rootViewController = self.viewController; 28 | [self.window makeKeyAndVisible]; 29 | return YES; 30 | } 31 | 32 | - (void)applicationWillResignActive:(UIApplication *)application 33 | { 34 | // 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. 35 | // 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. 36 | } 37 | 38 | - (void)applicationDidEnterBackground:(UIApplication *)application 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 | - (void)applicationWillEnterForeground:(UIApplication *)application 45 | { 46 | // 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. 47 | } 48 | 49 | - (void)applicationDidBecomeActive:(UIApplication *)application 50 | { 51 | // 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. 52 | } 53 | 54 | - (void)applicationWillTerminate:(UIApplication *)application 55 | { 56 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 57 | } 58 | 59 | @end 60 | -------------------------------------------------------------------------------- /DWTagList/Classes/DWTagList.h: -------------------------------------------------------------------------------- 1 | // 2 | // DWTagList.h 3 | // 4 | // Created by Dominic Wroblewski on 07/07/2012. 5 | // Copyright (c) 2012 Terracoding LTD. All rights reserved. 6 | // 7 | 8 | #import 9 | 10 | IB_DESIGNABLE 11 | @protocol DWTagListDelegate, DWTagViewDelegate; 12 | 13 | @interface DWTagList : UIScrollView 14 | { 15 | UIView *view; 16 | NSArray *textArray; 17 | CGSize sizeFit; 18 | UIColor *lblBackgroundColor; 19 | } 20 | 21 | @property (nonatomic) BOOL viewOnly; 22 | @property (nonatomic) BOOL showTagMenu; 23 | @property (nonatomic, strong) UIView *view; 24 | @property (nonatomic, strong) NSArray *textArray; 25 | @property (nonatomic, weak) id tagDelegate; 26 | @property (nonatomic, strong) IBInspectable UIColor *highlightedBackgroundColor; 27 | @property (nonatomic) IBInspectable BOOL automaticResize; 28 | @property (nonatomic, strong) IBInspectable UIFont *font; 29 | @property (nonatomic, assign) IBInspectable CGFloat labelMargin; 30 | @property (nonatomic, assign) IBInspectable CGFloat bottomMargin; 31 | @property (nonatomic, assign) IBInspectable CGFloat horizontalPadding; 32 | @property (nonatomic, assign) IBInspectable CGFloat verticalPadding; 33 | @property (nonatomic, assign) IBInspectable CGFloat minimumWidth; 34 | @property (nonatomic, assign) IBInspectable CGFloat cornerRadius; 35 | @property (nonatomic, strong) IBInspectable UIColor *borderColor; 36 | @property (nonatomic, assign) IBInspectable CGFloat borderWidth; 37 | @property (nonatomic, strong) IBInspectable UIColor *textColor; 38 | @property (nonatomic, strong) IBInspectable UIColor *textShadowColor; 39 | @property (nonatomic, assign) IBInspectable CGSize textShadowOffset; 40 | 41 | - (void)setTagBackgroundColor:(UIColor *)color; 42 | - (void)setTagHighlightColor:(UIColor *)color; 43 | - (void)setTags:(NSArray *)array; 44 | - (void)display; 45 | - (CGSize)fittedSize; 46 | - (void)scrollToBottomAnimated:(BOOL)animated; 47 | 48 | @end 49 | 50 | @interface DWTagView : UIView 51 | 52 | @property (nonatomic, strong) UIButton *button; 53 | @property (nonatomic, strong) UILabel *label; 54 | @property (nonatomic, weak) id delegate; 55 | 56 | - (void)updateWithString:(NSString*)text 57 | font:(UIFont*)font 58 | constrainedToWidth:(CGFloat)maxWidth 59 | padding:(CGSize)padding 60 | minimumWidth:(CGFloat)minimumWidth; 61 | - (void)setLabelText:(NSString*)text; 62 | - (void)setCornerRadius:(CGFloat)cornerRadius; 63 | - (void)setBorderColor:(CGColorRef)borderColor; 64 | - (void)setBorderWidth:(CGFloat)borderWidth; 65 | - (void)setTextColor:(UIColor*)textColor; 66 | - (void)setTextShadowColor:(UIColor*)textShadowColor; 67 | - (void)setTextShadowOffset:(CGSize)textShadowOffset; 68 | 69 | @end 70 | 71 | 72 | @protocol DWTagListDelegate 73 | 74 | @optional 75 | 76 | - (void)selectedTag:(NSString *)tagName tagIndex:(NSInteger)tagIndex; 77 | - (void)selectedTag:(NSString *)tagName; 78 | - (void)tagListTagsChanged:(DWTagList *)tagList; 79 | 80 | @end 81 | 82 | @protocol DWTagViewDelegate 83 | 84 | @required 85 | 86 | - (void)tagViewWantsToBeDeleted:(DWTagView *)tagView; 87 | 88 | @end 89 | -------------------------------------------------------------------------------- /DWTagList/Classes/DWTagList.m: -------------------------------------------------------------------------------- 1 | // 2 | // DWTagList.m 3 | // 4 | // Created by Dominic Wroblewski on 07/07/2012. 5 | // Copyright (c) 2012 Terracoding LTD. All rights reserved. 6 | // 7 | 8 | #import "DWTagList.h" 9 | #import 10 | 11 | #define CORNER_RADIUS 10.0f 12 | #define LABEL_MARGIN_DEFAULT 5.0f 13 | #define BOTTOM_MARGIN_DEFAULT 5.0f 14 | #define FONT_SIZE_DEFAULT 13.0f 15 | #define HORIZONTAL_PADDING_DEFAULT 7.0f 16 | #define VERTICAL_PADDING_DEFAULT 3.0f 17 | #define BACKGROUND_COLOR [UIColor colorWithRed:0.93 green:0.93 blue:0.93 alpha:1.00] 18 | #define TEXT_COLOR [UIColor blackColor] 19 | #define TEXT_SHADOW_COLOR [UIColor whiteColor] 20 | #define TEXT_SHADOW_OFFSET CGSizeMake(0.0f, 1.0f) 21 | #define BORDER_COLOR [UIColor lightGrayColor] 22 | #define BORDER_WIDTH 1.0f 23 | #define HIGHLIGHTED_BACKGROUND_COLOR [UIColor colorWithRed:0.40 green:0.80 blue:1.00 alpha:0.5] 24 | #define DEFAULT_AUTOMATIC_RESIZE NO 25 | #define DEFAULT_SHOW_TAG_MENU NO 26 | 27 | @interface DWTagList () 28 | 29 | @end 30 | 31 | @implementation DWTagList 32 | 33 | @synthesize view, textArray, automaticResize; 34 | 35 | - (id)initWithFrame:(CGRect)frame 36 | { 37 | self = [super initWithFrame:frame]; 38 | if (self) { 39 | [self setup]; 40 | } 41 | return self; 42 | } 43 | 44 | - (id)initWithCoder:(NSCoder *)aDecoder { 45 | self = [super initWithCoder:aDecoder]; 46 | if (self) { 47 | [self setup]; 48 | } 49 | return self; 50 | } 51 | 52 | - (void)setup { 53 | [self addSubview:view]; 54 | [self setClipsToBounds:YES]; 55 | self.automaticResize = DEFAULT_AUTOMATIC_RESIZE; 56 | self.highlightedBackgroundColor = HIGHLIGHTED_BACKGROUND_COLOR; 57 | self.font = [UIFont systemFontOfSize:FONT_SIZE_DEFAULT]; 58 | self.labelMargin = LABEL_MARGIN_DEFAULT; 59 | self.bottomMargin = BOTTOM_MARGIN_DEFAULT; 60 | self.horizontalPadding = HORIZONTAL_PADDING_DEFAULT; 61 | self.verticalPadding = VERTICAL_PADDING_DEFAULT; 62 | self.cornerRadius = CORNER_RADIUS; 63 | self.borderColor = BORDER_COLOR; 64 | self.borderWidth = BORDER_WIDTH; 65 | self.textColor = TEXT_COLOR; 66 | self.textShadowColor = TEXT_SHADOW_COLOR; 67 | self.textShadowOffset = TEXT_SHADOW_OFFSET; 68 | self.showTagMenu = DEFAULT_SHOW_TAG_MENU; 69 | } 70 | 71 | - (void)setTags:(NSArray *)array 72 | { 73 | textArray = [[NSArray alloc] initWithArray:array]; 74 | sizeFit = CGSizeZero; 75 | if (automaticResize) { 76 | [self display]; 77 | self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, sizeFit.width, sizeFit.height); 78 | } 79 | else { 80 | [self display]; 81 | } 82 | } 83 | 84 | - (void)setTagBackgroundColor:(UIColor *)color 85 | { 86 | lblBackgroundColor = color; 87 | [self display]; 88 | } 89 | 90 | - (void)setTagHighlightColor:(UIColor *)color 91 | { 92 | self.highlightedBackgroundColor = color; 93 | [self display]; 94 | } 95 | 96 | - (void)setViewOnly:(BOOL)viewOnly 97 | { 98 | if (_viewOnly != viewOnly) { 99 | _viewOnly = viewOnly; 100 | [self display]; 101 | } 102 | } 103 | 104 | - (void)layoutSubviews 105 | { 106 | [super layoutSubviews]; 107 | [self display]; 108 | } 109 | 110 | - (void)display 111 | { 112 | NSMutableArray *tagViews = [NSMutableArray array]; 113 | for (UIView *subview in [self subviews]) { 114 | if ([subview isKindOfClass:[DWTagView class]]) { 115 | DWTagView *tagView = (DWTagView*)subview; 116 | for (UIGestureRecognizer *gesture in [subview gestureRecognizers]) { 117 | [subview removeGestureRecognizer:gesture]; 118 | } 119 | 120 | [tagView.button removeTarget:nil action:nil forControlEvents:UIControlEventAllEvents]; 121 | [tagViews addObject:subview]; 122 | } 123 | [subview removeFromSuperview]; 124 | } 125 | 126 | CGRect previousFrame = CGRectZero; 127 | BOOL gotPreviousFrame = NO; 128 | 129 | NSInteger tag = 0; 130 | for (id text in textArray) { 131 | DWTagView *tagView; 132 | if (tagViews.count > 0) { 133 | tagView = [tagViews lastObject]; 134 | [tagViews removeLastObject]; 135 | } 136 | else { 137 | tagView = [[DWTagView alloc] init]; 138 | } 139 | 140 | 141 | [tagView updateWithString:text 142 | font:self.font 143 | constrainedToWidth:self.frame.size.width - (self.horizontalPadding * 2) 144 | padding:CGSizeMake(self.horizontalPadding, self.verticalPadding) 145 | minimumWidth:self.minimumWidth 146 | ]; 147 | 148 | if (gotPreviousFrame) { 149 | CGRect newRect = CGRectZero; 150 | if (previousFrame.origin.x + previousFrame.size.width + tagView.frame.size.width + self.labelMargin > self.frame.size.width) { 151 | newRect.origin = CGPointMake(0, previousFrame.origin.y + tagView.frame.size.height + self.bottomMargin); 152 | } else { 153 | newRect.origin = CGPointMake(previousFrame.origin.x + previousFrame.size.width + self.labelMargin, previousFrame.origin.y); 154 | } 155 | newRect.size = tagView.frame.size; 156 | [tagView setFrame:newRect]; 157 | } 158 | 159 | previousFrame = tagView.frame; 160 | gotPreviousFrame = YES; 161 | 162 | [tagView setBackgroundColor:[self getBackgroundColor]]; 163 | [tagView setCornerRadius:self.cornerRadius]; 164 | [tagView setBorderColor:self.borderColor.CGColor]; 165 | [tagView setBorderWidth:self.borderWidth]; 166 | [tagView setTextColor:self.textColor]; 167 | [tagView setTextShadowColor:self.textShadowColor]; 168 | [tagView setTextShadowOffset:self.textShadowOffset]; 169 | [tagView setTag:tag]; 170 | [tagView setDelegate:self]; 171 | 172 | tag++; 173 | 174 | [self addSubview:tagView]; 175 | 176 | if (!_viewOnly) { 177 | [tagView.button addTarget:self action:@selector(touchDownInside:) forControlEvents:UIControlEventTouchDown]; 178 | [tagView.button addTarget:self action:@selector(touchUpInside:) forControlEvents:UIControlEventTouchUpInside]; 179 | [tagView.button addTarget:self action:@selector(touchDragExit:) forControlEvents:UIControlEventTouchDragExit]; 180 | [tagView.button addTarget:self action:@selector(touchDragInside:) forControlEvents:UIControlEventTouchDragInside]; 181 | } 182 | } 183 | 184 | sizeFit = CGSizeMake(self.frame.size.width, previousFrame.origin.y + previousFrame.size.height + self.bottomMargin + 1.0f); 185 | self.contentSize = sizeFit; 186 | } 187 | 188 | - (CGSize)fittedSize 189 | { 190 | return sizeFit; 191 | } 192 | 193 | - (void)scrollToBottomAnimated:(BOOL)animated 194 | { 195 | [self setContentOffset:CGPointMake(0.0, self.contentSize.height - self.bounds.size.height + self.contentInset.bottom) 196 | animated:animated]; 197 | } 198 | 199 | - (void)touchDownInside:(id)sender 200 | { 201 | UIButton *button = (UIButton*)sender; 202 | [[button superview] setBackgroundColor:self.highlightedBackgroundColor]; 203 | } 204 | 205 | - (void)touchUpInside:(id)sender 206 | { 207 | UIButton *button = (UIButton*)sender; 208 | DWTagView *tagView = (DWTagView *)[button superview]; 209 | [tagView setBackgroundColor:[self getBackgroundColor]]; 210 | 211 | if ([self.tagDelegate respondsToSelector:@selector(selectedTag:tagIndex:)]) { 212 | [self.tagDelegate selectedTag:tagView.label.text tagIndex:tagView.tag]; 213 | } 214 | 215 | if ([self.tagDelegate respondsToSelector:@selector(selectedTag:)]) { 216 | [self.tagDelegate selectedTag:tagView.label.text]; 217 | } 218 | 219 | if (self.showTagMenu) { 220 | UIMenuController *menuController = [UIMenuController sharedMenuController]; 221 | [menuController setTargetRect:tagView.frame inView:self]; 222 | [menuController setMenuVisible:YES animated:YES]; 223 | [tagView becomeFirstResponder]; 224 | } 225 | } 226 | 227 | - (void)touchDragExit:(id)sender 228 | { 229 | UIButton *button = (UIButton*)sender; 230 | [[button superview] setBackgroundColor:[self getBackgroundColor]]; 231 | } 232 | 233 | - (void)touchDragInside:(id)sender 234 | { 235 | UIButton *button = (UIButton*)sender; 236 | [[button superview] setBackgroundColor:[self getBackgroundColor]]; 237 | } 238 | 239 | - (UIColor *)getBackgroundColor 240 | { 241 | return !lblBackgroundColor ? BACKGROUND_COLOR : lblBackgroundColor; 242 | } 243 | 244 | - (void)setCornerRadius:(CGFloat)cornerRadius 245 | { 246 | _cornerRadius = cornerRadius; 247 | [self display]; 248 | } 249 | 250 | - (void)setBorderColor:(UIColor*)borderColor 251 | { 252 | _borderColor = borderColor; 253 | [self display]; 254 | } 255 | 256 | - (void)setBorderWidth:(CGFloat)borderWidth 257 | { 258 | _borderWidth = borderWidth; 259 | [self display]; 260 | } 261 | 262 | - (void)setTextColor:(UIColor *)textColor 263 | { 264 | _textColor = textColor; 265 | [self display]; 266 | } 267 | 268 | - (void)setTextShadowColor:(UIColor *)textShadowColor 269 | { 270 | _textShadowColor = textShadowColor; 271 | [self display]; 272 | } 273 | 274 | - (void)setTextShadowOffset:(CGSize)textShadowOffset 275 | { 276 | _textShadowOffset = textShadowOffset; 277 | [self display]; 278 | } 279 | 280 | - (void)dealloc 281 | { 282 | view = nil; 283 | textArray = nil; 284 | lblBackgroundColor = nil; 285 | } 286 | 287 | #pragma mark - DWTagViewDelegate 288 | 289 | - (void)tagViewWantsToBeDeleted:(DWTagView *)tagView { 290 | NSMutableArray *mTextArray = [self.textArray mutableCopy]; 291 | [mTextArray removeObject:tagView.label.text]; 292 | [self setTags:mTextArray]; 293 | 294 | if ([self.tagDelegate respondsToSelector:@selector(tagListTagsChanged:)]) { 295 | [self.tagDelegate tagListTagsChanged:self]; 296 | } 297 | } 298 | 299 | @end 300 | 301 | 302 | @implementation DWTagView 303 | 304 | - (id)init 305 | { 306 | self = [super init]; 307 | if (self) { 308 | _label = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 0, 0)]; 309 | [_label setTextColor:TEXT_COLOR]; 310 | [_label setShadowColor:TEXT_SHADOW_COLOR]; 311 | [_label setShadowOffset:TEXT_SHADOW_OFFSET]; 312 | [_label setBackgroundColor:[UIColor clearColor]]; 313 | [_label setTextAlignment:NSTextAlignmentCenter]; 314 | [self addSubview:_label]; 315 | 316 | _button = [UIButton buttonWithType:UIButtonTypeCustom]; 317 | _button.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth; 318 | [_button setFrame:self.frame]; 319 | [self addSubview:_button]; 320 | 321 | [self.layer setMasksToBounds:YES]; 322 | [self.layer setCornerRadius:CORNER_RADIUS]; 323 | [self.layer setBorderColor:BORDER_COLOR.CGColor]; 324 | [self.layer setBorderWidth:BORDER_WIDTH]; 325 | } 326 | return self; 327 | } 328 | 329 | - (void)updateWithString:(id)text font:(UIFont*)font constrainedToWidth:(CGFloat)maxWidth padding:(CGSize)padding minimumWidth:(CGFloat)minimumWidth 330 | { 331 | CGSize textSize = CGSizeZero; 332 | BOOL isTextAttributedString = [text isKindOfClass:[NSAttributedString class]]; 333 | 334 | if (isTextAttributedString) { 335 | NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithAttributedString:text]; 336 | [attributedString addAttributes:@{NSFontAttributeName: font} range:NSMakeRange(0, ((NSAttributedString *)text).string.length)]; 337 | 338 | textSize = [attributedString boundingRectWithSize:CGSizeMake(maxWidth, 0) options:NSStringDrawingUsesLineFragmentOrigin context:nil].size; 339 | _label.attributedText = [attributedString copy]; 340 | } else { 341 | textSize = [text sizeWithFont:font forWidth:maxWidth lineBreakMode:NSLineBreakByTruncatingTail]; 342 | _label.text = text; 343 | } 344 | 345 | textSize.width = MAX(textSize.width, minimumWidth); 346 | textSize.height += padding.height*2; 347 | 348 | self.frame = CGRectMake(0, 0, textSize.width+padding.width*2, textSize.height); 349 | _label.frame = CGRectMake(padding.width, 0, MIN(textSize.width, self.frame.size.width), textSize.height); 350 | _label.font = font; 351 | 352 | [_button setAccessibilityLabel:self.label.text]; 353 | } 354 | 355 | - (void)setCornerRadius:(CGFloat)cornerRadius 356 | { 357 | [self.layer setCornerRadius:cornerRadius]; 358 | } 359 | 360 | - (void)setBorderColor:(CGColorRef)borderColor 361 | { 362 | [self.layer setBorderColor:borderColor]; 363 | } 364 | 365 | - (void)setBorderWidth:(CGFloat)borderWidth 366 | { 367 | [self.layer setBorderWidth:borderWidth]; 368 | } 369 | 370 | - (void)setLabelText:(NSString*)text 371 | { 372 | [_label setText:text]; 373 | } 374 | 375 | - (void)setTextColor:(UIColor *)textColor 376 | { 377 | [_label setTextColor:textColor]; 378 | } 379 | 380 | - (void)setTextShadowColor:(UIColor*)textShadowColor 381 | { 382 | [_label setShadowColor:textShadowColor]; 383 | } 384 | 385 | - (void)setTextShadowOffset:(CGSize)textShadowOffset 386 | { 387 | [_label setShadowOffset:textShadowOffset]; 388 | } 389 | 390 | - (void)dealloc 391 | { 392 | _label = nil; 393 | _button = nil; 394 | } 395 | 396 | #pragma mark - UIMenuController support 397 | 398 | - (BOOL)canBecomeFirstResponder 399 | { 400 | return YES; 401 | } 402 | 403 | - (BOOL)canPerformAction:(SEL)action withSender:(id)sender 404 | { 405 | return (action == @selector(copy:)) || (action == @selector(delete:)); 406 | } 407 | 408 | - (void)copy:(id)sender 409 | { 410 | [[UIPasteboard generalPasteboard] setString:self.label.text]; 411 | } 412 | 413 | - (void)delete:(id)sender 414 | { 415 | [self.delegate tagViewWantsToBeDeleted:self]; 416 | } 417 | 418 | @end 419 | -------------------------------------------------------------------------------- /DWTagList/DWTagList-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 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 | -------------------------------------------------------------------------------- /DWTagList/DWTagList-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header for all source files of the 'DWTagList' target in the 'DWTagList' 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 | -------------------------------------------------------------------------------- /DWTagList/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // DWTagList 4 | // 5 | // Created by Dominic Wroblewski on 07/07/2012. 6 | // Copyright (c) 2012 Terracoding LTD. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DWTagList.h" 11 | 12 | @interface ViewController : UIViewController 13 | 14 | @property (nonatomic, strong) NSMutableArray *array; 15 | @property (nonatomic, weak) IBOutlet DWTagList *tagList; 16 | @property (nonatomic, weak) IBOutlet UITextField *addTagField; 17 | 18 | - (IBAction)tappedAdd:(id)sender; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /DWTagList/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // DWTagList 4 | // 5 | // Created by Dominic Wroblewski on 07/07/2012. 6 | // Copyright (c) 2012 Terracoding LTD. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | 11 | @interface ViewController () 12 | 13 | @end 14 | 15 | @implementation ViewController 16 | 17 | //- (void)selectedTag:(NSString *)tagName{ 18 | // 19 | // UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Message" 20 | // message:[NSString stringWithFormat:@"You tapped tag %@", tagName] 21 | // delegate:nil 22 | // cancelButtonTitle:@"Ok" 23 | // otherButtonTitles:nil]; 24 | // [alert show]; 25 | //} 26 | 27 | - (void)selectedTag:(NSString *)tagName tagIndex:(NSInteger)tagIndex 28 | { 29 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Message" 30 | message:[NSString stringWithFormat:@"You tapped tag %@ at index %ld", tagName,(long)tagIndex] 31 | delegate:nil 32 | cancelButtonTitle:@"Ok" 33 | otherButtonTitles:nil]; 34 | [alert show]; 35 | } 36 | 37 | - (void)viewDidLoad 38 | { 39 | [super viewDidLoad]; 40 | [_tagList setAutomaticResize:YES]; 41 | _array = [[NSMutableArray alloc] initWithObjects:@"Foo", 42 | @"Tag Label 1", 43 | @"Tag Label 2", 44 | @"Tag Label 3", 45 | @"Tag Label 4", 46 | @"Long long long long long long Tag", nil]; 47 | [_tagList setTags:_array]; 48 | [_tagList setTagDelegate:self]; 49 | } 50 | 51 | - (IBAction)tappedAdd:(id)sender 52 | { 53 | [_addTagField resignFirstResponder]; 54 | if ([[_addTagField text] length]) { 55 | [_array addObject:[_addTagField text]]; 56 | } 57 | [_addTagField setText:@""]; 58 | [_tagList setTags:_array]; 59 | } 60 | 61 | - (void)viewDidUnload 62 | { 63 | [super viewDidUnload]; 64 | } 65 | 66 | - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation 67 | { 68 | if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) { 69 | return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown); 70 | } else { 71 | return YES; 72 | } 73 | } 74 | 75 | @end 76 | -------------------------------------------------------------------------------- /DWTagList/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /DWTagList/en.lproj/ViewController_iPad.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /DWTagList/en.lproj/ViewController_iPhone.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /DWTagList/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // DWTagList 4 | // 5 | // Created by Dominic Wroblewski on 07/07/2012. 6 | // Copyright (c) 2012 Terracoding LTD. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Default-568h@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/domness/DWTagList/0d344a04ac4e27e4ceb4be1b8c9be7a9c02106f9/Default-568h@2x.png -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 Dominic Wroblewski 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DWTagList 2 | ========= 3 | 4 | Create a list of tags from an NSArray to be show in a view with customisable fonts, colors etc. 5 | 6 | ![preview](http://f.cl.ly/items/1k3K1i0w2b1d1M0O1w1G/DWTagList.png "Preview") 7 | 8 | ## Installation 9 | 10 | Simple copy over `DWTagList.h` and `DWTagList.m` into your project and make sure you have linked the framework `QuartzCore.framework`. 11 | 12 | You may then add tags to your view by the following lines of code: 13 | 14 | // Initalise and set the frame of the tag list 15 | tagList = [[DWTagList alloc] initWithFrame:CGRectMake(20.0f, 70.0f, 280.0f, 300.0f)]; 16 | 17 | // Add the items to the array 18 | NSArray *array = [[NSArray alloc] initWithObjects:@"Foo", @"Tag Label 1", @"Tag Label 2", @"Tag Label 3", @"Tag Label 4", @"Tag Label 5", nil]; 19 | [tagList setTags:array]; 20 | 21 | // Add the taglist to your UIView 22 | [self.view addSubview:tagList]; 23 | 24 | ## Customisation 25 | 26 | In `DWTagList.m` there are a number of customisable options to change the layout and the aesthetics of the tags. These can be done via @properties, not all of them are there yet. 27 | 28 | NOTE: In the future, these will be added as methods that can be used to customise the tags after initialisation. 29 | 30 | ## License 31 | 32 | I have included the license in the `LICENSE` file. I've got it as the MIT license, mainly because I want people to do what they want with this library. 33 | 34 | If you do something cool, or find any problems, please create a pull request and I will look at including any of your changes into this project. 35 | --------------------------------------------------------------------------------