├── DLSkillTagView.png ├── dlskilltagview.gif ├── DLSkillTagView ├── .DS_Store ├── DLSkillTagView │ ├── .DS_Store │ ├── Assets.xcassets │ │ ├── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── DLSkillTagViewIcon-1.png │ │ │ ├── DLSkillTagViewIcon-2.png │ │ │ ├── DLSkillTagViewIcon.png │ │ │ ├── DLSkillTagViewIcon@2x.png │ │ │ ├── DLSkillTagViewIcon@3x.png │ │ │ ├── DLSkillTagViewIcon@2x-1.png │ │ │ ├── DLSkillTagViewIcon@2x-2.png │ │ │ ├── DLSkillTagViewIcon@3x-1.png │ │ │ └── Contents.json │ ├── Lib │ │ ├── .DS_Store │ │ ├── SKTagView │ │ │ ├── SKTagButton.h │ │ │ ├── SKTag.m │ │ │ ├── SKTagView.h │ │ │ ├── SKTag.h │ │ │ ├── SKTagButton.m │ │ │ └── SKTagView.m │ │ └── Classes │ │ │ ├── HexColors.h │ │ │ └── HexColors.m │ ├── ViewController.h │ ├── AppDelegate.h │ ├── main.m │ ├── Info.plist │ ├── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard │ ├── AppDelegate.m │ └── ViewController.m ├── DLSkillTagView.xcodeproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── ft_david.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ ├── xcuserdata │ │ └── ft_david.xcuserdatad │ │ │ └── xcschemes │ │ │ ├── xcschememanagement.plist │ │ │ └── DLSkillTagView.xcscheme │ └── project.pbxproj ├── DLSkillTagViewTests │ ├── Info.plist │ └── DLSkillTagViewTests.m └── DLSkillTagViewUITests │ ├── Info.plist │ └── DLSkillTagViewUITests.m ├── README.md └── LICENSE /DLSkillTagView.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liqiankun/DLSkillTagView/HEAD/DLSkillTagView.png -------------------------------------------------------------------------------- /dlskilltagview.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liqiankun/DLSkillTagView/HEAD/dlskilltagview.gif -------------------------------------------------------------------------------- /DLSkillTagView/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liqiankun/DLSkillTagView/HEAD/DLSkillTagView/.DS_Store -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liqiankun/DLSkillTagView/HEAD/DLSkillTagView/DLSkillTagView/.DS_Store -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/Lib/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liqiankun/DLSkillTagView/HEAD/DLSkillTagView/DLSkillTagView/Lib/.DS_Store -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/Assets.xcassets/AppIcon.appiconset/DLSkillTagViewIcon-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liqiankun/DLSkillTagView/HEAD/DLSkillTagView/DLSkillTagView/Assets.xcassets/AppIcon.appiconset/DLSkillTagViewIcon-1.png -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/Assets.xcassets/AppIcon.appiconset/DLSkillTagViewIcon-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liqiankun/DLSkillTagView/HEAD/DLSkillTagView/DLSkillTagView/Assets.xcassets/AppIcon.appiconset/DLSkillTagViewIcon-2.png -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/Assets.xcassets/AppIcon.appiconset/DLSkillTagViewIcon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liqiankun/DLSkillTagView/HEAD/DLSkillTagView/DLSkillTagView/Assets.xcassets/AppIcon.appiconset/DLSkillTagViewIcon.png -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/Assets.xcassets/AppIcon.appiconset/DLSkillTagViewIcon@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liqiankun/DLSkillTagView/HEAD/DLSkillTagView/DLSkillTagView/Assets.xcassets/AppIcon.appiconset/DLSkillTagViewIcon@2x.png -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/Assets.xcassets/AppIcon.appiconset/DLSkillTagViewIcon@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liqiankun/DLSkillTagView/HEAD/DLSkillTagView/DLSkillTagView/Assets.xcassets/AppIcon.appiconset/DLSkillTagViewIcon@3x.png -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/Assets.xcassets/AppIcon.appiconset/DLSkillTagViewIcon@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liqiankun/DLSkillTagView/HEAD/DLSkillTagView/DLSkillTagView/Assets.xcassets/AppIcon.appiconset/DLSkillTagViewIcon@2x-1.png -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/Assets.xcassets/AppIcon.appiconset/DLSkillTagViewIcon@2x-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liqiankun/DLSkillTagView/HEAD/DLSkillTagView/DLSkillTagView/Assets.xcassets/AppIcon.appiconset/DLSkillTagViewIcon@2x-2.png -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/Assets.xcassets/AppIcon.appiconset/DLSkillTagViewIcon@3x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liqiankun/DLSkillTagView/HEAD/DLSkillTagView/DLSkillTagView/Assets.xcassets/AppIcon.appiconset/DLSkillTagViewIcon@3x-1.png -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView.xcodeproj/project.xcworkspace/xcuserdata/ft_david.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Liqiankun/DLSkillTagView/HEAD/DLSkillTagView/DLSkillTagView.xcodeproj/project.xcworkspace/xcuserdata/ft_david.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // DLSkillTagView 4 | // 5 | // Created by FT_David on 2016/11/17. 6 | // Copyright © 2016年 FT_David. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/Lib/SKTagView/SKTagButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Shaokang Zhao on 15/1/12. 3 | // Copyright (c) 2015 Shaokang Zhao. All rights reserved. 4 | // 5 | 6 | #import 7 | #import 8 | 9 | @class SKTag; 10 | @interface SKTagButton: UIButton 11 | 12 | + (nonnull instancetype)buttonWithTag: (nonnull SKTag *)tag; 13 | 14 | @end -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // DLSkillTagView 4 | // 5 | // Created by FT_David on 2016/11/17. 6 | // Copyright © 2016年 FT_David. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // DLSkillTagView 4 | // 5 | // Created by FT_David on 2016/11/17. 6 | // Copyright © 2016年 FT_David. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagViewTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagViewUITests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/Lib/SKTagView/SKTag.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Shaokang Zhao on 15/1/12. 3 | // Copyright (c) 2015 Shaokang Zhao. All rights reserved. 4 | // 5 | 6 | #import "SKTag.h" 7 | 8 | static const CGFloat kDefaultFontSize = 13.0; 9 | 10 | @implementation SKTag 11 | 12 | - (instancetype)init { 13 | self = [super init]; 14 | if (self) { 15 | _fontSize = kDefaultFontSize; 16 | _textColor = [UIColor blackColor]; 17 | _bgColor = [UIColor whiteColor]; 18 | _enable = YES; 19 | } 20 | return self; 21 | } 22 | 23 | - (instancetype)initWithText: (NSString *)text { 24 | self = [self init]; 25 | if (self) { 26 | _text = text; 27 | } 28 | return self; 29 | } 30 | 31 | + (instancetype)tagWithText: (NSString *)text { 32 | return [[self alloc] initWithText: text]; 33 | } 34 | 35 | @end -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView.xcodeproj/xcuserdata/ft_david.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | DLSkillTagView.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | AAB977A01DDDBF5100A3CF89 16 | 17 | primary 18 | 19 | 20 | AAB977B91DDDBF5100A3CF89 21 | 22 | primary 23 | 24 | 25 | AAB977C41DDDBF5100A3CF89 26 | 27 | primary 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![](https://github.com/Liqiankun/DLSkillTagView/raw/master/DLSkillTagView.png)
2 | Choose skills view based on [SKTagView](https://github.com/zsk425/SKTagView). With DLSkillTagView you can type the tag you want,than add to the tagView.
3 | 一个基于[SKTagView](https://github.com/zsk425/SKTagView)的技能选择的View。用DLSkillTagView可以添加自己想要的技能。 4 | ![](https://github.com/Liqiankun/DLSkillTagView/raw/master/dlskilltagview.gif) 5 | 6 | # Features 7 | - [x] Easy to use 8 | - [x] Add tag you want 9 | - [x] 使用简单 10 | - [x] 支持标签添加 11 | 12 | # How to use 13 | Drag `Lib` folder to your project. Then `#import "SKTagView.h"`,`#import "HexColors.h"`. For more details please check out the demo code.
14 | 将`Lib`文件夹拖入你的的项目,然后`#import "SKTagView.h"`,`#import "HexColors.h"`。如果要了解更详细的内容请查看Demo中的代码。 15 | 16 | #Requirements 17 | - Xcode 7.0 or greater 18 | - iOS8.0(manually only) or greater 19 | 20 | #Author 21 | David Lee, qiankunli@yahoo.com 22 | -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/Lib/SKTagView/SKTagView.h: -------------------------------------------------------------------------------- 1 | // 2 | // SKTagView.h 3 | // 4 | // Created by Shaokang Zhao on 15/1/12. 5 | // Copyright (c) 2015 Shaokang Zhao. All rights reserved. 6 | // 7 | 8 | #import 9 | #import "SKTag.h" 10 | #import "SKTagButton.h" 11 | @interface SKTagView : UIView 12 | 13 | @property (assign, nonatomic) UIEdgeInsets padding; 14 | @property (assign, nonatomic) CGFloat lineSpacing; 15 | @property (assign, nonatomic) CGFloat interitemSpacing; 16 | @property (assign, nonatomic) CGFloat preferredMaxLayoutWidth; 17 | @property (assign, nonatomic) BOOL singleLine; 18 | @property (copy, nonatomic, nullable) void (^didTapTagAtIndex)(NSUInteger index); 19 | 20 | - (void)addTag: (nonnull SKTag *)tag; 21 | - (void)insertTag: (nonnull SKTag *)tag atIndex:(NSUInteger)index; 22 | - (void)removeTag: (nonnull SKTag *)tag; 23 | - (void)removeTagAtIndex: (NSUInteger)index; 24 | - (void)removeAllTags; 25 | 26 | @end 27 | 28 | -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagViewTests/DLSkillTagViewTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // DLSkillTagViewTests.m 3 | // DLSkillTagViewTests 4 | // 5 | // Created by FT_David on 2016/11/17. 6 | // Copyright © 2016年 FT_David. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DLSkillTagViewTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation DLSkillTagViewTests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | // Put setup code here. This method is called before the invocation of each test method in the class. 20 | } 21 | 22 | - (void)tearDown { 23 | // Put teardown code here. This method is called after the invocation of each test method in the class. 24 | [super tearDown]; 25 | } 26 | 27 | - (void)testExample { 28 | // This is an example of a functional test case. 29 | // Use XCTAssert and related functions to verify your tests produce the correct results. 30 | } 31 | 32 | - (void)testPerformanceExample { 33 | // This is an example of a performance test case. 34 | [self measureBlock:^{ 35 | // Put the code you want to measure the time of here. 36 | }]; 37 | } 38 | 39 | @end 40 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 David 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "DLSkillTagViewIcon.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "DLSkillTagViewIcon@2x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "DLSkillTagViewIcon-2.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "DLSkillTagViewIcon@2x-2.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "DLSkillTagViewIcon-1.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "DLSkillTagViewIcon@2x-1.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "DLSkillTagViewIcon@3x-1.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "DLSkillTagViewIcon@3x.png", 49 | "scale" : "3x" 50 | } 51 | ], 52 | "info" : { 53 | "version" : 1, 54 | "author" : "xcode" 55 | } 56 | } -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagViewUITests/DLSkillTagViewUITests.m: -------------------------------------------------------------------------------- 1 | // 2 | // DLSkillTagViewUITests.m 3 | // DLSkillTagViewUITests 4 | // 5 | // Created by FT_David on 2016/11/17. 6 | // Copyright © 2016年 FT_David. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DLSkillTagViewUITests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation DLSkillTagViewUITests 16 | 17 | - (void)setUp { 18 | [super setUp]; 19 | 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | 22 | // In UI tests it is usually best to stop immediately when a failure occurs. 23 | self.continueAfterFailure = NO; 24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. 25 | [[[XCUIApplication alloc] init] launch]; 26 | 27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. 28 | } 29 | 30 | - (void)tearDown { 31 | // Put teardown code here. This method is called after the invocation of each test method in the class. 32 | [super tearDown]; 33 | } 34 | 35 | - (void)testExample { 36 | // Use recording to get started writing UI tests. 37 | // Use XCTAssert and related functions to verify your tests produce the correct results. 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/Lib/SKTagView/SKTag.h: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Shaokang Zhao on 15/1/12. 3 | // Copyright (c) 2015 Shaokang Zhao. All rights reserved. 4 | // 5 | 6 | #import 7 | #import 8 | 9 | @interface SKTag : NSObject 10 | 11 | @property (copy, nonatomic, nullable) NSString *text; 12 | @property (copy, nonatomic, nullable) NSAttributedString *attributedText; 13 | @property (strong, nonatomic, nullable) UIColor *textColor; 14 | @property(nonatomic,strong,nullable)UIColor *slcTextColor; 15 | ///backgound color 16 | @property (strong, nonatomic, nullable) UIColor *bgColor; 17 | @property(nonatomic,strong,nullable) UIColor *slcColor; 18 | @property(nonatomic,strong,nullable)UIColor *nrmColor; 19 | @property (strong, nonatomic, nullable) UIColor *highlightedBgColor; 20 | ///background image 21 | @property (strong, nonatomic, nullable) UIImage *bgImg; 22 | @property (assign, nonatomic) CGFloat cornerRadius; 23 | @property (strong, nonatomic, nullable) UIColor *borderColor; 24 | @property (assign, nonatomic) CGFloat borderWidth; 25 | ///like padding in css 26 | @property (assign, nonatomic) UIEdgeInsets padding; 27 | @property (strong, nonatomic, nullable) UIFont *font; 28 | ///if no font is specified, system font with fontSize is used 29 | @property (assign, nonatomic) CGFloat fontSize; 30 | ///default:YES 31 | @property (assign, nonatomic) BOOL enable; 32 | 33 | - (nonnull instancetype)initWithText: (nonnull NSString *)text; 34 | + (nonnull instancetype)tagWithText: (nonnull NSString *)text; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // DLSkillTagView 4 | // 5 | // Created by FT_David on 2016/11/17. 6 | // Copyright © 2016年 FT_David. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // 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. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // 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. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/Lib/SKTagView/SKTagButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // Created by Shaokang Zhao on 15/1/12. 3 | // Copyright (c) 2015 Shaokang Zhao. All rights reserved. 4 | // 5 | 6 | #import "SKTagButton.h" 7 | #import "SKTag.h" 8 | 9 | @implementation SKTagButton 10 | 11 | + (instancetype)buttonWithTag: (SKTag *)tag { 12 | SKTagButton *btn = [super buttonWithType:UIButtonTypeCustom]; 13 | 14 | if (tag.attributedText) { 15 | [btn setAttributedTitle: tag.attributedText forState: UIControlStateNormal]; 16 | } else { 17 | [btn setTitle: tag.text forState:UIControlStateNormal]; 18 | [btn setTitleColor: tag.textColor forState: UIControlStateNormal]; 19 | btn.titleLabel.font = tag.font ?: [UIFont systemFontOfSize: tag.fontSize]; 20 | } 21 | 22 | if (tag.slcTextColor) { 23 | [btn setTitleColor: tag.slcTextColor forState: UIControlStateSelected]; 24 | } 25 | if (tag.bgColor) { 26 | btn.backgroundColor = tag.bgColor; 27 | } 28 | 29 | if (tag.slcColor) { 30 | [btn setBackgroundImage:[self imageWithColor:tag.slcColor] forState:UIControlStateSelected]; 31 | } 32 | if (tag.nrmColor) { 33 | [btn setBackgroundImage:[self imageWithColor:tag.nrmColor] forState:UIControlStateNormal]; 34 | } 35 | 36 | 37 | btn.contentEdgeInsets = tag.padding; 38 | btn.titleLabel.lineBreakMode = NSLineBreakByTruncatingTail; 39 | 40 | if (tag.bgImg) { 41 | [btn setBackgroundImage: tag.bgImg forState: UIControlStateNormal]; 42 | } 43 | 44 | if (tag.borderColor) { 45 | btn.layer.borderColor = tag.borderColor.CGColor; 46 | } 47 | 48 | if (tag.borderWidth) { 49 | btn.layer.borderWidth = tag.borderWidth; 50 | } 51 | 52 | btn.userInteractionEnabled = tag.enable; 53 | if (tag.enable) { 54 | UIColor *highlightedBgColor = tag.highlightedBgColor ?: [self darkerColor:btn.backgroundColor]; 55 | [btn setBackgroundImage:[self imageWithColor:highlightedBgColor] forState:UIControlStateHighlighted]; 56 | } 57 | 58 | btn.layer.cornerRadius = tag.cornerRadius; 59 | btn.layer.masksToBounds = YES; 60 | 61 | return btn; 62 | } 63 | 64 | + (UIImage *)imageWithColor:(UIColor *)color { 65 | CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f); 66 | UIGraphicsBeginImageContext(rect.size); 67 | CGContextRef context = UIGraphicsGetCurrentContext(); 68 | 69 | CGContextSetFillColorWithColor(context, [color CGColor]); 70 | CGContextFillRect(context, rect); 71 | 72 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 73 | UIGraphicsEndImageContext(); 74 | 75 | return image; 76 | } 77 | 78 | + (UIColor *)darkerColor:(UIColor *)color { 79 | CGFloat h, s, b, a; 80 | if ([color getHue:&h saturation:&s brightness:&b alpha:&a]) 81 | return [UIColor colorWithHue:h 82 | saturation:s 83 | brightness:b * 0.85 84 | alpha:a]; 85 | return color; 86 | } 87 | 88 | @end 89 | -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // DLSkillTagView 4 | // 5 | // Created by FT_David on 2016/11/17. 6 | // Copyright © 2016年 FT_David. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "SKTagView.h" 11 | #import "HexColors.h" 12 | 13 | @interface ViewController () 14 | @property (strong, nonatomic) SKTagView *tagView; 15 | @property (strong, nonatomic) NSArray *colors; 16 | @property(nonatomic,assign)NSUInteger originalButtonCount; 17 | -(void)dl_setupTagView; 18 | -(void)dl_configTag:(SKTag*)tag withIndex:(NSUInteger)index; 19 | @end 20 | 21 | @implementation ViewController 22 | #pragma mark - Lifecycle 23 | - (void)viewDidLoad { 24 | [super viewDidLoad]; 25 | self.colors = @[@"#7ecef4", @"#84ccc9", @"#88abda", @"#7dc1dd", @"#b6b8de"]; 26 | [self dl_setupTagView]; 27 | } 28 | 29 | #pragma mark - Private 30 | - (void)dl_setupTagView { 31 | self.tagView = ({ 32 | SKTagView *view = [SKTagView new]; 33 | view.backgroundColor = [UIColor whiteColor]; 34 | view.padding = UIEdgeInsetsMake(40, 20, 40, 20); 35 | view.interitemSpacing = 15; 36 | view.lineSpacing = 10; 37 | view.didTapTagAtIndex = ^(NSUInteger index){ 38 | if (index == 0) { 39 | UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"输入技能" message:nil delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil]; 40 | alertView.alertViewStyle = UIAlertViewStylePlainTextInput; 41 | [alertView show]; 42 | } 43 | }; 44 | view; 45 | }); 46 | self.tagView.frame = self.view.bounds; 47 | [self.view addSubview:self.tagView]; 48 | 49 | NSArray *tagsArray = @[@"+ 添加",@"Python", @"Javascript", @"Python", @"Swift", @"Go", @"Objective-C", @"C", @"PHP"]; 50 | self.originalButtonCount = tagsArray.count; 51 | [tagsArray enumerateObjectsUsingBlock: ^(NSString *text, NSUInteger idx, BOOL *stop) { 52 | SKTag *tag = [SKTag tagWithText: text]; 53 | if (idx == 0) { 54 | tag.textColor = [UIColor hx_colorWithHexString: self.colors[idx % self.colors.count]]; 55 | tag.borderColor = tag.textColor; 56 | tag.borderWidth = 1; 57 | tag.fontSize = 15; 58 | tag.padding = UIEdgeInsetsMake(13.5, 12.5, 13.5, 12.5); 59 | tag.nrmColor = [UIColor clearColor]; 60 | tag.cornerRadius = 5; 61 | }else{ 62 | [self dl_configTag:tag withIndex:idx]; 63 | } 64 | [self.tagView addTag:tag]; 65 | }]; 66 | } 67 | 68 | -(void)dl_configTag:(SKTag *)tag withIndex:(NSUInteger)index 69 | { 70 | tag.textColor = [UIColor whiteColor]; 71 | tag.fontSize = 15; 72 | tag.padding = UIEdgeInsetsMake(13.5, 12.5, 13.5, 12.5); 73 | tag.nrmColor = [UIColor hx_colorWithHexString: self.colors[index % self.colors.count]]; 74 | tag.cornerRadius = 5; 75 | } 76 | 77 | #pragma mark - UIAlertViewDelegate 78 | -(void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex 79 | { 80 | if (buttonIndex == 1) { 81 | SKTag *tag = [SKTag tagWithText: [alertView textFieldAtIndex:0].text]; 82 | [self dl_configTag:tag withIndex:self.originalButtonCount]; 83 | [self.tagView insertTag:tag atIndex:1]; 84 | self.originalButtonCount ++ ; 85 | } 86 | } 87 | 88 | 89 | 90 | 91 | @end 92 | -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/Lib/Classes/HexColors.h: -------------------------------------------------------------------------------- 1 | // 2 | // HexColor.h 3 | // 4 | // Created by Marius Landwehr on 02.12.12. 5 | // The MIT License (MIT) 6 | // Copyright (c) 2013 Marius Landwehr marius.landwehr@gmail.com 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | // 14 | 15 | #import "TargetConditionals.h" 16 | 17 | #if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR 18 | #import 19 | #define HXColor UIColor 20 | #else 21 | #import 22 | #define HXColor NSColor 23 | #endif 24 | 25 | @interface HXColor (HexColorAddition) 26 | 27 | /** 28 | Creates a UIColor or NSColor from a HexString like #fff, #ffff, #ff00aa or #ff00aaee. 29 | With complete support for short hand hex values, short hand with short alpha value, full 30 | hex values and full hex values with alpha. 31 | 32 | @param hexString NSString hex string for color generation 33 | @return UIColor / NSColor or nil 34 | */ 35 | + (nullable HXColor *)hx_colorWithHexString:(nonnull NSString *)hexString; 36 | 37 | /** 38 | Same implementation as hx_colorWithHexString but you can hand in a normal alpha value from 0 to 1 39 | 40 | @param hexString NSString hex string for color generation 41 | @param alpha CGFloat from 0 to 1 42 | @return UIColor / NSColor or nil 43 | */ 44 | + (nullable HXColor *)hx_colorWithHexString:(nonnull NSString *)hexString alpha:(CGFloat)alpha; 45 | 46 | /** 47 | Don't like to devide by 255 to get a value between 0 to 1 for creating a color? This helps you create 48 | a UIColor without the hassle, which leads to cleaner code 49 | 50 | @param red NSInteger hand in a value for red between 0 and 255 51 | @param green NSInteger hand in a value for green between 0 and 255 52 | @param blue NSInteger hand in a value for blue between 0 and 255 53 | @return UIColor / NSColor 54 | */ 55 | + (nonnull HXColor *)hx_colorWith8BitRed:(NSInteger)red green:(NSInteger)green blue:(NSInteger)blue; 56 | 57 | /** 58 | Same implementation as hx_colorWith8BitRed:green:blue but you can hand in a normal alpha value from 0 to 1 59 | 60 | @param red NSInteger hand in a value for red between 0 and 255 61 | @param green NSInteger hand in a value for green between 0 and 255 62 | @param blue NSInteger hand in a value for blue between 0 and 255 63 | @param alpha CGFloat from 0 to 1 64 | @return UIColor / NSColor 65 | */ 66 | + (nonnull HXColor *)hx_colorWith8BitRed:(NSInteger)red green:(NSInteger)green blue:(NSInteger)blue alpha:(CGFloat)alpha; 67 | 68 | @end 69 | 70 | 71 | @interface NSString (hx_StringTansformer) 72 | 73 | /** 74 | Checks for a short hexString like #fff and transform it to a long hexstring like #ffffff 75 | 76 | @return hexString NSString a normal hexString with the length of 7 characters like #ffffff or the initial string 77 | */ 78 | - (nonnull NSString *)hx_hexStringTransformFromThreeCharacters; 79 | 80 | @end -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView.xcodeproj/xcuserdata/ft_david.xcuserdatad/xcschemes/DLSkillTagView.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 43 | 49 | 50 | 51 | 52 | 53 | 59 | 60 | 61 | 62 | 63 | 64 | 74 | 76 | 82 | 83 | 84 | 85 | 86 | 87 | 93 | 95 | 101 | 102 | 103 | 104 | 106 | 107 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/Lib/Classes/HexColors.m: -------------------------------------------------------------------------------- 1 | // 2 | // HexColor.m 3 | // 4 | // Created by Marius Landwehr on 02.12.12. 5 | // The MIT License (MIT) 6 | // Copyright (c) 2013 Marius Landwehr marius.landwehr@gmail.com 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 9 | // 10 | // The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 11 | // 12 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 13 | // 14 | 15 | #import "HexColors.h" 16 | 17 | @implementation HXColor (HexColorAddition) 18 | 19 | + (HXColor *)hx_colorWithHexString:(NSString *)hexString 20 | { 21 | return [[self class] hx_colorWithHexString:hexString alpha:1.0]; 22 | } 23 | 24 | + (HXColor *)hx_colorWithHexString:(NSString *)hexString alpha:(CGFloat)alpha 25 | { 26 | // We found an empty string, we are returning nothing 27 | if (hexString.length == 0) { 28 | return nil; 29 | } 30 | 31 | // Check for hash and add the missing hash 32 | if('#' != [hexString characterAtIndex:0]) { 33 | hexString = [NSString stringWithFormat:@"#%@", hexString]; 34 | } 35 | 36 | // returning no object on wrong alpha values 37 | NSArray *validHexStringLengths = @[@4, @5, @7, @9]; 38 | NSNumber *hexStringLengthNumber = [NSNumber numberWithUnsignedInteger:hexString.length]; 39 | if ([validHexStringLengths indexOfObject:hexStringLengthNumber] == NSNotFound) { 40 | return nil; 41 | } 42 | 43 | // if the hex string is 5 or 9 we are ignoring the alpha value and we are using the value from the hex string instead 44 | CGFloat handedInAlpha = alpha; 45 | if (5 == hexString.length || 9 == hexString.length) { 46 | NSString * alphaHex = [hexString substringWithRange:NSMakeRange(1, 9 == hexString.length ? 2 : 1)]; 47 | if (1 == alphaHex.length) alphaHex = [NSString stringWithFormat:@"%@%@", alphaHex, alphaHex]; 48 | hexString = [NSString stringWithFormat:@"#%@", [hexString substringFromIndex:9 == hexString.length ? 3 : 2]]; 49 | unsigned alpha_u = [[self class] hx_hexValueToUnsigned:alphaHex]; 50 | handedInAlpha = ((CGFloat) alpha_u) / 255.0; 51 | } 52 | 53 | // check for 3 character HexStrings 54 | hexString = [hexString hx_hexStringTransformFromThreeCharacters]; 55 | 56 | NSString *redHex = [NSString stringWithFormat:@"0x%@", [hexString substringWithRange:NSMakeRange(1, 2)]]; 57 | unsigned redInt = [[self class] hx_hexValueToUnsigned:redHex]; 58 | 59 | NSString *greenHex = [NSString stringWithFormat:@"0x%@", [hexString substringWithRange:NSMakeRange(3, 2)]]; 60 | unsigned greenInt = [[self class] hx_hexValueToUnsigned:greenHex]; 61 | 62 | NSString *blueHex = [NSString stringWithFormat:@"0x%@", [hexString substringWithRange:NSMakeRange(5, 2)]]; 63 | unsigned blueInt = [[self class] hx_hexValueToUnsigned:blueHex]; 64 | 65 | HXColor *color = [HXColor hx_colorWith8BitRed:redInt green:greenInt blue:blueInt alpha:handedInAlpha]; 66 | 67 | return color; 68 | } 69 | 70 | + (HXColor *)hx_colorWith8BitRed:(NSInteger)red green:(NSInteger)green blue:(NSInteger)blue 71 | { 72 | return [[self class] hx_colorWith8BitRed:red green:green blue:blue alpha:1.0]; 73 | } 74 | 75 | + (HXColor *)hx_colorWith8BitRed:(NSInteger)red green:(NSInteger)green blue:(NSInteger)blue alpha:(CGFloat)alpha 76 | { 77 | HXColor *color = nil; 78 | #if (TARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE) 79 | color = [HXColor colorWithRed:(float)red/255 green:(float)green/255 blue:(float)blue/255 alpha:alpha]; 80 | #else 81 | color = [HXColor colorWithCalibratedRed:(float)red/255 green:(float)green/255 blue:(float)blue/255 alpha:alpha]; 82 | #endif 83 | 84 | return color; 85 | } 86 | 87 | + (unsigned)hx_hexValueToUnsigned:(NSString *)hexValue 88 | { 89 | unsigned value = 0; 90 | 91 | NSScanner *hexValueScanner = [NSScanner scannerWithString:hexValue]; 92 | [hexValueScanner scanHexInt:&value]; 93 | 94 | return value; 95 | } 96 | 97 | 98 | @end 99 | 100 | @implementation NSString (hx_StringTansformer) 101 | 102 | - (NSString *)hx_hexStringTransformFromThreeCharacters; 103 | { 104 | if(self.length == 4) 105 | { 106 | NSString * hexString = [NSString stringWithFormat:@"#%1$c%1$c%2$c%2$c%3$c%3$c", 107 | [self characterAtIndex:1], 108 | [self characterAtIndex:2], 109 | [self characterAtIndex:3]]; 110 | return hexString; 111 | } 112 | 113 | return self; 114 | } 115 | 116 | @end 117 | -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView/Lib/SKTagView/SKTagView.m: -------------------------------------------------------------------------------- 1 | // 2 | // SKTagView.m 3 | // 4 | // Created by Shaokang Zhao on 15/1/12. 5 | // Copyright (c) 2015 Shaokang Zhao. All rights reserved. 6 | // 7 | 8 | #import "SKTagView.h" 9 | #import "SKTagButton.h" 10 | 11 | 12 | @interface SKTagView () 13 | 14 | @property (strong, nonatomic, nullable) NSMutableArray *tags; 15 | @property (assign, nonatomic) BOOL didSetup; 16 | @property(nonatomic,assign)BOOL outOfBounds; 17 | 18 | @end 19 | 20 | @implementation SKTagView 21 | 22 | #pragma mark - Lifecycle 23 | 24 | -(CGSize)intrinsicContentSize { 25 | if (!self.tags.count) { 26 | return CGSizeZero; 27 | } 28 | 29 | NSArray *subviews = self.subviews; 30 | UIView *previousView = nil; 31 | CGFloat topPadding = self.padding.top; 32 | CGFloat bottomPadding = self.padding.bottom; 33 | CGFloat leftPadding = self.padding.left; 34 | CGFloat rightPadding = self.padding.right; 35 | CGFloat itemSpacing = self.interitemSpacing; 36 | CGFloat lineSpacing = self.lineSpacing; 37 | CGFloat currentX = leftPadding; 38 | CGFloat intrinsicHeight = topPadding; 39 | CGFloat intrinsicWidth = leftPadding; 40 | 41 | if (!self.singleLine && self.preferredMaxLayoutWidth > 0) { 42 | NSInteger lineCount = 0; 43 | for (UIView *view in subviews) { 44 | CGSize size = view.intrinsicContentSize; 45 | if (previousView) { 46 | CGFloat width = size.width; 47 | currentX += itemSpacing; 48 | if (currentX + width + rightPadding <= self.preferredMaxLayoutWidth) { 49 | currentX += size.width; 50 | } else { 51 | lineCount ++; 52 | currentX = leftPadding + size.width; 53 | intrinsicHeight += size.height; 54 | } 55 | } else { 56 | lineCount ++; 57 | intrinsicHeight += size.height; 58 | currentX += size.width; 59 | } 60 | previousView = view; 61 | intrinsicWidth = MAX(intrinsicWidth, currentX + rightPadding); 62 | } 63 | 64 | intrinsicHeight += bottomPadding + lineSpacing * (lineCount - 1); 65 | } else { 66 | for (UIView *view in subviews) { 67 | CGSize size = view.intrinsicContentSize; 68 | intrinsicWidth += size.width; 69 | } 70 | intrinsicWidth += itemSpacing * (subviews.count - 1) + rightPadding; 71 | intrinsicHeight += ((UIView *)subviews.firstObject).intrinsicContentSize.height + bottomPadding; 72 | } 73 | 74 | return CGSizeMake(intrinsicWidth, intrinsicHeight); 75 | } 76 | 77 | - (void)layoutSubviews { 78 | if (!self.singleLine) { 79 | self.preferredMaxLayoutWidth = self.frame.size.width; 80 | } 81 | 82 | [super layoutSubviews]; 83 | 84 | [self layoutTags]; 85 | } 86 | 87 | #pragma mark - Custom accessors 88 | 89 | - (NSMutableArray *)tags { 90 | if(!_tags) { 91 | _tags = [NSMutableArray array]; 92 | } 93 | return _tags; 94 | } 95 | 96 | - (void)setPreferredMaxLayoutWidth: (CGFloat)preferredMaxLayoutWidth { 97 | if (preferredMaxLayoutWidth != _preferredMaxLayoutWidth) { 98 | _preferredMaxLayoutWidth = preferredMaxLayoutWidth; 99 | _didSetup = NO; 100 | [self invalidateIntrinsicContentSize]; 101 | } 102 | } 103 | 104 | #pragma mark - Private 105 | 106 | - (void)layoutTags { 107 | if (self.didSetup || !self.tags.count) { 108 | return; 109 | } 110 | 111 | NSArray *subviews = self.subviews; 112 | UIView *previousView = nil; 113 | CGFloat topPadding = self.padding.top; 114 | CGFloat leftPadding = self.padding.left; 115 | CGFloat rightPadding = self.padding.right; 116 | CGFloat bottomPadding = self.padding.bottom; 117 | CGFloat itemSpacing = self.interitemSpacing; 118 | CGFloat lineSpacing = self.lineSpacing; 119 | CGFloat currentX = leftPadding; 120 | 121 | if (!self.singleLine && self.preferredMaxLayoutWidth > 0) { 122 | if (self.outOfBounds) return; 123 | for (UIView *view in subviews) { 124 | CGSize size = view.intrinsicContentSize; 125 | if (previousView) { 126 | CGFloat width = size.width; 127 | currentX += itemSpacing; 128 | if (currentX + width + rightPadding <= self.preferredMaxLayoutWidth) { 129 | if (CGRectGetMaxY(previousView.frame) + lineSpacing < self.bounds.size.height - bottomPadding) { 130 | view.frame = CGRectMake(currentX, CGRectGetMinY(previousView.frame), size.width, size.height); 131 | currentX += size.width; 132 | }else{ 133 | [view removeFromSuperview]; 134 | self.outOfBounds = YES; 135 | break; 136 | } 137 | 138 | } else { 139 | CGFloat width = MIN(size.width, self.preferredMaxLayoutWidth - leftPadding - rightPadding); 140 | if (CGRectGetMaxY(previousView.frame) + lineSpacing < self.bounds.size.height - bottomPadding) { 141 | view.frame = CGRectMake(leftPadding, CGRectGetMaxY(previousView.frame) + lineSpacing, width, size.height); 142 | currentX = leftPadding + width; 143 | }else{ 144 | [view removeFromSuperview]; 145 | self.outOfBounds = YES; 146 | break; 147 | } 148 | } 149 | } else { 150 | CGFloat width = MIN(size.width, self.preferredMaxLayoutWidth - leftPadding - rightPadding); 151 | view.frame = CGRectMake(leftPadding, topPadding, width, size.height); 152 | currentX += width; 153 | } 154 | 155 | previousView = view; 156 | } 157 | } else { 158 | for (UIView *view in subviews) { 159 | CGSize size = view.intrinsicContentSize; 160 | view.frame = CGRectMake(currentX, topPadding, size.width, size.height); 161 | currentX += size.width; 162 | currentX += itemSpacing; 163 | 164 | previousView = view; 165 | } 166 | } 167 | 168 | NSLog(@"%@",NSStringFromCGRect(previousView.frame)); 169 | 170 | self.didSetup = YES; 171 | } 172 | 173 | #pragma mark - IBActions 174 | 175 | - (void)onTag: (UIButton *)btn { 176 | btn.selected = !btn.selected; 177 | if (self.didTapTagAtIndex) { 178 | self.didTapTagAtIndex([self.subviews indexOfObject: btn]); 179 | } 180 | } 181 | 182 | #pragma mark - Public 183 | 184 | - (void)addTag: (SKTag *)tag { 185 | if (self.outOfBounds) return; 186 | 187 | 188 | NSParameterAssert(tag); 189 | SKTagButton *btn = [SKTagButton buttonWithTag: tag]; 190 | [btn addTarget: self action: @selector(onTag:) forControlEvents: UIControlEventTouchUpInside]; 191 | [self addSubview: btn]; 192 | [self.tags addObject: tag]; 193 | 194 | self.didSetup = NO; 195 | [self invalidateIntrinsicContentSize]; 196 | } 197 | 198 | - (void)insertTag: (SKTag *)tag atIndex: (NSUInteger)index { 199 | if(self.outOfBounds) return; 200 | NSParameterAssert(tag); 201 | if (index + 1 > self.tags.count) { 202 | [self addTag: tag]; 203 | } else { 204 | SKTagButton *btn = [SKTagButton buttonWithTag: tag]; 205 | [btn addTarget: self action: @selector(onTag:) forControlEvents: UIControlEventTouchUpInside]; 206 | [self insertSubview: btn atIndex: index]; 207 | [self.tags insertObject: tag atIndex: index]; 208 | 209 | self.didSetup = NO; 210 | [self invalidateIntrinsicContentSize]; 211 | } 212 | } 213 | 214 | - (void)removeTag: (SKTag *)tag { 215 | NSParameterAssert(tag); 216 | NSUInteger index = [self.tags indexOfObject: tag]; 217 | if (NSNotFound == index) { 218 | return; 219 | } 220 | 221 | [self.tags removeObjectAtIndex: index]; 222 | if (self.subviews.count > index) { 223 | [self.subviews[index] removeFromSuperview]; 224 | self.outOfBounds = NO; 225 | } 226 | 227 | self.didSetup = NO; 228 | [self invalidateIntrinsicContentSize]; 229 | } 230 | 231 | - (void)removeTagAtIndex: (NSUInteger)index { 232 | if (index + 1 > self.tags.count) { 233 | return; 234 | } 235 | 236 | [self.tags removeObjectAtIndex: index]; 237 | if (self.subviews.count > index) { 238 | [self.subviews[index] removeFromSuperview]; 239 | } 240 | 241 | self.didSetup = NO; 242 | [self invalidateIntrinsicContentSize]; 243 | } 244 | 245 | - (void)removeAllTags { 246 | [self.tags removeAllObjects]; 247 | for (UIView *view in self.subviews) { 248 | [view removeFromSuperview]; 249 | } 250 | 251 | self.didSetup = NO; 252 | [self invalidateIntrinsicContentSize]; 253 | } 254 | 255 | @end 256 | -------------------------------------------------------------------------------- /DLSkillTagView/DLSkillTagView.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | AAB977A61DDDBF5100A3CF89 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = AAB977A51DDDBF5100A3CF89 /* main.m */; }; 11 | AAB977A91DDDBF5100A3CF89 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = AAB977A81DDDBF5100A3CF89 /* AppDelegate.m */; }; 12 | AAB977AC1DDDBF5100A3CF89 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = AAB977AB1DDDBF5100A3CF89 /* ViewController.m */; }; 13 | AAB977AF1DDDBF5100A3CF89 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AAB977AD1DDDBF5100A3CF89 /* Main.storyboard */; }; 14 | AAB977B11DDDBF5100A3CF89 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = AAB977B01DDDBF5100A3CF89 /* Assets.xcassets */; }; 15 | AAB977B41DDDBF5100A3CF89 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AAB977B21DDDBF5100A3CF89 /* LaunchScreen.storyboard */; }; 16 | AAB977BF1DDDBF5100A3CF89 /* DLSkillTagViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = AAB977BE1DDDBF5100A3CF89 /* DLSkillTagViewTests.m */; }; 17 | AAB977CA1DDDBF5100A3CF89 /* DLSkillTagViewUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = AAB977C91DDDBF5100A3CF89 /* DLSkillTagViewUITests.m */; }; 18 | AAB977EC1DDE960600A3CF89 /* HexColors.m in Sources */ = {isa = PBXBuildFile; fileRef = AAB977E41DDE960600A3CF89 /* HexColors.m */; }; 19 | AAB977ED1DDE960600A3CF89 /* SKTag.m in Sources */ = {isa = PBXBuildFile; fileRef = AAB977E71DDE960600A3CF89 /* SKTag.m */; }; 20 | AAB977EE1DDE960600A3CF89 /* SKTagButton.m in Sources */ = {isa = PBXBuildFile; fileRef = AAB977E91DDE960600A3CF89 /* SKTagButton.m */; }; 21 | AAB977EF1DDE960600A3CF89 /* SKTagView.m in Sources */ = {isa = PBXBuildFile; fileRef = AAB977EB1DDE960600A3CF89 /* SKTagView.m */; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXContainerItemProxy section */ 25 | AAB977BB1DDDBF5100A3CF89 /* PBXContainerItemProxy */ = { 26 | isa = PBXContainerItemProxy; 27 | containerPortal = AAB977991DDDBF5100A3CF89 /* Project object */; 28 | proxyType = 1; 29 | remoteGlobalIDString = AAB977A01DDDBF5100A3CF89; 30 | remoteInfo = DLSkillTagView; 31 | }; 32 | AAB977C61DDDBF5100A3CF89 /* PBXContainerItemProxy */ = { 33 | isa = PBXContainerItemProxy; 34 | containerPortal = AAB977991DDDBF5100A3CF89 /* Project object */; 35 | proxyType = 1; 36 | remoteGlobalIDString = AAB977A01DDDBF5100A3CF89; 37 | remoteInfo = DLSkillTagView; 38 | }; 39 | /* End PBXContainerItemProxy section */ 40 | 41 | /* Begin PBXFileReference section */ 42 | AAB977A11DDDBF5100A3CF89 /* DLSkillTagView.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = DLSkillTagView.app; sourceTree = BUILT_PRODUCTS_DIR; }; 43 | AAB977A51DDDBF5100A3CF89 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 44 | AAB977A71DDDBF5100A3CF89 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 45 | AAB977A81DDDBF5100A3CF89 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 46 | AAB977AA1DDDBF5100A3CF89 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; 47 | AAB977AB1DDDBF5100A3CF89 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; 48 | AAB977AE1DDDBF5100A3CF89 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 49 | AAB977B01DDDBF5100A3CF89 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 50 | AAB977B31DDDBF5100A3CF89 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 51 | AAB977B51DDDBF5100A3CF89 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 52 | AAB977BA1DDDBF5100A3CF89 /* DLSkillTagViewTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DLSkillTagViewTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | AAB977BE1DDDBF5100A3CF89 /* DLSkillTagViewTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DLSkillTagViewTests.m; sourceTree = ""; }; 54 | AAB977C01DDDBF5100A3CF89 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 55 | AAB977C51DDDBF5100A3CF89 /* DLSkillTagViewUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = DLSkillTagViewUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 56 | AAB977C91DDDBF5100A3CF89 /* DLSkillTagViewUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DLSkillTagViewUITests.m; sourceTree = ""; }; 57 | AAB977CB1DDDBF5100A3CF89 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 58 | AAB977E31DDE960600A3CF89 /* HexColors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HexColors.h; sourceTree = ""; }; 59 | AAB977E41DDE960600A3CF89 /* HexColors.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HexColors.m; sourceTree = ""; }; 60 | AAB977E61DDE960600A3CF89 /* SKTag.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SKTag.h; sourceTree = ""; }; 61 | AAB977E71DDE960600A3CF89 /* SKTag.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SKTag.m; sourceTree = ""; }; 62 | AAB977E81DDE960600A3CF89 /* SKTagButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SKTagButton.h; sourceTree = ""; }; 63 | AAB977E91DDE960600A3CF89 /* SKTagButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SKTagButton.m; sourceTree = ""; }; 64 | AAB977EA1DDE960600A3CF89 /* SKTagView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SKTagView.h; sourceTree = ""; }; 65 | AAB977EB1DDE960600A3CF89 /* SKTagView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SKTagView.m; sourceTree = ""; }; 66 | /* End PBXFileReference section */ 67 | 68 | /* Begin PBXFrameworksBuildPhase section */ 69 | AAB9779E1DDDBF5100A3CF89 /* Frameworks */ = { 70 | isa = PBXFrameworksBuildPhase; 71 | buildActionMask = 2147483647; 72 | files = ( 73 | ); 74 | runOnlyForDeploymentPostprocessing = 0; 75 | }; 76 | AAB977B71DDDBF5100A3CF89 /* Frameworks */ = { 77 | isa = PBXFrameworksBuildPhase; 78 | buildActionMask = 2147483647; 79 | files = ( 80 | ); 81 | runOnlyForDeploymentPostprocessing = 0; 82 | }; 83 | AAB977C21DDDBF5100A3CF89 /* Frameworks */ = { 84 | isa = PBXFrameworksBuildPhase; 85 | buildActionMask = 2147483647; 86 | files = ( 87 | ); 88 | runOnlyForDeploymentPostprocessing = 0; 89 | }; 90 | /* End PBXFrameworksBuildPhase section */ 91 | 92 | /* Begin PBXGroup section */ 93 | AAB977981DDDBF5100A3CF89 = { 94 | isa = PBXGroup; 95 | children = ( 96 | AAB977A31DDDBF5100A3CF89 /* DLSkillTagView */, 97 | AAB977BD1DDDBF5100A3CF89 /* DLSkillTagViewTests */, 98 | AAB977C81DDDBF5100A3CF89 /* DLSkillTagViewUITests */, 99 | AAB977A21DDDBF5100A3CF89 /* Products */, 100 | ); 101 | sourceTree = ""; 102 | }; 103 | AAB977A21DDDBF5100A3CF89 /* Products */ = { 104 | isa = PBXGroup; 105 | children = ( 106 | AAB977A11DDDBF5100A3CF89 /* DLSkillTagView.app */, 107 | AAB977BA1DDDBF5100A3CF89 /* DLSkillTagViewTests.xctest */, 108 | AAB977C51DDDBF5100A3CF89 /* DLSkillTagViewUITests.xctest */, 109 | ); 110 | name = Products; 111 | sourceTree = ""; 112 | }; 113 | AAB977A31DDDBF5100A3CF89 /* DLSkillTagView */ = { 114 | isa = PBXGroup; 115 | children = ( 116 | AAB977E11DDE960600A3CF89 /* Lib */, 117 | AAB977A71DDDBF5100A3CF89 /* AppDelegate.h */, 118 | AAB977A81DDDBF5100A3CF89 /* AppDelegate.m */, 119 | AAB977AA1DDDBF5100A3CF89 /* ViewController.h */, 120 | AAB977AB1DDDBF5100A3CF89 /* ViewController.m */, 121 | AAB977AD1DDDBF5100A3CF89 /* Main.storyboard */, 122 | AAB977B01DDDBF5100A3CF89 /* Assets.xcassets */, 123 | AAB977B21DDDBF5100A3CF89 /* LaunchScreen.storyboard */, 124 | AAB977B51DDDBF5100A3CF89 /* Info.plist */, 125 | AAB977A41DDDBF5100A3CF89 /* Supporting Files */, 126 | ); 127 | path = DLSkillTagView; 128 | sourceTree = ""; 129 | }; 130 | AAB977A41DDDBF5100A3CF89 /* Supporting Files */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | AAB977A51DDDBF5100A3CF89 /* main.m */, 134 | ); 135 | name = "Supporting Files"; 136 | sourceTree = ""; 137 | }; 138 | AAB977BD1DDDBF5100A3CF89 /* DLSkillTagViewTests */ = { 139 | isa = PBXGroup; 140 | children = ( 141 | AAB977BE1DDDBF5100A3CF89 /* DLSkillTagViewTests.m */, 142 | AAB977C01DDDBF5100A3CF89 /* Info.plist */, 143 | ); 144 | path = DLSkillTagViewTests; 145 | sourceTree = ""; 146 | }; 147 | AAB977C81DDDBF5100A3CF89 /* DLSkillTagViewUITests */ = { 148 | isa = PBXGroup; 149 | children = ( 150 | AAB977C91DDDBF5100A3CF89 /* DLSkillTagViewUITests.m */, 151 | AAB977CB1DDDBF5100A3CF89 /* Info.plist */, 152 | ); 153 | path = DLSkillTagViewUITests; 154 | sourceTree = ""; 155 | }; 156 | AAB977E11DDE960600A3CF89 /* Lib */ = { 157 | isa = PBXGroup; 158 | children = ( 159 | AAB977E21DDE960600A3CF89 /* Classes */, 160 | AAB977E51DDE960600A3CF89 /* SKTagView */, 161 | ); 162 | path = Lib; 163 | sourceTree = ""; 164 | }; 165 | AAB977E21DDE960600A3CF89 /* Classes */ = { 166 | isa = PBXGroup; 167 | children = ( 168 | AAB977E31DDE960600A3CF89 /* HexColors.h */, 169 | AAB977E41DDE960600A3CF89 /* HexColors.m */, 170 | ); 171 | path = Classes; 172 | sourceTree = ""; 173 | }; 174 | AAB977E51DDE960600A3CF89 /* SKTagView */ = { 175 | isa = PBXGroup; 176 | children = ( 177 | AAB977E61DDE960600A3CF89 /* SKTag.h */, 178 | AAB977E71DDE960600A3CF89 /* SKTag.m */, 179 | AAB977E81DDE960600A3CF89 /* SKTagButton.h */, 180 | AAB977E91DDE960600A3CF89 /* SKTagButton.m */, 181 | AAB977EA1DDE960600A3CF89 /* SKTagView.h */, 182 | AAB977EB1DDE960600A3CF89 /* SKTagView.m */, 183 | ); 184 | path = SKTagView; 185 | sourceTree = ""; 186 | }; 187 | /* End PBXGroup section */ 188 | 189 | /* Begin PBXNativeTarget section */ 190 | AAB977A01DDDBF5100A3CF89 /* DLSkillTagView */ = { 191 | isa = PBXNativeTarget; 192 | buildConfigurationList = AAB977CE1DDDBF5100A3CF89 /* Build configuration list for PBXNativeTarget "DLSkillTagView" */; 193 | buildPhases = ( 194 | AAB9779D1DDDBF5100A3CF89 /* Sources */, 195 | AAB9779E1DDDBF5100A3CF89 /* Frameworks */, 196 | AAB9779F1DDDBF5100A3CF89 /* Resources */, 197 | ); 198 | buildRules = ( 199 | ); 200 | dependencies = ( 201 | ); 202 | name = DLSkillTagView; 203 | productName = DLSkillTagView; 204 | productReference = AAB977A11DDDBF5100A3CF89 /* DLSkillTagView.app */; 205 | productType = "com.apple.product-type.application"; 206 | }; 207 | AAB977B91DDDBF5100A3CF89 /* DLSkillTagViewTests */ = { 208 | isa = PBXNativeTarget; 209 | buildConfigurationList = AAB977D11DDDBF5100A3CF89 /* Build configuration list for PBXNativeTarget "DLSkillTagViewTests" */; 210 | buildPhases = ( 211 | AAB977B61DDDBF5100A3CF89 /* Sources */, 212 | AAB977B71DDDBF5100A3CF89 /* Frameworks */, 213 | AAB977B81DDDBF5100A3CF89 /* Resources */, 214 | ); 215 | buildRules = ( 216 | ); 217 | dependencies = ( 218 | AAB977BC1DDDBF5100A3CF89 /* PBXTargetDependency */, 219 | ); 220 | name = DLSkillTagViewTests; 221 | productName = DLSkillTagViewTests; 222 | productReference = AAB977BA1DDDBF5100A3CF89 /* DLSkillTagViewTests.xctest */; 223 | productType = "com.apple.product-type.bundle.unit-test"; 224 | }; 225 | AAB977C41DDDBF5100A3CF89 /* DLSkillTagViewUITests */ = { 226 | isa = PBXNativeTarget; 227 | buildConfigurationList = AAB977D41DDDBF5100A3CF89 /* Build configuration list for PBXNativeTarget "DLSkillTagViewUITests" */; 228 | buildPhases = ( 229 | AAB977C11DDDBF5100A3CF89 /* Sources */, 230 | AAB977C21DDDBF5100A3CF89 /* Frameworks */, 231 | AAB977C31DDDBF5100A3CF89 /* Resources */, 232 | ); 233 | buildRules = ( 234 | ); 235 | dependencies = ( 236 | AAB977C71DDDBF5100A3CF89 /* PBXTargetDependency */, 237 | ); 238 | name = DLSkillTagViewUITests; 239 | productName = DLSkillTagViewUITests; 240 | productReference = AAB977C51DDDBF5100A3CF89 /* DLSkillTagViewUITests.xctest */; 241 | productType = "com.apple.product-type.bundle.ui-testing"; 242 | }; 243 | /* End PBXNativeTarget section */ 244 | 245 | /* Begin PBXProject section */ 246 | AAB977991DDDBF5100A3CF89 /* Project object */ = { 247 | isa = PBXProject; 248 | attributes = { 249 | LastUpgradeCheck = 0810; 250 | ORGANIZATIONNAME = FT_David; 251 | TargetAttributes = { 252 | AAB977A01DDDBF5100A3CF89 = { 253 | CreatedOnToolsVersion = 8.1; 254 | DevelopmentTeam = 27XVM2QM7Z; 255 | ProvisioningStyle = Automatic; 256 | }; 257 | AAB977B91DDDBF5100A3CF89 = { 258 | CreatedOnToolsVersion = 8.1; 259 | ProvisioningStyle = Automatic; 260 | TestTargetID = AAB977A01DDDBF5100A3CF89; 261 | }; 262 | AAB977C41DDDBF5100A3CF89 = { 263 | CreatedOnToolsVersion = 8.1; 264 | ProvisioningStyle = Automatic; 265 | TestTargetID = AAB977A01DDDBF5100A3CF89; 266 | }; 267 | }; 268 | }; 269 | buildConfigurationList = AAB9779C1DDDBF5100A3CF89 /* Build configuration list for PBXProject "DLSkillTagView" */; 270 | compatibilityVersion = "Xcode 3.2"; 271 | developmentRegion = English; 272 | hasScannedForEncodings = 0; 273 | knownRegions = ( 274 | en, 275 | Base, 276 | ); 277 | mainGroup = AAB977981DDDBF5100A3CF89; 278 | productRefGroup = AAB977A21DDDBF5100A3CF89 /* Products */; 279 | projectDirPath = ""; 280 | projectRoot = ""; 281 | targets = ( 282 | AAB977A01DDDBF5100A3CF89 /* DLSkillTagView */, 283 | AAB977B91DDDBF5100A3CF89 /* DLSkillTagViewTests */, 284 | AAB977C41DDDBF5100A3CF89 /* DLSkillTagViewUITests */, 285 | ); 286 | }; 287 | /* End PBXProject section */ 288 | 289 | /* Begin PBXResourcesBuildPhase section */ 290 | AAB9779F1DDDBF5100A3CF89 /* Resources */ = { 291 | isa = PBXResourcesBuildPhase; 292 | buildActionMask = 2147483647; 293 | files = ( 294 | AAB977B41DDDBF5100A3CF89 /* LaunchScreen.storyboard in Resources */, 295 | AAB977B11DDDBF5100A3CF89 /* Assets.xcassets in Resources */, 296 | AAB977AF1DDDBF5100A3CF89 /* Main.storyboard in Resources */, 297 | ); 298 | runOnlyForDeploymentPostprocessing = 0; 299 | }; 300 | AAB977B81DDDBF5100A3CF89 /* Resources */ = { 301 | isa = PBXResourcesBuildPhase; 302 | buildActionMask = 2147483647; 303 | files = ( 304 | ); 305 | runOnlyForDeploymentPostprocessing = 0; 306 | }; 307 | AAB977C31DDDBF5100A3CF89 /* Resources */ = { 308 | isa = PBXResourcesBuildPhase; 309 | buildActionMask = 2147483647; 310 | files = ( 311 | ); 312 | runOnlyForDeploymentPostprocessing = 0; 313 | }; 314 | /* End PBXResourcesBuildPhase section */ 315 | 316 | /* Begin PBXSourcesBuildPhase section */ 317 | AAB9779D1DDDBF5100A3CF89 /* Sources */ = { 318 | isa = PBXSourcesBuildPhase; 319 | buildActionMask = 2147483647; 320 | files = ( 321 | AAB977EE1DDE960600A3CF89 /* SKTagButton.m in Sources */, 322 | AAB977ED1DDE960600A3CF89 /* SKTag.m in Sources */, 323 | AAB977AC1DDDBF5100A3CF89 /* ViewController.m in Sources */, 324 | AAB977EC1DDE960600A3CF89 /* HexColors.m in Sources */, 325 | AAB977EF1DDE960600A3CF89 /* SKTagView.m in Sources */, 326 | AAB977A91DDDBF5100A3CF89 /* AppDelegate.m in Sources */, 327 | AAB977A61DDDBF5100A3CF89 /* main.m in Sources */, 328 | ); 329 | runOnlyForDeploymentPostprocessing = 0; 330 | }; 331 | AAB977B61DDDBF5100A3CF89 /* Sources */ = { 332 | isa = PBXSourcesBuildPhase; 333 | buildActionMask = 2147483647; 334 | files = ( 335 | AAB977BF1DDDBF5100A3CF89 /* DLSkillTagViewTests.m in Sources */, 336 | ); 337 | runOnlyForDeploymentPostprocessing = 0; 338 | }; 339 | AAB977C11DDDBF5100A3CF89 /* Sources */ = { 340 | isa = PBXSourcesBuildPhase; 341 | buildActionMask = 2147483647; 342 | files = ( 343 | AAB977CA1DDDBF5100A3CF89 /* DLSkillTagViewUITests.m in Sources */, 344 | ); 345 | runOnlyForDeploymentPostprocessing = 0; 346 | }; 347 | /* End PBXSourcesBuildPhase section */ 348 | 349 | /* Begin PBXTargetDependency section */ 350 | AAB977BC1DDDBF5100A3CF89 /* PBXTargetDependency */ = { 351 | isa = PBXTargetDependency; 352 | target = AAB977A01DDDBF5100A3CF89 /* DLSkillTagView */; 353 | targetProxy = AAB977BB1DDDBF5100A3CF89 /* PBXContainerItemProxy */; 354 | }; 355 | AAB977C71DDDBF5100A3CF89 /* PBXTargetDependency */ = { 356 | isa = PBXTargetDependency; 357 | target = AAB977A01DDDBF5100A3CF89 /* DLSkillTagView */; 358 | targetProxy = AAB977C61DDDBF5100A3CF89 /* PBXContainerItemProxy */; 359 | }; 360 | /* End PBXTargetDependency section */ 361 | 362 | /* Begin PBXVariantGroup section */ 363 | AAB977AD1DDDBF5100A3CF89 /* Main.storyboard */ = { 364 | isa = PBXVariantGroup; 365 | children = ( 366 | AAB977AE1DDDBF5100A3CF89 /* Base */, 367 | ); 368 | name = Main.storyboard; 369 | sourceTree = ""; 370 | }; 371 | AAB977B21DDDBF5100A3CF89 /* LaunchScreen.storyboard */ = { 372 | isa = PBXVariantGroup; 373 | children = ( 374 | AAB977B31DDDBF5100A3CF89 /* Base */, 375 | ); 376 | name = LaunchScreen.storyboard; 377 | sourceTree = ""; 378 | }; 379 | /* End PBXVariantGroup section */ 380 | 381 | /* Begin XCBuildConfiguration section */ 382 | AAB977CC1DDDBF5100A3CF89 /* Debug */ = { 383 | isa = XCBuildConfiguration; 384 | buildSettings = { 385 | ALWAYS_SEARCH_USER_PATHS = NO; 386 | CLANG_ANALYZER_NONNULL = YES; 387 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 388 | CLANG_CXX_LIBRARY = "libc++"; 389 | CLANG_ENABLE_MODULES = YES; 390 | CLANG_ENABLE_OBJC_ARC = YES; 391 | CLANG_WARN_BOOL_CONVERSION = YES; 392 | CLANG_WARN_CONSTANT_CONVERSION = YES; 393 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 394 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 395 | CLANG_WARN_EMPTY_BODY = YES; 396 | CLANG_WARN_ENUM_CONVERSION = YES; 397 | CLANG_WARN_INFINITE_RECURSION = YES; 398 | CLANG_WARN_INT_CONVERSION = YES; 399 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 400 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 401 | CLANG_WARN_UNREACHABLE_CODE = YES; 402 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 403 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 404 | COPY_PHASE_STRIP = NO; 405 | DEBUG_INFORMATION_FORMAT = dwarf; 406 | ENABLE_STRICT_OBJC_MSGSEND = YES; 407 | ENABLE_TESTABILITY = YES; 408 | GCC_C_LANGUAGE_STANDARD = gnu99; 409 | GCC_DYNAMIC_NO_PIC = NO; 410 | GCC_NO_COMMON_BLOCKS = YES; 411 | GCC_OPTIMIZATION_LEVEL = 0; 412 | GCC_PREPROCESSOR_DEFINITIONS = ( 413 | "DEBUG=1", 414 | "$(inherited)", 415 | ); 416 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 417 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 418 | GCC_WARN_UNDECLARED_SELECTOR = YES; 419 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 420 | GCC_WARN_UNUSED_FUNCTION = YES; 421 | GCC_WARN_UNUSED_VARIABLE = YES; 422 | IPHONEOS_DEPLOYMENT_TARGET = 10.1; 423 | MTL_ENABLE_DEBUG_INFO = YES; 424 | ONLY_ACTIVE_ARCH = YES; 425 | SDKROOT = iphoneos; 426 | }; 427 | name = Debug; 428 | }; 429 | AAB977CD1DDDBF5100A3CF89 /* Release */ = { 430 | isa = XCBuildConfiguration; 431 | buildSettings = { 432 | ALWAYS_SEARCH_USER_PATHS = NO; 433 | CLANG_ANALYZER_NONNULL = YES; 434 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 435 | CLANG_CXX_LIBRARY = "libc++"; 436 | CLANG_ENABLE_MODULES = YES; 437 | CLANG_ENABLE_OBJC_ARC = YES; 438 | CLANG_WARN_BOOL_CONVERSION = YES; 439 | CLANG_WARN_CONSTANT_CONVERSION = YES; 440 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 441 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 442 | CLANG_WARN_EMPTY_BODY = YES; 443 | CLANG_WARN_ENUM_CONVERSION = YES; 444 | CLANG_WARN_INFINITE_RECURSION = YES; 445 | CLANG_WARN_INT_CONVERSION = YES; 446 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 447 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 448 | CLANG_WARN_UNREACHABLE_CODE = YES; 449 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 450 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 451 | COPY_PHASE_STRIP = NO; 452 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 453 | ENABLE_NS_ASSERTIONS = NO; 454 | ENABLE_STRICT_OBJC_MSGSEND = YES; 455 | GCC_C_LANGUAGE_STANDARD = gnu99; 456 | GCC_NO_COMMON_BLOCKS = YES; 457 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 458 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 459 | GCC_WARN_UNDECLARED_SELECTOR = YES; 460 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 461 | GCC_WARN_UNUSED_FUNCTION = YES; 462 | GCC_WARN_UNUSED_VARIABLE = YES; 463 | IPHONEOS_DEPLOYMENT_TARGET = 10.1; 464 | MTL_ENABLE_DEBUG_INFO = NO; 465 | SDKROOT = iphoneos; 466 | VALIDATE_PRODUCT = YES; 467 | }; 468 | name = Release; 469 | }; 470 | AAB977CF1DDDBF5100A3CF89 /* Debug */ = { 471 | isa = XCBuildConfiguration; 472 | buildSettings = { 473 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 474 | DEVELOPMENT_TEAM = 27XVM2QM7Z; 475 | INFOPLIST_FILE = DLSkillTagView/Info.plist; 476 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 477 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 478 | PRODUCT_BUNDLE_IDENTIFIER = davidlee.DLSkillTagView; 479 | PRODUCT_NAME = "$(TARGET_NAME)"; 480 | }; 481 | name = Debug; 482 | }; 483 | AAB977D01DDDBF5100A3CF89 /* Release */ = { 484 | isa = XCBuildConfiguration; 485 | buildSettings = { 486 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 487 | DEVELOPMENT_TEAM = 27XVM2QM7Z; 488 | INFOPLIST_FILE = DLSkillTagView/Info.plist; 489 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 490 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 491 | PRODUCT_BUNDLE_IDENTIFIER = davidlee.DLSkillTagView; 492 | PRODUCT_NAME = "$(TARGET_NAME)"; 493 | }; 494 | name = Release; 495 | }; 496 | AAB977D21DDDBF5100A3CF89 /* Debug */ = { 497 | isa = XCBuildConfiguration; 498 | buildSettings = { 499 | BUNDLE_LOADER = "$(TEST_HOST)"; 500 | INFOPLIST_FILE = DLSkillTagViewTests/Info.plist; 501 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 502 | PRODUCT_BUNDLE_IDENTIFIER = davidlee.DLSkillTagViewTests; 503 | PRODUCT_NAME = "$(TARGET_NAME)"; 504 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DLSkillTagView.app/DLSkillTagView"; 505 | }; 506 | name = Debug; 507 | }; 508 | AAB977D31DDDBF5100A3CF89 /* Release */ = { 509 | isa = XCBuildConfiguration; 510 | buildSettings = { 511 | BUNDLE_LOADER = "$(TEST_HOST)"; 512 | INFOPLIST_FILE = DLSkillTagViewTests/Info.plist; 513 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 514 | PRODUCT_BUNDLE_IDENTIFIER = davidlee.DLSkillTagViewTests; 515 | PRODUCT_NAME = "$(TARGET_NAME)"; 516 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/DLSkillTagView.app/DLSkillTagView"; 517 | }; 518 | name = Release; 519 | }; 520 | AAB977D51DDDBF5100A3CF89 /* Debug */ = { 521 | isa = XCBuildConfiguration; 522 | buildSettings = { 523 | INFOPLIST_FILE = DLSkillTagViewUITests/Info.plist; 524 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 525 | PRODUCT_BUNDLE_IDENTIFIER = davidlee.DLSkillTagViewUITests; 526 | PRODUCT_NAME = "$(TARGET_NAME)"; 527 | TEST_TARGET_NAME = DLSkillTagView; 528 | }; 529 | name = Debug; 530 | }; 531 | AAB977D61DDDBF5100A3CF89 /* Release */ = { 532 | isa = XCBuildConfiguration; 533 | buildSettings = { 534 | INFOPLIST_FILE = DLSkillTagViewUITests/Info.plist; 535 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 536 | PRODUCT_BUNDLE_IDENTIFIER = davidlee.DLSkillTagViewUITests; 537 | PRODUCT_NAME = "$(TARGET_NAME)"; 538 | TEST_TARGET_NAME = DLSkillTagView; 539 | }; 540 | name = Release; 541 | }; 542 | /* End XCBuildConfiguration section */ 543 | 544 | /* Begin XCConfigurationList section */ 545 | AAB9779C1DDDBF5100A3CF89 /* Build configuration list for PBXProject "DLSkillTagView" */ = { 546 | isa = XCConfigurationList; 547 | buildConfigurations = ( 548 | AAB977CC1DDDBF5100A3CF89 /* Debug */, 549 | AAB977CD1DDDBF5100A3CF89 /* Release */, 550 | ); 551 | defaultConfigurationIsVisible = 0; 552 | defaultConfigurationName = Release; 553 | }; 554 | AAB977CE1DDDBF5100A3CF89 /* Build configuration list for PBXNativeTarget "DLSkillTagView" */ = { 555 | isa = XCConfigurationList; 556 | buildConfigurations = ( 557 | AAB977CF1DDDBF5100A3CF89 /* Debug */, 558 | AAB977D01DDDBF5100A3CF89 /* Release */, 559 | ); 560 | defaultConfigurationIsVisible = 0; 561 | defaultConfigurationName = Release; 562 | }; 563 | AAB977D11DDDBF5100A3CF89 /* Build configuration list for PBXNativeTarget "DLSkillTagViewTests" */ = { 564 | isa = XCConfigurationList; 565 | buildConfigurations = ( 566 | AAB977D21DDDBF5100A3CF89 /* Debug */, 567 | AAB977D31DDDBF5100A3CF89 /* Release */, 568 | ); 569 | defaultConfigurationIsVisible = 0; 570 | defaultConfigurationName = Release; 571 | }; 572 | AAB977D41DDDBF5100A3CF89 /* Build configuration list for PBXNativeTarget "DLSkillTagViewUITests" */ = { 573 | isa = XCConfigurationList; 574 | buildConfigurations = ( 575 | AAB977D51DDDBF5100A3CF89 /* Debug */, 576 | AAB977D61DDDBF5100A3CF89 /* Release */, 577 | ); 578 | defaultConfigurationIsVisible = 0; 579 | defaultConfigurationName = Release; 580 | }; 581 | /* End XCConfigurationList section */ 582 | }; 583 | rootObject = AAB977991DDDBF5100A3CF89 /* Project object */; 584 | } 585 | --------------------------------------------------------------------------------