├── .gitignore ├── BENTagsView.podspec ├── BENTagsView ├── BENTag.h ├── BENTag.m ├── BENTagsView.h └── BENTagsView.m ├── BENTagsViewDemo.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata ├── BENTagsViewDemo ├── BENAppDelegate.h ├── BENAppDelegate.m ├── BENTagsDemoController.h ├── BENTagsDemoController.m ├── BENTagsViewDemo-Info.plist ├── BENTagsViewDemo-Prefix.pch ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── LaunchImage.launchimage │ │ └── Contents.json ├── Screenshot1.png ├── en.lproj │ └── InfoPlist.strings └── main.m ├── BENTagsViewDemoTests ├── BENTagsViewDemoTests-Info.plist ├── BENTagsViewDemoTests.m └── en.lproj │ └── InfoPlist.strings ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | .DS_Store 3 | */build/* 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | profile 14 | *.moved-aside 15 | DerivedData 16 | .idea/ 17 | *.hmap 18 | *.xccheckout 19 | 20 | #CocoaPods 21 | Pods 22 | -------------------------------------------------------------------------------- /BENTagsView.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | 3 | s.name = "BENTagsView" 4 | s.version = "0.9.0" 5 | s.summary = "A simple UIView sublass for displaying a series of tags." 6 | s.description = "BENTagsView allows you to quickly add a series of tags to any UIView. It is easy to add tags, customize fonts and colors, and to turn tags on and off." 7 | s.homepage = "https://github.com/benpackard/BENTagsView" 8 | s.license = 'MIT' 9 | s.author = { "Ben Packard" => "ben@benpackard.org" } 10 | s.platform = :ios 11 | s.source = { :git => "https://github.com/benpackard/BENTagsView.git", :tag => "0.9.0" } 12 | s.source_files = 'BENTagsView/*.{h,m}' 13 | s.requires_arc = true 14 | end -------------------------------------------------------------------------------- /BENTagsView/BENTag.h: -------------------------------------------------------------------------------- 1 | // 2 | // BENTag.h 3 | // BENTagsView 4 | // 5 | // Created by Ben Packard on 3/13/14. 6 | // Copyright (c) 2014 Ben Packard. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BENTag : UIView 12 | 13 | @property UILabel *textLabel; 14 | @property BOOL on; 15 | @property UIColor *onColor, *offColor; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /BENTagsView/BENTag.m: -------------------------------------------------------------------------------- 1 | // 2 | // BENTag.m 3 | // BENTagsView 4 | // 5 | // Created by Ben Packard on 3/12/14. 6 | // 7 | // 8 | 9 | #import "BENTag.h" 10 | 11 | @implementation BENTag 12 | 13 | @synthesize on = _on; 14 | 15 | - (id)initWithFrame:(CGRect)frame 16 | { 17 | self = [super initWithFrame:frame]; 18 | if (self) 19 | { 20 | //defaults 21 | self.on = NO; 22 | self.offColor = self.offColor = [UIColor colorWithRed:0.79 green:0.79 blue:0.79 alpha:1.0]; 23 | self.onColor = [UIColor blackColor]; 24 | 25 | //add the label 26 | self.textLabel = [[UILabel alloc] init]; 27 | self.textLabel.translatesAutoresizingMaskIntoConstraints = NO; 28 | self.textLabel.textColor = [UIColor whiteColor]; 29 | self.textLabel.font = [UIFont systemFontOfSize:9]; 30 | [self addSubview:self.textLabel]; 31 | NSDictionary *views = @{@"label":self.textLabel}; 32 | [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-7-[label]-7-|" 33 | options:0 34 | metrics:nil 35 | views:views]]; 36 | [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-2-[label]-2-|" 37 | options:0 38 | metrics:nil 39 | views:views]]; 40 | 41 | //refresh 42 | [self refresh]; 43 | } 44 | return self; 45 | } 46 | 47 | - (void)refresh 48 | { 49 | [self setPersistantBackgroundColor:self.on ? self.onColor : self.offColor]; 50 | } 51 | 52 | - (BOOL)on 53 | { 54 | return _on; 55 | } 56 | 57 | - (void)setOn:(BOOL)on 58 | { 59 | _on = on; 60 | [self refresh]; 61 | } 62 | 63 | //if embedded in a UITableViewCell, on cell selection the default behavior is for all of the cell's subviews to set their background color to transparent. See SO 7053340. To avoid this, make the default implementation of setBackground do nothing, and instead provide a different method to change the color internally. 64 | - (void)setPersistantBackgroundColor:(UIColor *)color 65 | { 66 | [super setBackgroundColor:color]; 67 | } 68 | 69 | - (void)setBackgroundColor:(UIColor *)backgroundColor 70 | { 71 | //do nothing 72 | } 73 | 74 | @end 75 | -------------------------------------------------------------------------------- /BENTagsView/BENTagsView.h: -------------------------------------------------------------------------------- 1 | // 2 | // BENTagsView.h 3 | // 4 | // 5 | // Created by Ben Packard on 3/12/14. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface BENTagsView : UIView 12 | 13 | @property NSArray *tagStrings; 14 | @property UIFont *font; 15 | @property UIColor *textColor, *onColor, *offColor; 16 | @property NSIndexSet *onIndexes; 17 | @property NSInteger tagCornerRadius; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /BENTagsView/BENTagsView.m: -------------------------------------------------------------------------------- 1 | // 2 | // BENTagsView.m 3 | // 4 | // 5 | // Created by Ben Packard on 3/12/14. 6 | // 7 | // 8 | 9 | #import "BENTagsView.h" 10 | 11 | //views 12 | #import "BENTag.h" 13 | 14 | @interface BENTagsView () 15 | 16 | @property NSMutableArray *tags; 17 | 18 | @end 19 | 20 | @implementation BENTagsView 21 | 22 | @synthesize tagStrings = _tagStrings; 23 | @synthesize font = _font; 24 | @synthesize textColor = _textColor; 25 | @synthesize onColor = _onColor; 26 | @synthesize offColor = _offColor; 27 | @synthesize onIndexes = _onIndexes; 28 | @synthesize tagCornerRadius = _tagCornerRadius; 29 | 30 | #pragma mark - initialization 31 | 32 | - (void)baseInit 33 | { 34 | //arrays 35 | self.onIndexes = [NSIndexSet indexSet]; 36 | self.tags = [NSMutableArray array]; 37 | 38 | //defaults 39 | self.onColor = [UIColor blackColor]; 40 | self.offColor = [UIColor colorWithRed:0.79 green:0.79 blue:0.79 alpha:1.0]; 41 | self.font = [UIFont systemFontOfSize:9]; 42 | self.textColor = [UIColor whiteColor]; 43 | self.tagCornerRadius = 0; 44 | } 45 | 46 | - (id)initWithFrame:(CGRect)frame 47 | { 48 | self = [super initWithFrame:frame]; 49 | if (self) 50 | { 51 | [self baseInit]; 52 | } 53 | return self; 54 | } 55 | 56 | - (id)initWithCoder:(NSCoder *)aDecoder 57 | { 58 | if (self = [super initWithCoder:aDecoder]) 59 | { 60 | [self baseInit]; 61 | } 62 | return self; 63 | } 64 | 65 | #pragma mark - subviews and layout 66 | 67 | - (void)refresh 68 | { 69 | //remove all existing tag views (also removes constraints automatically) 70 | for (BENTag *tag in self.tags) 71 | { 72 | [tag removeFromSuperview]; 73 | } 74 | [self.tags removeAllObjects]; 75 | 76 | //add tags 77 | [self.tagStrings enumerateObjectsUsingBlock:^(id tagString, NSUInteger idx, BOOL *stop) { 78 | BENTag *tag = [[BENTag alloc] init]; 79 | tag.translatesAutoresizingMaskIntoConstraints = NO; 80 | tag.textLabel.text = tagString; 81 | tag.textLabel.font = self.font; 82 | tag.textLabel.textColor = self.textColor; 83 | tag.onColor = self.onColor; 84 | tag.offColor = self.offColor; 85 | tag.on = [self.onIndexes containsIndex:idx] ? YES : NO; 86 | tag.layer.cornerRadius = self.tagCornerRadius; 87 | [self addSubview:tag]; 88 | [self.tags addObject:tag]; 89 | }]; 90 | 91 | //layout 92 | BENTag *previousTag = nil; 93 | 94 | for (BENTag *tag in self.tags) 95 | { 96 | [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[tag]|" 97 | options:0 98 | metrics:nil 99 | views:NSDictionaryOfVariableBindings(tag)]]; 100 | 101 | if (!previousTag) 102 | { 103 | [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[tag]" 104 | options:0 105 | metrics:nil 106 | views:NSDictionaryOfVariableBindings(tag)]]; 107 | } 108 | else 109 | { 110 | [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"[previousTag]-5-[tag]" 111 | options:0 112 | metrics:nil 113 | views:NSDictionaryOfVariableBindings(previousTag, tag)]]; 114 | } 115 | 116 | if (tag == [self.tags lastObject]) 117 | { 118 | [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"[tag]|" 119 | options:0 120 | metrics:nil 121 | views:NSDictionaryOfVariableBindings(tag)]]; 122 | } 123 | 124 | previousTag = tag; 125 | } 126 | } 127 | 128 | #pragma mark - custom setters for properties that require a refresh 129 | 130 | - (NSArray *)tagStrings 131 | { 132 | return _tagStrings; 133 | } 134 | 135 | - (void)setTagStrings:(NSArray *)tagStrings 136 | { 137 | if ([tagStrings isEqualToArray:self.tagStrings]) return; 138 | BOOL reuseTags = tagStrings.count == self.tagStrings.count; 139 | _tagStrings = tagStrings; 140 | 141 | if (reuseTags) 142 | { 143 | [self.tags enumerateObjectsUsingBlock:^(BENTag *tag, NSUInteger idx, BOOL *stop) { 144 | tag.textLabel.text = self.tagStrings[idx]; 145 | }]; 146 | } 147 | else 148 | { 149 | [self refresh]; 150 | } 151 | } 152 | 153 | - (UIFont *)font 154 | { 155 | return _font; 156 | } 157 | 158 | - (void)setFont:(UIFont *)font 159 | { 160 | if ([font isEqual:self.font]) return; 161 | _font = font; 162 | [self refresh]; 163 | } 164 | 165 | - (UIColor *)textColor 166 | { 167 | return _textColor; 168 | } 169 | 170 | - (void)setTextColor:(UIColor *)textColor 171 | { 172 | if ([textColor isEqual:self.textColor]) return; 173 | _textColor = textColor; 174 | [self refresh]; 175 | } 176 | 177 | - (UIColor *)onColor 178 | { 179 | return _onColor; 180 | } 181 | 182 | - (void)setOnColor:(UIColor *)onColor 183 | { 184 | if ([onColor isEqual:self.onColor]) return; 185 | _onColor = onColor; 186 | 187 | for (BENTag *tag in self.tags) 188 | { 189 | tag.onColor = onColor; 190 | } 191 | } 192 | 193 | - (UIColor *)offColor 194 | { 195 | return _offColor; 196 | } 197 | 198 | - (void)setOffColor:(UIColor *)offColor 199 | { 200 | if ([offColor isEqual:self.offColor]) return; 201 | _offColor = offColor; 202 | 203 | for (BENTag *tag in self.tags) 204 | { 205 | tag.offColor = offColor; 206 | } 207 | } 208 | 209 | - (NSIndexSet *)onIndexes 210 | { 211 | return _onIndexes; 212 | } 213 | 214 | - (void)setOnIndexes:(NSIndexSet *)onIndexes 215 | { 216 | if ([onIndexes isEqualToIndexSet:self.onIndexes]) return; 217 | _onIndexes = onIndexes; 218 | 219 | [self.tags enumerateObjectsUsingBlock:^(BENTag *tag, NSUInteger idx, BOOL *stop) { 220 | tag.on = [self.onIndexes containsIndex:idx] ? YES : NO; 221 | }]; 222 | } 223 | 224 | - (NSInteger)tagCornerRadius 225 | { 226 | return _tagCornerRadius; 227 | } 228 | 229 | - (void)setTagCornerRadius:(NSInteger)tagCornerRadius 230 | { 231 | if (tagCornerRadius == self.tagCornerRadius) return; 232 | _tagCornerRadius = tagCornerRadius; 233 | [self refresh]; 234 | } 235 | 236 | @end 237 | -------------------------------------------------------------------------------- /BENTagsViewDemo.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | C5242D7718D20FBB00F6C6BF /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C5242D7618D20FBB00F6C6BF /* Foundation.framework */; }; 11 | C5242D7918D20FBB00F6C6BF /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C5242D7818D20FBB00F6C6BF /* CoreGraphics.framework */; }; 12 | C5242D7B18D20FBB00F6C6BF /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C5242D7A18D20FBB00F6C6BF /* UIKit.framework */; }; 13 | C5242D8118D20FBB00F6C6BF /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = C5242D7F18D20FBB00F6C6BF /* InfoPlist.strings */; }; 14 | C5242D8318D20FBB00F6C6BF /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C5242D8218D20FBB00F6C6BF /* main.m */; }; 15 | C5242D8718D20FBB00F6C6BF /* BENAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = C5242D8618D20FBB00F6C6BF /* BENAppDelegate.m */; }; 16 | C5242D8918D20FBB00F6C6BF /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = C5242D8818D20FBB00F6C6BF /* Images.xcassets */; }; 17 | C5242D9018D20FBB00F6C6BF /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C5242D8F18D20FBB00F6C6BF /* XCTest.framework */; }; 18 | C5242D9118D20FBB00F6C6BF /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C5242D7618D20FBB00F6C6BF /* Foundation.framework */; }; 19 | C5242D9218D20FBB00F6C6BF /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = C5242D7A18D20FBB00F6C6BF /* UIKit.framework */; }; 20 | C5242D9A18D20FBB00F6C6BF /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = C5242D9818D20FBB00F6C6BF /* InfoPlist.strings */; }; 21 | C5242D9C18D20FBB00F6C6BF /* BENTagsViewDemoTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C5242D9B18D20FBB00F6C6BF /* BENTagsViewDemoTests.m */; }; 22 | C5242DA718D20FF600F6C6BF /* BENTagsDemoController.m in Sources */ = {isa = PBXBuildFile; fileRef = C5242DA618D20FF600F6C6BF /* BENTagsDemoController.m */; }; 23 | C5242DAD18D2102B00F6C6BF /* BENTag.m in Sources */ = {isa = PBXBuildFile; fileRef = C5242DAA18D2102B00F6C6BF /* BENTag.m */; }; 24 | C5242DAE18D2102B00F6C6BF /* BENTagsView.m in Sources */ = {isa = PBXBuildFile; fileRef = C5242DAC18D2102B00F6C6BF /* BENTagsView.m */; }; 25 | E958829F18DB6F090033B561 /* Screenshot1.png in Resources */ = {isa = PBXBuildFile; fileRef = E958829E18DB6F090033B561 /* Screenshot1.png */; }; 26 | /* End PBXBuildFile section */ 27 | 28 | /* Begin PBXContainerItemProxy section */ 29 | C5242D9318D20FBB00F6C6BF /* PBXContainerItemProxy */ = { 30 | isa = PBXContainerItemProxy; 31 | containerPortal = C5242D6B18D20FBB00F6C6BF /* Project object */; 32 | proxyType = 1; 33 | remoteGlobalIDString = C5242D7218D20FBB00F6C6BF; 34 | remoteInfo = BENTagsViewDemo; 35 | }; 36 | /* End PBXContainerItemProxy section */ 37 | 38 | /* Begin PBXFileReference section */ 39 | C5242D7318D20FBB00F6C6BF /* BENTagsViewDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = BENTagsViewDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 40 | C5242D7618D20FBB00F6C6BF /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; 41 | C5242D7818D20FBB00F6C6BF /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; 42 | C5242D7A18D20FBB00F6C6BF /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 43 | C5242D7E18D20FBB00F6C6BF /* BENTagsViewDemo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "BENTagsViewDemo-Info.plist"; sourceTree = ""; }; 44 | C5242D8018D20FBB00F6C6BF /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 45 | C5242D8218D20FBB00F6C6BF /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 46 | C5242D8418D20FBB00F6C6BF /* BENTagsViewDemo-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BENTagsViewDemo-Prefix.pch"; sourceTree = ""; }; 47 | C5242D8518D20FBB00F6C6BF /* BENAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BENAppDelegate.h; sourceTree = ""; }; 48 | C5242D8618D20FBB00F6C6BF /* BENAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BENAppDelegate.m; sourceTree = ""; }; 49 | C5242D8818D20FBB00F6C6BF /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 50 | C5242D8E18D20FBB00F6C6BF /* BENTagsViewDemoTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = BENTagsViewDemoTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 51 | C5242D8F18D20FBB00F6C6BF /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; 52 | C5242D9718D20FBB00F6C6BF /* BENTagsViewDemoTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "BENTagsViewDemoTests-Info.plist"; sourceTree = ""; }; 53 | C5242D9918D20FBB00F6C6BF /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; 54 | C5242D9B18D20FBB00F6C6BF /* BENTagsViewDemoTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BENTagsViewDemoTests.m; sourceTree = ""; }; 55 | C5242DA518D20FF600F6C6BF /* BENTagsDemoController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BENTagsDemoController.h; sourceTree = ""; }; 56 | C5242DA618D20FF600F6C6BF /* BENTagsDemoController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BENTagsDemoController.m; sourceTree = ""; }; 57 | C5242DA918D2102B00F6C6BF /* BENTag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BENTag.h; sourceTree = ""; }; 58 | C5242DAA18D2102B00F6C6BF /* BENTag.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BENTag.m; sourceTree = ""; }; 59 | C5242DAB18D2102B00F6C6BF /* BENTagsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BENTagsView.h; sourceTree = ""; }; 60 | C5242DAC18D2102B00F6C6BF /* BENTagsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BENTagsView.m; sourceTree = ""; }; 61 | E958829E18DB6F090033B561 /* Screenshot1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Screenshot1.png; sourceTree = ""; }; 62 | /* End PBXFileReference section */ 63 | 64 | /* Begin PBXFrameworksBuildPhase section */ 65 | C5242D7018D20FBB00F6C6BF /* Frameworks */ = { 66 | isa = PBXFrameworksBuildPhase; 67 | buildActionMask = 2147483647; 68 | files = ( 69 | C5242D7918D20FBB00F6C6BF /* CoreGraphics.framework in Frameworks */, 70 | C5242D7B18D20FBB00F6C6BF /* UIKit.framework in Frameworks */, 71 | C5242D7718D20FBB00F6C6BF /* Foundation.framework in Frameworks */, 72 | ); 73 | runOnlyForDeploymentPostprocessing = 0; 74 | }; 75 | C5242D8B18D20FBB00F6C6BF /* Frameworks */ = { 76 | isa = PBXFrameworksBuildPhase; 77 | buildActionMask = 2147483647; 78 | files = ( 79 | C5242D9018D20FBB00F6C6BF /* XCTest.framework in Frameworks */, 80 | C5242D9218D20FBB00F6C6BF /* UIKit.framework in Frameworks */, 81 | C5242D9118D20FBB00F6C6BF /* Foundation.framework in Frameworks */, 82 | ); 83 | runOnlyForDeploymentPostprocessing = 0; 84 | }; 85 | /* End PBXFrameworksBuildPhase section */ 86 | 87 | /* Begin PBXGroup section */ 88 | C5242D6A18D20FBB00F6C6BF = { 89 | isa = PBXGroup; 90 | children = ( 91 | C5242DA818D2101700F6C6BF /* BENTagsView */, 92 | C5242D7C18D20FBB00F6C6BF /* BENTagsViewDemo */, 93 | C5242D9518D20FBB00F6C6BF /* BENTagsViewDemoTests */, 94 | C5242D7518D20FBB00F6C6BF /* Frameworks */, 95 | C5242D7418D20FBB00F6C6BF /* Products */, 96 | ); 97 | sourceTree = ""; 98 | }; 99 | C5242D7418D20FBB00F6C6BF /* Products */ = { 100 | isa = PBXGroup; 101 | children = ( 102 | C5242D7318D20FBB00F6C6BF /* BENTagsViewDemo.app */, 103 | C5242D8E18D20FBB00F6C6BF /* BENTagsViewDemoTests.xctest */, 104 | ); 105 | name = Products; 106 | sourceTree = ""; 107 | }; 108 | C5242D7518D20FBB00F6C6BF /* Frameworks */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | C5242D7618D20FBB00F6C6BF /* Foundation.framework */, 112 | C5242D7818D20FBB00F6C6BF /* CoreGraphics.framework */, 113 | C5242D7A18D20FBB00F6C6BF /* UIKit.framework */, 114 | C5242D8F18D20FBB00F6C6BF /* XCTest.framework */, 115 | ); 116 | name = Frameworks; 117 | sourceTree = ""; 118 | }; 119 | C5242D7C18D20FBB00F6C6BF /* BENTagsViewDemo */ = { 120 | isa = PBXGroup; 121 | children = ( 122 | C5242D8518D20FBB00F6C6BF /* BENAppDelegate.h */, 123 | C5242D8618D20FBB00F6C6BF /* BENAppDelegate.m */, 124 | C5242DA518D20FF600F6C6BF /* BENTagsDemoController.h */, 125 | C5242DA618D20FF600F6C6BF /* BENTagsDemoController.m */, 126 | C5242D8818D20FBB00F6C6BF /* Images.xcassets */, 127 | C5242D7D18D20FBB00F6C6BF /* Supporting Files */, 128 | ); 129 | path = BENTagsViewDemo; 130 | sourceTree = ""; 131 | }; 132 | C5242D7D18D20FBB00F6C6BF /* Supporting Files */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | C5242D7E18D20FBB00F6C6BF /* BENTagsViewDemo-Info.plist */, 136 | C5242D7F18D20FBB00F6C6BF /* InfoPlist.strings */, 137 | C5242D8218D20FBB00F6C6BF /* main.m */, 138 | C5242D8418D20FBB00F6C6BF /* BENTagsViewDemo-Prefix.pch */, 139 | E958829E18DB6F090033B561 /* Screenshot1.png */, 140 | ); 141 | name = "Supporting Files"; 142 | sourceTree = ""; 143 | }; 144 | C5242D9518D20FBB00F6C6BF /* BENTagsViewDemoTests */ = { 145 | isa = PBXGroup; 146 | children = ( 147 | C5242D9B18D20FBB00F6C6BF /* BENTagsViewDemoTests.m */, 148 | C5242D9618D20FBB00F6C6BF /* Supporting Files */, 149 | ); 150 | path = BENTagsViewDemoTests; 151 | sourceTree = ""; 152 | }; 153 | C5242D9618D20FBB00F6C6BF /* Supporting Files */ = { 154 | isa = PBXGroup; 155 | children = ( 156 | C5242D9718D20FBB00F6C6BF /* BENTagsViewDemoTests-Info.plist */, 157 | C5242D9818D20FBB00F6C6BF /* InfoPlist.strings */, 158 | ); 159 | name = "Supporting Files"; 160 | sourceTree = ""; 161 | }; 162 | C5242DA818D2101700F6C6BF /* BENTagsView */ = { 163 | isa = PBXGroup; 164 | children = ( 165 | C5242DA918D2102B00F6C6BF /* BENTag.h */, 166 | C5242DAA18D2102B00F6C6BF /* BENTag.m */, 167 | C5242DAB18D2102B00F6C6BF /* BENTagsView.h */, 168 | C5242DAC18D2102B00F6C6BF /* BENTagsView.m */, 169 | ); 170 | path = BENTagsView; 171 | sourceTree = ""; 172 | }; 173 | /* End PBXGroup section */ 174 | 175 | /* Begin PBXNativeTarget section */ 176 | C5242D7218D20FBB00F6C6BF /* BENTagsViewDemo */ = { 177 | isa = PBXNativeTarget; 178 | buildConfigurationList = C5242D9F18D20FBB00F6C6BF /* Build configuration list for PBXNativeTarget "BENTagsViewDemo" */; 179 | buildPhases = ( 180 | C5242D6F18D20FBB00F6C6BF /* Sources */, 181 | C5242D7018D20FBB00F6C6BF /* Frameworks */, 182 | C5242D7118D20FBB00F6C6BF /* Resources */, 183 | ); 184 | buildRules = ( 185 | ); 186 | dependencies = ( 187 | ); 188 | name = BENTagsViewDemo; 189 | productName = BENTagsViewDemo; 190 | productReference = C5242D7318D20FBB00F6C6BF /* BENTagsViewDemo.app */; 191 | productType = "com.apple.product-type.application"; 192 | }; 193 | C5242D8D18D20FBB00F6C6BF /* BENTagsViewDemoTests */ = { 194 | isa = PBXNativeTarget; 195 | buildConfigurationList = C5242DA218D20FBB00F6C6BF /* Build configuration list for PBXNativeTarget "BENTagsViewDemoTests" */; 196 | buildPhases = ( 197 | C5242D8A18D20FBB00F6C6BF /* Sources */, 198 | C5242D8B18D20FBB00F6C6BF /* Frameworks */, 199 | C5242D8C18D20FBB00F6C6BF /* Resources */, 200 | ); 201 | buildRules = ( 202 | ); 203 | dependencies = ( 204 | C5242D9418D20FBB00F6C6BF /* PBXTargetDependency */, 205 | ); 206 | name = BENTagsViewDemoTests; 207 | productName = BENTagsViewDemoTests; 208 | productReference = C5242D8E18D20FBB00F6C6BF /* BENTagsViewDemoTests.xctest */; 209 | productType = "com.apple.product-type.bundle.unit-test"; 210 | }; 211 | /* End PBXNativeTarget section */ 212 | 213 | /* Begin PBXProject section */ 214 | C5242D6B18D20FBB00F6C6BF /* Project object */ = { 215 | isa = PBXProject; 216 | attributes = { 217 | CLASSPREFIX = BEN; 218 | LastUpgradeCheck = 0510; 219 | ORGANIZATIONNAME = "Ben Packard"; 220 | TargetAttributes = { 221 | C5242D8D18D20FBB00F6C6BF = { 222 | TestTargetID = C5242D7218D20FBB00F6C6BF; 223 | }; 224 | }; 225 | }; 226 | buildConfigurationList = C5242D6E18D20FBB00F6C6BF /* Build configuration list for PBXProject "BENTagsViewDemo" */; 227 | compatibilityVersion = "Xcode 3.2"; 228 | developmentRegion = English; 229 | hasScannedForEncodings = 0; 230 | knownRegions = ( 231 | en, 232 | ); 233 | mainGroup = C5242D6A18D20FBB00F6C6BF; 234 | productRefGroup = C5242D7418D20FBB00F6C6BF /* Products */; 235 | projectDirPath = ""; 236 | projectRoot = ""; 237 | targets = ( 238 | C5242D7218D20FBB00F6C6BF /* BENTagsViewDemo */, 239 | C5242D8D18D20FBB00F6C6BF /* BENTagsViewDemoTests */, 240 | ); 241 | }; 242 | /* End PBXProject section */ 243 | 244 | /* Begin PBXResourcesBuildPhase section */ 245 | C5242D7118D20FBB00F6C6BF /* Resources */ = { 246 | isa = PBXResourcesBuildPhase; 247 | buildActionMask = 2147483647; 248 | files = ( 249 | E958829F18DB6F090033B561 /* Screenshot1.png in Resources */, 250 | C5242D8118D20FBB00F6C6BF /* InfoPlist.strings in Resources */, 251 | C5242D8918D20FBB00F6C6BF /* Images.xcassets in Resources */, 252 | ); 253 | runOnlyForDeploymentPostprocessing = 0; 254 | }; 255 | C5242D8C18D20FBB00F6C6BF /* Resources */ = { 256 | isa = PBXResourcesBuildPhase; 257 | buildActionMask = 2147483647; 258 | files = ( 259 | C5242D9A18D20FBB00F6C6BF /* InfoPlist.strings in Resources */, 260 | ); 261 | runOnlyForDeploymentPostprocessing = 0; 262 | }; 263 | /* End PBXResourcesBuildPhase section */ 264 | 265 | /* Begin PBXSourcesBuildPhase section */ 266 | C5242D6F18D20FBB00F6C6BF /* Sources */ = { 267 | isa = PBXSourcesBuildPhase; 268 | buildActionMask = 2147483647; 269 | files = ( 270 | C5242DAE18D2102B00F6C6BF /* BENTagsView.m in Sources */, 271 | C5242DAD18D2102B00F6C6BF /* BENTag.m in Sources */, 272 | C5242D8718D20FBB00F6C6BF /* BENAppDelegate.m in Sources */, 273 | C5242DA718D20FF600F6C6BF /* BENTagsDemoController.m in Sources */, 274 | C5242D8318D20FBB00F6C6BF /* main.m in Sources */, 275 | ); 276 | runOnlyForDeploymentPostprocessing = 0; 277 | }; 278 | C5242D8A18D20FBB00F6C6BF /* Sources */ = { 279 | isa = PBXSourcesBuildPhase; 280 | buildActionMask = 2147483647; 281 | files = ( 282 | C5242D9C18D20FBB00F6C6BF /* BENTagsViewDemoTests.m in Sources */, 283 | ); 284 | runOnlyForDeploymentPostprocessing = 0; 285 | }; 286 | /* End PBXSourcesBuildPhase section */ 287 | 288 | /* Begin PBXTargetDependency section */ 289 | C5242D9418D20FBB00F6C6BF /* PBXTargetDependency */ = { 290 | isa = PBXTargetDependency; 291 | target = C5242D7218D20FBB00F6C6BF /* BENTagsViewDemo */; 292 | targetProxy = C5242D9318D20FBB00F6C6BF /* PBXContainerItemProxy */; 293 | }; 294 | /* End PBXTargetDependency section */ 295 | 296 | /* Begin PBXVariantGroup section */ 297 | C5242D7F18D20FBB00F6C6BF /* InfoPlist.strings */ = { 298 | isa = PBXVariantGroup; 299 | children = ( 300 | C5242D8018D20FBB00F6C6BF /* en */, 301 | ); 302 | name = InfoPlist.strings; 303 | sourceTree = ""; 304 | }; 305 | C5242D9818D20FBB00F6C6BF /* InfoPlist.strings */ = { 306 | isa = PBXVariantGroup; 307 | children = ( 308 | C5242D9918D20FBB00F6C6BF /* en */, 309 | ); 310 | name = InfoPlist.strings; 311 | sourceTree = ""; 312 | }; 313 | /* End PBXVariantGroup section */ 314 | 315 | /* Begin XCBuildConfiguration section */ 316 | C5242D9D18D20FBB00F6C6BF /* Debug */ = { 317 | isa = XCBuildConfiguration; 318 | buildSettings = { 319 | ALWAYS_SEARCH_USER_PATHS = NO; 320 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 321 | CLANG_CXX_LIBRARY = "libc++"; 322 | CLANG_ENABLE_MODULES = YES; 323 | CLANG_ENABLE_OBJC_ARC = YES; 324 | CLANG_WARN_BOOL_CONVERSION = YES; 325 | CLANG_WARN_CONSTANT_CONVERSION = YES; 326 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 327 | CLANG_WARN_EMPTY_BODY = YES; 328 | CLANG_WARN_ENUM_CONVERSION = YES; 329 | CLANG_WARN_INT_CONVERSION = YES; 330 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 331 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 332 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 333 | COPY_PHASE_STRIP = NO; 334 | GCC_C_LANGUAGE_STANDARD = gnu99; 335 | GCC_DYNAMIC_NO_PIC = NO; 336 | GCC_OPTIMIZATION_LEVEL = 0; 337 | GCC_PREPROCESSOR_DEFINITIONS = ( 338 | "DEBUG=1", 339 | "$(inherited)", 340 | ); 341 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 342 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 343 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 344 | GCC_WARN_UNDECLARED_SELECTOR = YES; 345 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 346 | GCC_WARN_UNUSED_FUNCTION = YES; 347 | GCC_WARN_UNUSED_VARIABLE = YES; 348 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 349 | ONLY_ACTIVE_ARCH = YES; 350 | SDKROOT = iphoneos; 351 | }; 352 | name = Debug; 353 | }; 354 | C5242D9E18D20FBB00F6C6BF /* Release */ = { 355 | isa = XCBuildConfiguration; 356 | buildSettings = { 357 | ALWAYS_SEARCH_USER_PATHS = NO; 358 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 359 | CLANG_CXX_LIBRARY = "libc++"; 360 | CLANG_ENABLE_MODULES = YES; 361 | CLANG_ENABLE_OBJC_ARC = YES; 362 | CLANG_WARN_BOOL_CONVERSION = YES; 363 | CLANG_WARN_CONSTANT_CONVERSION = YES; 364 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 365 | CLANG_WARN_EMPTY_BODY = YES; 366 | CLANG_WARN_ENUM_CONVERSION = YES; 367 | CLANG_WARN_INT_CONVERSION = YES; 368 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 369 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 370 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 371 | COPY_PHASE_STRIP = YES; 372 | ENABLE_NS_ASSERTIONS = NO; 373 | GCC_C_LANGUAGE_STANDARD = gnu99; 374 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 375 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 376 | GCC_WARN_UNDECLARED_SELECTOR = YES; 377 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 378 | GCC_WARN_UNUSED_FUNCTION = YES; 379 | GCC_WARN_UNUSED_VARIABLE = YES; 380 | IPHONEOS_DEPLOYMENT_TARGET = 7.1; 381 | SDKROOT = iphoneos; 382 | VALIDATE_PRODUCT = YES; 383 | }; 384 | name = Release; 385 | }; 386 | C5242DA018D20FBB00F6C6BF /* Debug */ = { 387 | isa = XCBuildConfiguration; 388 | buildSettings = { 389 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 390 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 391 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 392 | GCC_PREFIX_HEADER = "BENTagsViewDemo/BENTagsViewDemo-Prefix.pch"; 393 | INFOPLIST_FILE = "BENTagsViewDemo/BENTagsViewDemo-Info.plist"; 394 | PRODUCT_NAME = "$(TARGET_NAME)"; 395 | WRAPPER_EXTENSION = app; 396 | }; 397 | name = Debug; 398 | }; 399 | C5242DA118D20FBB00F6C6BF /* Release */ = { 400 | isa = XCBuildConfiguration; 401 | buildSettings = { 402 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 403 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 404 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 405 | GCC_PREFIX_HEADER = "BENTagsViewDemo/BENTagsViewDemo-Prefix.pch"; 406 | INFOPLIST_FILE = "BENTagsViewDemo/BENTagsViewDemo-Info.plist"; 407 | PRODUCT_NAME = "$(TARGET_NAME)"; 408 | WRAPPER_EXTENSION = app; 409 | }; 410 | name = Release; 411 | }; 412 | C5242DA318D20FBB00F6C6BF /* Debug */ = { 413 | isa = XCBuildConfiguration; 414 | buildSettings = { 415 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/BENTagsViewDemo.app/BENTagsViewDemo"; 416 | FRAMEWORK_SEARCH_PATHS = ( 417 | "$(SDKROOT)/Developer/Library/Frameworks", 418 | "$(inherited)", 419 | "$(DEVELOPER_FRAMEWORKS_DIR)", 420 | ); 421 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 422 | GCC_PREFIX_HEADER = "BENTagsViewDemo/BENTagsViewDemo-Prefix.pch"; 423 | GCC_PREPROCESSOR_DEFINITIONS = ( 424 | "DEBUG=1", 425 | "$(inherited)", 426 | ); 427 | INFOPLIST_FILE = "BENTagsViewDemoTests/BENTagsViewDemoTests-Info.plist"; 428 | PRODUCT_NAME = "$(TARGET_NAME)"; 429 | TEST_HOST = "$(BUNDLE_LOADER)"; 430 | WRAPPER_EXTENSION = xctest; 431 | }; 432 | name = Debug; 433 | }; 434 | C5242DA418D20FBB00F6C6BF /* Release */ = { 435 | isa = XCBuildConfiguration; 436 | buildSettings = { 437 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/BENTagsViewDemo.app/BENTagsViewDemo"; 438 | FRAMEWORK_SEARCH_PATHS = ( 439 | "$(SDKROOT)/Developer/Library/Frameworks", 440 | "$(inherited)", 441 | "$(DEVELOPER_FRAMEWORKS_DIR)", 442 | ); 443 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 444 | GCC_PREFIX_HEADER = "BENTagsViewDemo/BENTagsViewDemo-Prefix.pch"; 445 | INFOPLIST_FILE = "BENTagsViewDemoTests/BENTagsViewDemoTests-Info.plist"; 446 | PRODUCT_NAME = "$(TARGET_NAME)"; 447 | TEST_HOST = "$(BUNDLE_LOADER)"; 448 | WRAPPER_EXTENSION = xctest; 449 | }; 450 | name = Release; 451 | }; 452 | /* End XCBuildConfiguration section */ 453 | 454 | /* Begin XCConfigurationList section */ 455 | C5242D6E18D20FBB00F6C6BF /* Build configuration list for PBXProject "BENTagsViewDemo" */ = { 456 | isa = XCConfigurationList; 457 | buildConfigurations = ( 458 | C5242D9D18D20FBB00F6C6BF /* Debug */, 459 | C5242D9E18D20FBB00F6C6BF /* Release */, 460 | ); 461 | defaultConfigurationIsVisible = 0; 462 | defaultConfigurationName = Release; 463 | }; 464 | C5242D9F18D20FBB00F6C6BF /* Build configuration list for PBXNativeTarget "BENTagsViewDemo" */ = { 465 | isa = XCConfigurationList; 466 | buildConfigurations = ( 467 | C5242DA018D20FBB00F6C6BF /* Debug */, 468 | C5242DA118D20FBB00F6C6BF /* Release */, 469 | ); 470 | defaultConfigurationIsVisible = 0; 471 | defaultConfigurationName = Release; 472 | }; 473 | C5242DA218D20FBB00F6C6BF /* Build configuration list for PBXNativeTarget "BENTagsViewDemoTests" */ = { 474 | isa = XCConfigurationList; 475 | buildConfigurations = ( 476 | C5242DA318D20FBB00F6C6BF /* Debug */, 477 | C5242DA418D20FBB00F6C6BF /* Release */, 478 | ); 479 | defaultConfigurationIsVisible = 0; 480 | defaultConfigurationName = Release; 481 | }; 482 | /* End XCConfigurationList section */ 483 | }; 484 | rootObject = C5242D6B18D20FBB00F6C6BF /* Project object */; 485 | } 486 | -------------------------------------------------------------------------------- /BENTagsViewDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /BENTagsViewDemo/BENAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // BENAppDelegate.h 3 | // BENTagsView 4 | // 5 | // Created by Ben Packard on 3/13/14. 6 | // Copyright (c) 2014 Ben Packard. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BENAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /BENTagsViewDemo/BENAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // BENAppDelegate.m 3 | // BENTagsView 4 | // 5 | // Created by Ben Packard on 3/13/14. 6 | // Copyright (c) 2014 Ben Packard. All rights reserved. 7 | // 8 | 9 | #import "BENAppDelegate.h" 10 | 11 | //controllers 12 | #import "BENTagsDemoController.h" 13 | 14 | @implementation BENAppDelegate 15 | 16 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 17 | { 18 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; 19 | BENTagsDemoController *controller = [[BENTagsDemoController alloc] initWithNibName:nil bundle:nil]; 20 | self.window.rootViewController = controller; 21 | [self.window makeKeyAndVisible]; 22 | return YES; 23 | } 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /BENTagsViewDemo/BENTagsDemoController.h: -------------------------------------------------------------------------------- 1 | // 2 | // BENTagsDemoController.h 3 | // BENTagsView 4 | // 5 | // Created by Ben Packard on 3/13/14. 6 | // Copyright (c) 2014 Ben Packard. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BENTagsDemoController : UIViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /BENTagsViewDemo/BENTagsDemoController.m: -------------------------------------------------------------------------------- 1 | // 2 | // BENTagsDemoController.m 3 | // BENTagsView 4 | // 5 | // Created by Ben Packard on 3/13/14. 6 | // Copyright (c) 2014 Ben Packard. All rights reserved. 7 | // 8 | 9 | #import "BENTagsDemoController.h" 10 | 11 | //views 12 | #import "BENTagsView.h" 13 | 14 | @interface BENTagsDemoController () 15 | 16 | @end 17 | 18 | @implementation BENTagsDemoController 19 | 20 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 21 | { 22 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 23 | if (self) 24 | { 25 | 26 | } 27 | return self; 28 | } 29 | 30 | - (void)viewDidLoad 31 | { 32 | [super viewDidLoad]; 33 | 34 | self.view.backgroundColor = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1.0]; 35 | 36 | UILabel *helpLabel = [[UILabel alloc] init]; 37 | helpLabel.translatesAutoresizingMaskIntoConstraints = NO; 38 | helpLabel.text = @"Here are some tags."; 39 | [self.view addSubview:helpLabel]; 40 | 41 | BENTagsView *tagsView = [[BENTagsView alloc] init]; 42 | tagsView.translatesAutoresizingMaskIntoConstraints = NO; 43 | tagsView.tagStrings = @[@"tag one", @"tag two", @"tag three"]; 44 | [self.view addSubview:tagsView]; 45 | 46 | UILabel *helpLabel2 = [[UILabel alloc] init]; 47 | helpLabel2.translatesAutoresizingMaskIntoConstraints = NO; 48 | helpLabel2.text = @"Tags can be on or off."; 49 | [self.view addSubview:helpLabel2]; 50 | 51 | BENTagsView *tagsView2 = [[BENTagsView alloc] init]; 52 | tagsView2.translatesAutoresizingMaskIntoConstraints = NO; 53 | tagsView2.tagStrings = @[@"on", @"off", @"on"]; 54 | NSMutableIndexSet *onIndexes = [NSMutableIndexSet indexSetWithIndex:0]; 55 | [onIndexes addIndex:2]; 56 | [tagsView2 setOnIndexes:onIndexes]; 57 | [self.view addSubview:tagsView2]; 58 | 59 | UILabel *helpLabel3 = [[UILabel alloc] init]; 60 | helpLabel3.translatesAutoresizingMaskIntoConstraints = NO; 61 | helpLabel3.text = @"On and off colors can be customized."; 62 | helpLabel3.numberOfLines = 0; 63 | helpLabel3.lineBreakMode = NSLineBreakByWordWrapping; 64 | [self.view addSubview:helpLabel3]; 65 | 66 | BENTagsView *tagsView3 = [[BENTagsView alloc] init]; 67 | tagsView3.translatesAutoresizingMaskIntoConstraints = NO; 68 | tagsView3.tagStrings = tagsView.tagStrings; 69 | [tagsView3 setOnIndexes:tagsView2.onIndexes]; 70 | [tagsView3 setOnColor:[UIColor greenColor]]; 71 | [tagsView3 setOffColor:[UIColor redColor]]; 72 | [self.view addSubview:tagsView3]; 73 | 74 | UILabel *helpLabel4 = [[UILabel alloc] init]; 75 | helpLabel4.translatesAutoresizingMaskIntoConstraints = NO; 76 | helpLabel4.text = @"Fonts, corners, and sizes can be customized."; 77 | helpLabel4.numberOfLines = 0; 78 | helpLabel4.lineBreakMode = NSLineBreakByWordWrapping; 79 | [self.view addSubview:helpLabel4]; 80 | 81 | BENTagsView *tagsView4 = [[BENTagsView alloc] init]; 82 | tagsView4.translatesAutoresizingMaskIntoConstraints = NO; 83 | tagsView4.tagStrings = tagsView.tagStrings; 84 | [tagsView4 setOnIndexes:tagsView2.onIndexes]; 85 | [tagsView4 setFont:[UIFont fontWithName:@"Baskerville-BoldItalic" size:16]]; 86 | [tagsView4 setTagCornerRadius:3]; 87 | [self.view addSubview:tagsView4]; 88 | 89 | //layout 90 | NSDictionary *views = @{@"help":helpLabel, @"tags":tagsView, @"help2":helpLabel2, @"tags2":tagsView2, @"help3":helpLabel3, @"tags3":tagsView3, @"help4":helpLabel4, @"tags4":tagsView4}; 91 | [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-45-[help]-[tags]-20-[help2]-[tags2]-20-[help3]-[tags3]-20-[help4]-[tags4]" 92 | options:0 93 | metrics:nil 94 | views:views]]; 95 | for (UIView *view in @[tagsView, tagsView2, tagsView3, tagsView4]) 96 | { 97 | [self.view addConstraint:[NSLayoutConstraint constraintWithItem:view 98 | attribute:NSLayoutAttributeCenterX 99 | relatedBy:NSLayoutRelationEqual 100 | toItem:self.view 101 | attribute:NSLayoutAttributeCenterX 102 | multiplier:1 103 | constant:0]]; 104 | } 105 | for (UIView *view in @[helpLabel, helpLabel2, helpLabel3, helpLabel4]) 106 | { 107 | [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-[view]-|" 108 | options:0 109 | metrics:nil 110 | views:NSDictionaryOfVariableBindings(view)]]; 111 | } 112 | } 113 | 114 | @end 115 | -------------------------------------------------------------------------------- /BENTagsViewDemo/BENTagsViewDemo-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.benpackard.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0.1 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 | 38 | 39 | -------------------------------------------------------------------------------- /BENTagsViewDemo/BENTagsViewDemo-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_3_0 10 | #warning "This project uses features only available in iOS SDK 3.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | -------------------------------------------------------------------------------- /BENTagsViewDemo/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /BENTagsViewDemo/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /BENTagsViewDemo/Screenshot1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/benpackard/BENTagsView/73d2494f47b0e47f5061e38d7f6d0747933f4327/BENTagsViewDemo/Screenshot1.png -------------------------------------------------------------------------------- /BENTagsViewDemo/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /BENTagsViewDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // BENTagsViewDemo 4 | // 5 | // Created by Ben Packard on 3/13/14. 6 | // Copyright (c) 2014 Ben Packard. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "BENAppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([BENAppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /BENTagsViewDemoTests/BENTagsViewDemoTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.benpackard.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /BENTagsViewDemoTests/BENTagsViewDemoTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // BENTagsViewDemoTests.m 3 | // BENTagsViewDemoTests 4 | // 5 | // Created by Ben Packard on 3/13/14. 6 | // Copyright (c) 2014 Ben Packard. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface BENTagsViewDemoTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation BENTagsViewDemoTests 16 | 17 | - (void)setUp 18 | { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown 24 | { 25 | // Put teardown code here. This method is called after the invocation of each test method in the class. 26 | [super tearDown]; 27 | } 28 | 29 | - (void)testExample 30 | { 31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /BENTagsViewDemoTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Ben Packard 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # BENTagsView 2 | 3 | **A simple UIView sublass for displaying a series of tags.** 4 | 5 | `BENTagsView` allows you to quickly add a series of tags to any `UIView`. 6 | 7 | 8 | 9 | ## Installation 10 | 11 | [CocoaPods](http://cocoapods.org) is the recommended method of installing BENTagsView. Simply add the following line to your `Podfile`: 12 | 13 | #### Podfile 14 | 15 | ``` ruby 16 | pod 'BENTagsView' 17 | ``` 18 | 19 | ## Usage 20 | 21 | ``` objective-c 22 | //create the tags view 23 | BENTagsView *tagsView = [[BENTagsView alloc] init]; 24 | 25 | //set the tag strings 26 | tagsView4.tagStrings = @[@"tag one", @"tag two", @"tag three"]; 27 | 28 | //switch some tags on - all others will be off 29 | NSMutableIndexSet *onIndexes = [NSMutableIndexSet indexSetWithIndex:0]; 30 | [onIndexes addIndex:2]; 31 | [tagsView setOnIndexes:onIndexes]; 32 | 33 | //customize on/off colors 34 | [tagsView setOnColor:[UIColor greenColor]]; 35 | [tagsView setOffColor:[UIColor redColor]]; 36 | 37 | //customize font, corner radii 38 | [tagsView setFont:[UIFont fontWithName:@"Baskerville-BoldItalic" size:16]]; 39 | [tagsView setTagCornerRadius:3]; 40 | 41 | //add the view 42 | [someView addSubview:tagsView]; 43 | ``` 44 | 45 | ## Demo 46 | 47 | Build and run the `BENTagsViewDemo` project in Xcode to see `BENTagsView` in action. 48 | 49 | ## Contact 50 | 51 | Ben Packard 52 | 53 | - http://twitter.com/benpackard 54 | - ben@benpackard.org 55 | 56 | ## License 57 | 58 | BENTagsView is available under the MIT license. See the LICENSE file for more info. 59 | --------------------------------------------------------------------------------