├── README.md
├── .DS_Store
├── LXSegmentControl
├── Assets.xcassets
│ ├── Contents.json
│ ├── back.imageset
│ │ ├── back@2x.png
│ │ ├── back@3x.png
│ │ └── Contents.json
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── Lib
│ ├── LXPageTab
│ │ ├── 三角形@2x.png
│ │ ├── LXPageTabItemLable.h
│ │ ├── LXPageTabItemLable.m
│ │ ├── LXPageTabView.h
│ │ └── LXPageTabView.m
│ └── XXPageTab
│ │ ├── XXPageTabItemLable.h
│ │ ├── XXPageTabItemLable.m
│ │ ├── XXPageTabView.h
│ │ └── XXPageTabView.m
├── ViewController.h
├── Category
│ ├── UIImage+LX.h
│ ├── UIColor+LX.h
│ ├── UIImage+LX.m
│ └── UIColor+LX.m
├── LXSegmentTitleViewController.h
├── LXSegmentType_0ViewController.h
├── LXSegmentType_1ViewController.h
├── AppDelegate.h
├── main.m
├── LXSegmentTitleViewController.m
├── ViewController.m
├── Info.plist
├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
├── AppDelegate.m
├── LXSegmentType_0ViewController.m
├── LX_Prefix.pch
└── LXSegmentType_1ViewController.m
├── LXSegmentControl.xcodeproj
├── xcuserdata
│ └── zlx.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ └── xcschememanagement.plist
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcuserdata
│ │ └── zlx.xcuserdatad
│ │ │ ├── UserInterfaceState.xcuserstate
│ │ │ └── IDEFindNavigatorScopes.plist
│ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── project.pbxproj
├── LXSegmentControlTests
├── Info.plist
└── LXSegmentControlTests.m
└── LXSegmentControlUITests
├── Info.plist
└── LXSegmentControlUITests.m
/README.md:
--------------------------------------------------------------------------------
1 | # LXPageTabDemo
2 |
3 | 页面切换,Segment控制
4 |
--------------------------------------------------------------------------------
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick8brown/LXPageTabDemo/HEAD/.DS_Store
--------------------------------------------------------------------------------
/LXSegmentControl/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/LXSegmentControl/Lib/LXPageTab/三角形@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick8brown/LXPageTabDemo/HEAD/LXSegmentControl/Lib/LXPageTab/三角形@2x.png
--------------------------------------------------------------------------------
/LXSegmentControl/Assets.xcassets/back.imageset/back@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick8brown/LXPageTabDemo/HEAD/LXSegmentControl/Assets.xcassets/back.imageset/back@2x.png
--------------------------------------------------------------------------------
/LXSegmentControl/Assets.xcassets/back.imageset/back@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick8brown/LXPageTabDemo/HEAD/LXSegmentControl/Assets.xcassets/back.imageset/back@3x.png
--------------------------------------------------------------------------------
/LXSegmentControl.xcodeproj/xcuserdata/zlx.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/LXSegmentControl.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/LXSegmentControl.xcodeproj/project.xcworkspace/xcuserdata/zlx.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/nick8brown/LXPageTabDemo/HEAD/LXSegmentControl.xcodeproj/project.xcworkspace/xcuserdata/zlx.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/LXSegmentControl.xcodeproj/project.xcworkspace/xcuserdata/zlx.xcuserdatad/IDEFindNavigatorScopes.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/LXSegmentControl/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // LXSegmentControl
4 | //
5 | // Created by LX Zeng on 2018/12/3.
6 | // Copyright © 2018 https://github.com/nick8brown All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/LXSegmentControl.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/LXSegmentControl/Category/UIImage+LX.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+LX.h
3 | // HZGAPP
4 | //
5 | // Created by LX Zeng on 16/8/25.
6 | // Copyright © 2016 https://github.com/nick8brown All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface UIImage (LX)
12 |
13 | + (UIImage *)getImageWithColor:(UIColor *)color;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/LXSegmentControl/Category/UIColor+LX.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIColor+LX.h
3 | // HZGAPP
4 | //
5 | // Created by LX Zeng on 16/7/4.
6 | // Copyright © 2016 https://github.com/nick8brown All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface UIColor (LX)
12 |
13 | + (UIColor *)colorWithHexString:(NSString *)color;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/LXSegmentControl/LXSegmentTitleViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // LXSegmentTitleViewController.h
3 | // LXSegmentControl
4 | //
5 | // Created by LX Zeng on 2018/12/3.
6 | // Copyright © 2018 https://github.com/nick8brown All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface LXSegmentTitleViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/LXSegmentControl/LXSegmentType_0ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // LXSegmentType_0ViewController.h
3 | // LXSegmentControl
4 | //
5 | // Created by LX Zeng on 2018/12/3.
6 | // Copyright © 2018 https://github.com/nick8brown All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface LXSegmentType_0ViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/LXSegmentControl/LXSegmentType_1ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // LXSegmentType_1ViewController.h
3 | // LXSegmentControl
4 | //
5 | // Created by LX Zeng on 2018/12/3.
6 | // Copyright © 2018 https://github.com/nick8brown All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface LXSegmentType_1ViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/LXSegmentControl/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // LXSegmentControl
4 | //
5 | // Created by LX Zeng on 2018/12/3.
6 | // Copyright © 2018 https://github.com/nick8brown 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 |
--------------------------------------------------------------------------------
/LXSegmentControl/Lib/XXPageTab/XXPageTabItemLable.h:
--------------------------------------------------------------------------------
1 | //
2 | // XXPageTabItemLable.h
3 | // XXPageTabDemo
4 | //
5 | // Created by HJTXX on 2017/3/3.
6 | // Copyright © 2017年 HJTXX. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface XXPageTabItemLable : UILabel
12 |
13 | @property (nonatomic, strong) UIColor *fillColor; //填充色
14 | @property (nonatomic, assign) CGFloat process; //填充占比
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/LXSegmentControl/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // LXSegmentControl
4 | //
5 | // Created by LX Zeng on 2018/12/3.
6 | // Copyright © 2018 https://github.com/nick8brown 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 |
--------------------------------------------------------------------------------
/LXSegmentControl/Lib/LXPageTab/LXPageTabItemLable.h:
--------------------------------------------------------------------------------
1 | //
2 | // LXPageTabItemLable.h
3 | // XXPageTabDemo
4 | //
5 | // Created by LX Zeng on 2017/3/3.
6 | // Copyright © 2017年 https://github.com/nick8brown All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface LXPageTabItemLable : UILabel
12 |
13 | @property (nonatomic, strong) UIColor *fillColor; //填充色
14 | @property (nonatomic, assign) CGFloat process; //填充占比
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/LXSegmentControl.xcodeproj/xcuserdata/zlx.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | LXSegmentControl.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/LXSegmentControl/Assets.xcassets/back.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "back@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "filename" : "back@3x.png",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "version" : 1,
20 | "author" : "xcode"
21 | }
22 | }
--------------------------------------------------------------------------------
/LXSegmentControl/LXSegmentTitleViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // LXSegmentTitleViewController.m
3 | // LXSegmentControl
4 | //
5 | // Created by LX Zeng on 2018/12/3.
6 | // Copyright © 2018 https://github.com/nick8brown All rights reserved.
7 | //
8 |
9 | #import "LXSegmentTitleViewController.h"
10 |
11 | @interface LXSegmentTitleViewController ()
12 |
13 | @end
14 |
15 | @implementation LXSegmentTitleViewController
16 |
17 | #pragma mark - life cycle
18 | - (void)viewDidLoad {
19 | [super viewDidLoad];
20 | }
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/LXSegmentControl/Lib/XXPageTab/XXPageTabItemLable.m:
--------------------------------------------------------------------------------
1 | //
2 | // XXPageTabItemLable.m
3 | // XXPageTabDemo
4 | //
5 | // Created by HJTXX on 2017/3/3.
6 | // Copyright © 2017年 HJTXX. All rights reserved.
7 | //
8 |
9 | #import "XXPageTabItemLable.h"
10 |
11 | @implementation XXPageTabItemLable
12 |
13 | - (void)drawRect:(CGRect)rect {
14 | [super drawRect:rect];
15 |
16 | if([_fillColor isKindOfClass:[UIColor class]]) {
17 | [_fillColor setFill];
18 | UIRectFillUsingBlendMode(CGRectMake(rect.origin.x, rect.origin.y, rect.size.width*_process, rect.size.height), kCGBlendModeSourceIn);
19 | }
20 | }
21 |
22 | - (void)setProcess:(CGFloat)process {
23 | _process = process;
24 | [self setNeedsDisplay];
25 | }
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/LXSegmentControl/Category/UIImage+LX.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+LX.m
3 | // HZGAPP
4 | //
5 | // Created by LX Zeng on 16/8/25.
6 | // Copyright © 2016 https://github.com/nick8brown All rights reserved.
7 | //
8 |
9 | #import "UIImage+LX.h"
10 |
11 | @implementation UIImage (LX)
12 |
13 | + (UIImage *)getImageWithColor:(UIColor *)color {
14 | CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
15 | UIGraphicsBeginImageContext(rect.size);
16 | CGContextRef context = UIGraphicsGetCurrentContext();
17 | CGContextSetFillColorWithColor(context, [color CGColor]);
18 | CGContextFillRect(context, rect);
19 | UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
20 | UIGraphicsEndImageContext();
21 | return theImage;
22 | }
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/LXSegmentControl/Lib/LXPageTab/LXPageTabItemLable.m:
--------------------------------------------------------------------------------
1 | //
2 | // LXPageTabItemLable.m
3 | // XXPageTabDemo
4 | //
5 | // Created by LX Zeng on 2017/3/3.
6 | // Copyright © 2017年 https://github.com/nick8brown All rights reserved.
7 | //
8 |
9 | #import "LXPageTabItemLable.h"
10 |
11 | @implementation LXPageTabItemLable
12 |
13 | - (void)drawRect:(CGRect)rect {
14 | [super drawRect:rect];
15 |
16 | if([_fillColor isKindOfClass:[UIColor class]]) {
17 | [_fillColor setFill];
18 | UIRectFillUsingBlendMode(CGRectMake(rect.origin.x, rect.origin.y, rect.size.width*_process, rect.size.height), kCGBlendModeSourceIn);
19 | }
20 | }
21 |
22 | - (void)setProcess:(CGFloat)process {
23 | _process = process;
24 | [self setNeedsDisplay];
25 | }
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/LXSegmentControlTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
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 |
--------------------------------------------------------------------------------
/LXSegmentControlUITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
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 |
--------------------------------------------------------------------------------
/LXSegmentControlTests/LXSegmentControlTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // LXSegmentControlTests.m
3 | // LXSegmentControlTests
4 | //
5 | // Created by LX Zeng on 2018/12/3.
6 | // Copyright © 2018 https://github.com/nick8brown All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface LXSegmentControlTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation LXSegmentControlTests
16 |
17 | - (void)setUp {
18 | // Put setup code here. This method is called before the invocation of each test method in the class.
19 | }
20 |
21 | - (void)tearDown {
22 | // Put teardown code here. This method is called after the invocation of each test method in the class.
23 | }
24 |
25 | - (void)testExample {
26 | // This is an example of a functional test case.
27 | // Use XCTAssert and related functions to verify your tests produce the correct results.
28 | }
29 |
30 | - (void)testPerformanceExample {
31 | // This is an example of a performance test case.
32 | [self measureBlock:^{
33 | // Put the code you want to measure the time of here.
34 | }];
35 | }
36 |
37 | @end
38 |
--------------------------------------------------------------------------------
/LXSegmentControlUITests/LXSegmentControlUITests.m:
--------------------------------------------------------------------------------
1 | //
2 | // LXSegmentControlUITests.m
3 | // LXSegmentControlUITests
4 | //
5 | // Created by LX Zeng on 2018/12/3.
6 | // Copyright © 2018 https://github.com/nick8brown All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface LXSegmentControlUITests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation LXSegmentControlUITests
16 |
17 | - (void)setUp {
18 | // Put setup code here. This method is called before the invocation of each test method in the class.
19 |
20 | // In UI tests it is usually best to stop immediately when a failure occurs.
21 | self.continueAfterFailure = NO;
22 |
23 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
24 | [[[XCUIApplication alloc] init] launch];
25 |
26 | // 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.
27 | }
28 |
29 | - (void)tearDown {
30 | // Put teardown code here. This method is called after the invocation of each test method in the class.
31 | }
32 |
33 | - (void)testExample {
34 | // Use recording to get started writing UI tests.
35 | // Use XCTAssert and related functions to verify your tests produce the correct results.
36 | }
37 |
38 | @end
39 |
--------------------------------------------------------------------------------
/LXSegmentControl/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // LXSegmentControl
4 | //
5 | // Created by LX Zeng on 2018/12/3.
6 | // Copyright © 2018 https://github.com/nick8brown All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 |
11 | #import "LXSegmentType_0ViewController.h"
12 | #import "LXSegmentType_1ViewController.h"
13 |
14 | @interface ViewController ()
15 |
16 | @end
17 |
18 | @implementation ViewController
19 |
20 | #pragma mark - life cycle
21 | - (void)viewDidLoad {
22 | [super viewDidLoad];
23 |
24 | self.title = @"自定义SegmentControl";
25 |
26 | // 初始化导航栏
27 | [self setupNavBar];
28 | }
29 |
30 | #pragma mark - 初始化导航栏
31 | - (void)setupNavBar {
32 | [self.navigationController.navigationBar setTitleTextAttributes:@{NSFontAttributeName:AppFont(18), NSForegroundColorAttributeName:SYS_White_Color}];
33 | [self.navigationController.navigationBar setBackgroundImage:[UIImage getImageWithColor:AppHTMLColor(@"4bccbc")] forBarMetrics:UIBarMetricsDefault];
34 | }
35 |
36 | #pragma mark - 样式一
37 | - (IBAction)type_0BtnClick:(UIButton *)sender {
38 | LXSegmentType_0ViewController *segmentType_0VC = [[LXSegmentType_0ViewController alloc] init];
39 | segmentType_0VC.title = @"样式一";
40 | [self.navigationController pushViewController:segmentType_0VC animated:YES];
41 | }
42 |
43 | #pragma mark - 样式二
44 | - (IBAction)type_1BtnClick:(UIButton *)sender {
45 | LXSegmentType_1ViewController *segmentType_1VC = [[LXSegmentType_1ViewController alloc] init];
46 | segmentType_1VC.title = @"样式二";
47 | [self.navigationController pushViewController:segmentType_1VC animated:YES];
48 | }
49 |
50 | @end
51 |
--------------------------------------------------------------------------------
/LXSegmentControl/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
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 | UISupportedInterfaceOrientations~ipad
38 |
39 | UIInterfaceOrientationPortrait
40 | UIInterfaceOrientationPortraitUpsideDown
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 | UIViewControllerBasedStatusBarAppearance
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/LXSegmentControl/Category/UIColor+LX.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIColor+LX.m
3 | // HZGAPP
4 | //
5 | // Created by LX Zeng on 16/7/4.
6 | // Copyright © 2016 https://github.com/nick8brown All rights reserved.
7 | //
8 |
9 | #import "UIColor+LX.h"
10 |
11 | @implementation UIColor (LX)
12 |
13 | + (UIColor *)colorWithHexString:(NSString *)color {
14 | NSString *cString = [[color stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] uppercaseString];
15 |
16 | // String should be 6 or 8 characters
17 | if ([cString length] < 6) {
18 | return [UIColor clearColor];
19 | }
20 |
21 | // strip 0X if it appears
22 | if ([cString hasPrefix:@"0X"])
23 | cString = [cString substringFromIndex:2];
24 | if ([cString hasPrefix:@"#"])
25 | cString = [cString substringFromIndex:1];
26 | if ([cString length] != 6)
27 | return [UIColor clearColor];
28 |
29 | // Separate into r, g, b substrings
30 | NSRange range;
31 | range.location = 0;
32 | range.length = 2;
33 |
34 | //r
35 | NSString *rString = [cString substringWithRange:range];
36 |
37 | //g
38 | range.location = 2;
39 | NSString *gString = [cString substringWithRange:range];
40 |
41 | //b
42 | range.location = 4;
43 | NSString *bString = [cString substringWithRange:range];
44 |
45 | // Scan values
46 | unsigned int r, g, b;
47 | [[NSScanner scannerWithString:rString] scanHexInt:&r];
48 | [[NSScanner scannerWithString:gString] scanHexInt:&g];
49 | [[NSScanner scannerWithString:bString] scanHexInt:&b];
50 |
51 | return [UIColor colorWithRed:((float) r / 255.0f) green:((float) g / 255.0f) blue:((float) b / 255.0f) alpha:1.0f];
52 | }
53 |
54 | @end
55 |
--------------------------------------------------------------------------------
/LXSegmentControl/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 |
--------------------------------------------------------------------------------
/LXSegmentControl/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/LXSegmentControl/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // LXSegmentControl
4 | //
5 | // Created by LX Zeng on 2018/12/3.
6 | // Copyright © 2018 https://github.com/nick8brown 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 |
20 | self.window.backgroundColor = SYS_White_Color;
21 | [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent;
22 |
23 | return YES;
24 | }
25 |
26 |
27 | - (void)applicationWillResignActive:(UIApplication *)application {
28 | // 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.
29 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
30 | }
31 |
32 |
33 | - (void)applicationDidEnterBackground:(UIApplication *)application {
34 | // 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.
35 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
36 | }
37 |
38 |
39 | - (void)applicationWillEnterForeground:(UIApplication *)application {
40 | // 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.
41 | }
42 |
43 |
44 | - (void)applicationDidBecomeActive:(UIApplication *)application {
45 | // 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.
46 | }
47 |
48 |
49 | - (void)applicationWillTerminate:(UIApplication *)application {
50 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
51 | }
52 |
53 |
54 | @end
55 |
--------------------------------------------------------------------------------
/LXSegmentControl/Lib/XXPageTab/XXPageTabView.h:
--------------------------------------------------------------------------------
1 | //
2 | // XXPageTabView.h
3 | // XXPageTabDemo
4 | //
5 | // Created by HJTXX on 2017/2/27.
6 | // Copyright © 2017年 HJTXX. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "XXPageTabItemLable.h"
11 |
12 | typedef NS_ENUM(NSInteger, XXPageTabTitleStyle) {
13 | XXPageTabTitleStyleDefault, //正常
14 | XXPageTabTitleStyleGradient, //渐变
15 | XXPageTabTitleStyleBlend //填充
16 | };
17 |
18 | typedef NS_ENUM(NSInteger, XXPageTabIndicatorStyle) {
19 | XXPageTabIndicatorStyleDefault, //正常,自定义宽度
20 | XXPageTabIndicatorStyleFollowText, //跟随文本长度变化
21 | XXPageTabIndicatorStyleStretch //拉伸
22 | };
23 |
24 | @protocol XXPageTabViewDelegate
25 | @optional
26 | /*切换完成代理方法*/
27 | - (void)pageTabViewDidEndChange;
28 | @end
29 |
30 | @interface XXPageTabView : UIView
31 |
32 | @property (nonatomic, weak) id delegate;
33 |
34 | /*设置当前选择项(无动画效果)*/
35 | @property (nonatomic, assign) NSInteger selectedTabIndex;
36 | /*一页展示最多的item个数,如果比item总数少,按照item总数计算*/
37 | @property (nonatomic, assign) NSInteger maxNumberOfPageItems;
38 | /*tab size,默认(self.width, 38.0)*/
39 | @property (nonatomic, assign) CGSize tabSize;
40 | /*item的字体大小*/
41 | @property (nonatomic, strong) UIFont *tabItemFont;
42 | /*未选择颜色*/
43 | @property (nonatomic, strong) UIColor *unSelectedColor;
44 | /*当前选中颜色*/
45 | @property (nonatomic, strong) UIColor *selectedColor;
46 | /*tab背景色,默认white*/
47 | @property (nonatomic, strong) UIColor *tabBackgroundColor;
48 | /*body背景色,默认white*/
49 | @property (nonatomic, strong) UIColor *bodyBackgroundColor;
50 | /*是否打开body的边界弹动效果*/
51 | @property (nonatomic, assign) BOOL bodyBounces;
52 |
53 | /*Title效果设置*/
54 | @property (nonatomic, assign) XXPageTabTitleStyle titleStyle;
55 | /*字体渐变,未选择的item的scale,默认是0.8(0~1)。仅XXPageTabTitleStyleScale生效*/
56 | @property (nonatomic, assign) CGFloat minScale;
57 |
58 | /*Indicator效果设置*/
59 | @property (nonatomic, assign) XXPageTabIndicatorStyle indicatorStyle;
60 | /*下标高度,默认是2.0*/
61 | @property (nonatomic, assign) CGFloat indicatorHeight;
62 | /*下标宽度,默认是0。XXPageTabIndicatorStyleFollowText时无效*/
63 | @property (nonatomic, assign) CGFloat indicatorWidth;
64 |
65 | - (instancetype)initWithChildControllers:(NSArray *)childControllers
66 | childTitles:(NSArray *)childTitles;
67 |
68 | @end
69 |
--------------------------------------------------------------------------------
/LXSegmentControl/Lib/LXPageTab/LXPageTabView.h:
--------------------------------------------------------------------------------
1 | //
2 | // LXPageTabView.h
3 | // XXPageTabDemo
4 | //
5 | // Created by LX Zeng on 2017/2/27.
6 | // Copyright © 2017年 https://github.com/nick8brown All rights reserved.
7 | //
8 |
9 | #import
10 | #import "LXPageTabItemLable.h"
11 |
12 | typedef NS_ENUM(NSInteger, LXPageTabTitleStyle) {
13 | LXPageTabTitleStyleDefault, //正常
14 | LXPageTabTitleStyleGradient, //渐变
15 | LXPageTabTitleStyleBlend //填充
16 | };
17 |
18 | typedef NS_ENUM(NSInteger, LXPageTabIndicatorStyle) {
19 | LXPageTabIndicatorStyleDefault, //正常,自定义宽度
20 | LXPageTabIndicatorStyleFollowText, //跟随文本长度变化
21 | LXPageTabIndicatorStyleStretch //拉伸
22 | };
23 |
24 | @protocol LXPageTabViewDelegate
25 | @optional
26 | /*切换完成代理方法*/
27 | - (void)pageTabViewDidEndChange;
28 | @end
29 |
30 | @interface LXPageTabView : UIView
31 |
32 | @property (nonatomic, weak) id delegate;
33 |
34 | /*设置当前选择项(无动画效果)*/
35 | @property (nonatomic, assign) NSInteger selectedTabIndex;
36 | /*一页展示最多的item个数,如果比item总数少,按照item总数计算*/
37 | @property (nonatomic, assign) NSInteger maxNumberOfPageItems;
38 | /*tab size,默认(self.width, 38.0)*/
39 | @property (nonatomic, assign) CGSize tabSize;
40 | /*item的字体大小*/
41 | @property (nonatomic, strong) UIFont *tabItemFont;
42 | /*未选择颜色*/
43 | @property (nonatomic, strong) UIColor *unSelectedColor;
44 | /*当前选中颜色*/
45 | @property (nonatomic, strong) UIColor *selectedColor;
46 | /*tab背景色,默认white*/
47 | @property (nonatomic, strong) UIColor *tabBackgroundColor;
48 | /*body背景色,默认white*/
49 | @property (nonatomic, strong) UIColor *bodyBackgroundColor;
50 | /*是否打开body的边界弹动效果*/
51 | @property (nonatomic, assign) BOOL bodyBounces;
52 |
53 | /*Title效果设置*/
54 | @property (nonatomic, assign) LXPageTabTitleStyle titleStyle;
55 | /*字体渐变,未选择的item的scale,默认是0.8(0~1)。仅LXPageTabTitleStyleScale生效*/
56 | @property (nonatomic, assign) CGFloat minScale;
57 |
58 | /*Indicator效果设置*/
59 | @property (nonatomic, assign) LXPageTabIndicatorStyle indicatorStyle;
60 | /*下标高度,默认是2.0*/
61 | @property (nonatomic, assign) CGFloat indicatorHeight;
62 | /*下标宽度,默认是0。LXPageTabIndicatorStyleFollowText时无效*/
63 | @property (nonatomic, assign) CGFloat indicatorWidth;
64 |
65 | - (instancetype)initWithChildControllers:(NSArray *)childControllers
66 | childTitles:(NSArray *)childTitles;
67 |
68 | @end
69 |
--------------------------------------------------------------------------------
/LXSegmentControl/LXSegmentType_0ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // LXSegmentType_0ViewController.m
3 | // LXSegmentControl
4 | //
5 | // Created by LX Zeng on 2018/12/3.
6 | // Copyright © 2018 https://github.com/nick8brown All rights reserved.
7 | //
8 |
9 | #import "LXSegmentType_0ViewController.h"
10 |
11 | #import "LXSegmentTitleViewController.h"
12 |
13 | #import "XXPageTabView.h"
14 |
15 | @interface LXSegmentType_0ViewController ()
16 |
17 | {
18 | XXPageTabView *_pageTabView;
19 | }
20 |
21 | @end
22 |
23 | @implementation LXSegmentType_0ViewController
24 |
25 | #pragma mark - life cycle
26 | - (void)viewDidLoad {
27 | [super viewDidLoad];
28 |
29 | // 初始化导航栏
30 | [self setupNavBar];
31 |
32 | // 初始化segmentType_0View
33 | [self setupSegmentType_0View];
34 | }
35 |
36 | #pragma mark - 初始化导航栏
37 | - (void)setupNavBar {
38 | // leftBarButtonItem(返回)
39 | UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
40 | btn.frame = CGRectMake(0, 0, 20, 20);
41 | [btn setImage:ImageNamed(@"back") forState:UIControlStateNormal];
42 | [btn addTarget:self action:@selector(returnBtnClick:) forControlEvents:UIControlEventTouchUpInside];
43 | UIBarButtonItem *returnItem = [[UIBarButtonItem alloc] initWithCustomView:btn];
44 |
45 | self.navigationItem.leftBarButtonItems = @[returnItem];
46 | }
47 |
48 | // 返回
49 | - (void)returnBtnClick:(UIButton *)sender {
50 | [self.navigationController popViewControllerAnimated:YES];
51 | }
52 |
53 | #pragma mark - 初始化segmentType_0View
54 | - (void)setupSegmentType_0View {
55 | // 1.我的项目组
56 | LXSegmentTitleViewController *title_0VC = [[LXSegmentTitleViewController alloc] init];
57 | title_0VC.view.backgroundColor = SYS_Cyan_Color;
58 |
59 | // 2.通讯录
60 | LXSegmentTitleViewController *title_1VC = [[LXSegmentTitleViewController alloc] init];
61 | title_1VC.view.backgroundColor = SYS_Yellow_Color;
62 |
63 | [self addChildViewController:title_0VC];
64 | [self addChildViewController:title_1VC];
65 |
66 | _pageTabView = [[XXPageTabView alloc] initWithChildControllers:self.childViewControllers childTitles:@[@"我的好友", @"通讯录"]];
67 | _pageTabView.frame = CGRectMake(0, SYS_NavigationBar_HEIGHT, kScreen_WIDTH, kScreen_HEIGHT-SYS_NavigationBar_HEIGHT);
68 | _pageTabView.tabSize = CGSizeMake(kScreen_WIDTH, 44);
69 | _pageTabView.tabItemFont = AppFont(15);
70 | _pageTabView.unSelectedColor = AppHTMLColor(@"999999");
71 | _pageTabView.selectedColor = AppHTMLColor(@"4bccbc");
72 | _pageTabView.bodyBounces = NO;
73 | _pageTabView.titleStyle = XXPageTabTitleStyleDefault;
74 | _pageTabView.indicatorStyle = XXPageTabIndicatorStyleFollowText;
75 | _pageTabView.delegate = self;
76 | [self.view addSubview:_pageTabView];
77 | }
78 |
79 | #pragma mark - XXPageTabViewDelegate
80 | - (void)pageTabViewDidEndChange {
81 | NSInteger selectedTabIndex = _pageTabView.selectedTabIndex;
82 | NSLog(@"点击了index:%zd", selectedTabIndex);
83 |
84 | switch (selectedTabIndex) {
85 | case 0:
86 | {
87 | // 我的好友
88 | }
89 | break;
90 | case 1:
91 | {
92 | // 通讯录
93 | }
94 | break;
95 | }
96 | }
97 |
98 | @end
99 |
--------------------------------------------------------------------------------
/LXSegmentControl/LX_Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // LX_Prefix.pch
3 | // LXHealthIndicatorDemo
4 | //
5 | // Created by LX Zeng on 2018/11/22.
6 | // Copyright © 2018 https://github.com/nick8brown All rights reserved.
7 | //
8 |
9 | #ifndef LX_Prefix_pch
10 | #define LX_Prefix_pch
11 |
12 |
13 | /*------------------------------视图大小位置------------------------------*/
14 |
15 | // 屏幕尺寸
16 | #define kScreen_WIDTH [UIScreen mainScreen].bounds.size.width
17 | #define kScreen_HEIGHT [UIScreen mainScreen].bounds.size.height
18 |
19 | #define SCREEN_RATIO (kScreen_WIDTH/375)
20 |
21 | // iPhone机型
22 | #define IS_iPhone5s_Before ((kScreen_WIDTH == 320) ? YES : NO)
23 | #define IS_iPhone6s_Later ((kScreen_WIDTH == 375) ? YES : NO)
24 | #define IS_iPhone6sPlus_Later ((kScreen_WIDTH == 414) ? YES : NO)
25 | #define IS_iPhoneX ((kScreen_WIDTH == 375 && kScreen_HEIGHT == 812) ? YES : NO)
26 |
27 | // iPhone版本
28 | #define IS_iOS11_Later (([[UIDevice currentDevice].systemVersion floatValue] >= 11.0) ? YES : NO)
29 |
30 | // 系统性参数
31 | #define SYS_StatusBar_HEIGHT ((!IS_iPhoneX) ? 20 : SYS_SafeArea_TOP)
32 | #define SYS_NavigationBar_HEIGHT (SYS_StatusBar_HEIGHT+44)
33 | #define SYS_Toolbar_HEIGHT 44
34 | #define SYS_TabBar_HEIGHT ((!IS_iPhoneX) ? 49 : (49+SYS_SafeArea_BOTTOM))
35 | #define SYS_Spacing_HEIGHT 8
36 |
37 | #define SYS_SafeArea_TOP ((IS_iPhoneX) ? 44 : 0)
38 | #define SYS_SafeArea_BOTTOM ((IS_iPhoneX) ? 34 : 0)
39 |
40 | // 最小间隔
41 | #define minimumSpacing 10
42 |
43 |
44 | /*------------------------------字体、颜色------------------------------*/
45 |
46 | // 系统颜色
47 | #define SYS_Black_Color [UIColor blackColor]
48 | #define SYS_DarkGray_Color [UIColor darkGrayColor]
49 | #define SYS_LightGray_Color [UIColor lightGrayColor]
50 | #define SYS_White_Color [UIColor whiteColor]
51 | #define SYS_Gray_Color [UIColor grayColor]
52 | #define SYS_Red_Color [UIColor redColor]
53 | #define SYS_Green_Color [UIColor greenColor]
54 | #define SYS_Blue_Color [UIColor blueColor]
55 | #define SYS_Cyan_Color [UIColor cyanColor]
56 | #define SYS_Yellow_Color [UIColor yellowColor]
57 | #define SYS_Magenta_Color [UIColor magentaColor]
58 | #define SYS_Orange_Color [UIColor orangeColor]
59 | #define SYS_Purple_Color [UIColor purpleColor]
60 | #define SYS_Brown_Color [UIColor brownColor]
61 | #define SYS_Clear_Color [UIColor clearColor]
62 | #define SYS_Random_Color [UIColor randomColor]
63 |
64 | // 字体
65 | #define AppFont(x) [UIFont systemFontOfSize:x]
66 | #define AppBoldFont(x) [UIFont boldSystemFontOfSize:x]
67 |
68 | // 颜色
69 | #define AppColor(r, g, b) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:1]
70 | #define AppAlphaColor(r, g, b, a) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:a]
71 |
72 | #define AppHTMLColor(html) [UIColor colorWithHexString:html]
73 |
74 |
75 | /*------------------------------图片------------------------------*/
76 |
77 | #define ImageNamed(name) [UIImage imageNamed:name]
78 | #define URLWithString(url) [NSURL URLWithString:url]
79 |
80 |
81 | /*------------------------------其它------------------------------*/
82 |
83 | #import "UIColor+LX.h"
84 | #import "UIImage+LX.h"
85 |
86 | // tag基数
87 | #define BASE_TAG 100
88 |
89 | // tableView注册
90 | #define RegisterClass_for_Cell(tableViewCell) [self.tableView registerClass:[tableViewCell class] forCellReuseIdentifier:NSStringFromClass([tableViewCell class])]
91 | #define RegisterClass_for_HeaderFooterView(tableViewHeaderFooterView) [self.tableView registerClass:[tableViewHeaderFooterView class] forHeaderFooterViewReuseIdentifier:NSStringFromClass([tableViewHeaderFooterView class])]
92 | #define RegisterNib_for_Cell(tableViewCell) [self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([tableViewCell class]) bundle:[NSBundle mainBundle]] forCellReuseIdentifier:NSStringFromClass([tableViewCell class])]
93 | #define RegisterNib_for_HeaderFooterView(tableViewHeaderFooterView) [self.tableView registerNib:[UINib nibWithNibName:NSStringFromClass([tableViewCell class]) bundle:[NSBundle mainBundle]] forCellReuseIdentifier:NSStringFromClass([tableViewCell class])]
94 |
95 | // tableView出列
96 | #define DequeueReusable_Cell [tableView dequeueReusableCellWithIdentifier:NSStringFromClass([self class])]
97 | #define DequeueReusable_HeaderFooterView [tableView dequeueReusableHeaderFooterViewWithIdentifier:NSStringFromClass([self class])]
98 |
99 |
100 | #endif /* LX_Prefix_pch */
101 |
--------------------------------------------------------------------------------
/LXSegmentControl/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
29 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
--------------------------------------------------------------------------------
/LXSegmentControl/LXSegmentType_1ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // LXSegmentType_1ViewController.m
3 | // LXSegmentControl
4 | //
5 | // Created by LX Zeng on 2018/12/3.
6 | // Copyright © 2018 https://github.com/nick8brown All rights reserved.
7 | //
8 |
9 | #import "LXSegmentType_1ViewController.h"
10 |
11 | #import "LXSegmentTitleViewController.h"
12 |
13 | #import "LXPageTabView.h"
14 |
15 | #define CellIdentifier @"Cell"
16 |
17 | @interface LXSegmentType_1ViewController ()
18 |
19 | {
20 | LXPageTabView *_pageTabView;
21 | }
22 | @property (nonatomic, strong) NSArray *titleArray;
23 | @property (nonatomic, strong) NSMutableArray *tableViewArray;
24 |
25 | @end
26 |
27 | @implementation LXSegmentType_1ViewController
28 |
29 | #pragma mark - lazy load
30 | - (NSArray *)titleArray {
31 | if (!_titleArray) {
32 | _titleArray = @[@"礼物TOP100", @"每日推荐", @"新星榜", @"送女友", @"送基友", @"送同事", @"送长辈"];
33 | }
34 | return _titleArray;
35 | }
36 |
37 | - (NSMutableArray *)tableViewArray {
38 | if (!_tableViewArray) {
39 | _tableViewArray = [NSMutableArray array];
40 | }
41 | return _tableViewArray;
42 | }
43 |
44 | #pragma mark - life cycle
45 | - (void)viewDidLoad {
46 | [super viewDidLoad];
47 |
48 | // 初始化导航栏
49 | [self setupNavBar];
50 |
51 | // 初始化segmentType_1View
52 | [self setupSegmentType_1View];
53 | }
54 |
55 | #pragma mark - 初始化导航栏
56 | - (void)setupNavBar {
57 | // leftBarButtonItem(返回)
58 | UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
59 | btn.frame = CGRectMake(0, 0, 20, 20);
60 | [btn setImage:ImageNamed(@"back") forState:UIControlStateNormal];
61 | [btn addTarget:self action:@selector(returnBtnClick:) forControlEvents:UIControlEventTouchUpInside];
62 | UIBarButtonItem *returnItem = [[UIBarButtonItem alloc] initWithCustomView:btn];
63 |
64 | self.navigationItem.leftBarButtonItems = @[returnItem];
65 | }
66 |
67 | // 返回
68 | - (void)returnBtnClick:(UIButton *)sender {
69 | [self.navigationController popViewControllerAnimated:YES];
70 | }
71 |
72 | #pragma mark - 初始化segmentType_1View
73 | - (void)setupSegmentType_1View {
74 | for (int i = 0; i < self.titleArray.count; i++) {
75 | LXSegmentTitleViewController *vc = [[LXSegmentTitleViewController alloc] init];
76 |
77 | // 初始化tableView
78 | [vc.view addSubview:[self setupTableView:i]];
79 |
80 | [self addChildViewController:vc];
81 | }
82 |
83 | _pageTabView = [[LXPageTabView alloc] initWithChildControllers:self.childViewControllers childTitles:self.titleArray];
84 | _pageTabView.frame = CGRectMake(0, SYS_NavigationBar_HEIGHT, kScreen_WIDTH, kScreen_HEIGHT-SYS_NavigationBar_HEIGHT);
85 | _pageTabView.tabSize = CGSizeMake(kScreen_WIDTH, 40);
86 | _pageTabView.tabItemFont = AppFont(15);
87 | _pageTabView.unSelectedColor = AppHTMLColor(@"c8c8c8");
88 | _pageTabView.selectedColor = AppHTMLColor(@"ffffff");
89 | _pageTabView.tabBackgroundColor = AppHTMLColor(@"ee8c8e");
90 | _pageTabView.bodyBounces = NO;
91 | _pageTabView.titleStyle = LXPageTabTitleStyleDefault;
92 | _pageTabView.indicatorStyle = LXPageTabIndicatorStyleDefault;
93 | _pageTabView.indicatorWidth = 20;
94 | _pageTabView.indicatorHeight = 10;
95 | _pageTabView.delegate = self;
96 | [self.view addSubview:_pageTabView];
97 | }
98 |
99 | // 初始化tableView
100 | - (UITableView *)setupTableView:(NSInteger)index {
101 | UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, kScreen_WIDTH, kScreen_HEIGHT-SYS_NavigationBar_HEIGHT-40) style:UITableViewStyleGrouped];
102 | tableView.backgroundColor = SYS_White_Color;
103 | tableView.dataSource = self;
104 | tableView.delegate = self;
105 | tableView.showsHorizontalScrollIndicator = NO;
106 | tableView.showsVerticalScrollIndicator = NO;
107 | tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
108 |
109 | [self.tableViewArray addObject:tableView];
110 |
111 | return tableView;
112 | }
113 |
114 | #pragma mark - UITableViewDataSource
115 | // 段数
116 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
117 | return 1;
118 | }
119 |
120 | // 行数
121 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
122 | return 15;
123 | }
124 |
125 | // cell样式
126 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
127 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
128 | if (!cell) {
129 | cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
130 | }
131 | cell.textLabel.text = self.titleArray[_pageTabView.selectedTabIndex];
132 | return cell;
133 | }
134 |
135 | #pragma mark - UITableViewDelegate
136 | // 行高
137 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
138 | return 50;
139 | }
140 |
141 | // 段头高度
142 | - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
143 | return CGFLOAT_MIN;
144 | }
145 |
146 | // 段尾高度
147 | - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
148 | return CGFLOAT_MIN;
149 | }
150 |
151 | // 段头视图
152 | - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section {
153 | return [[UIView alloc] init];
154 | }
155 |
156 | // 段尾视图
157 | - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section {
158 | return [[UIView alloc] init];
159 | }
160 |
161 | // 选中某行
162 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
163 | }
164 |
165 | #pragma mark - LXPageTabViewDelegate
166 | - (void)pageTabViewDidEndChange {
167 | NSInteger selectedTabIndex = _pageTabView.selectedTabIndex;
168 | NSLog(@"点击了index:%zd", selectedTabIndex);
169 |
170 | //
171 | [self.tableViewArray[selectedTabIndex] reloadData];
172 | }
173 |
174 | @end
175 |
--------------------------------------------------------------------------------
/LXSegmentControl/Lib/LXPageTab/LXPageTabView.m:
--------------------------------------------------------------------------------
1 | //
2 | // LXPageTabView.m
3 | // XXPageTabDemo
4 | //
5 | // Created by LX Zeng on 2017/2/27.
6 | // Copyright © 2017年 https://github.com/nick8brown All rights reserved.
7 | //
8 |
9 | #import "LXPageTabView.h"
10 |
11 | #define kTabDefautHeight 38.0
12 | #define kTabDefautFontSize 15.0
13 | #define kMaxNumberOfPageItems 4
14 | #define kIndicatorHeight 2.0
15 | #define kIndicatorWidth 20
16 | #define kMinScale 0.8
17 |
18 | #define HEIGHT(view) view.bounds.size.height
19 | #define WIDTH(view) view.bounds.size.width
20 | #define ORIGIN_X(view) view.frame.origin.x
21 | #define ORIGIN_Y(view) view.frame.origin.y
22 |
23 | @interface LXPageTabView ()
24 | //bg
25 | @property (nonatomic, strong) UIView *bgView; //由于遇到nav->vc,vc的第一个子试图是UIScrollView会自动产生64像素偏移,所以加上一个虚拟背景(没有尺寸)
26 |
27 | //tab
28 | @property (nonatomic, strong) UIScrollView *tabView;
29 | @property (nonatomic, strong) UIImageView *indicatorView;
30 |
31 | //body
32 | @property (nonatomic, strong) UIScrollView *bodyView;
33 |
34 | //data
35 | @property (nonatomic, assign) NSInteger lastSelectedTabIndex; //记录上一次的索引
36 | @property (nonatomic, assign) NSInteger numberOfTabItems;
37 | @property (nonatomic, assign) CGFloat tabItemWidth;
38 | @property (nonatomic, strong) NSMutableArray *tabItems;
39 | @property (nonatomic, strong) NSArray *childControllers;
40 | @property (nonatomic, strong) NSArray *childTitles;
41 |
42 | //animation
43 | @property (nonatomic, assign) BOOL isNeedRefreshLayout; //滑动过程中不允许layoutSubviews
44 | @property (nonatomic, assign) BOOL isChangeByClick; //是否是通过点击改变的。因为点击可以长距离点击,部分效果不作处理会出现途中经过的按钮也会依次有效果(仿网易客户端有此效果,个人觉得并不好,头条的客户端更合理)
45 | @property (nonatomic, assign) NSInteger leftItemIndex; //记录滑动时左边的itemIndex
46 | @property (nonatomic, assign) NSInteger rightItemIndex; //记录滑动时右边的itemIndex
47 |
48 | /*LXPageTabTitleStyleScale*/
49 | @property (nonatomic, assign) CGFloat selectedColorR;
50 | @property (nonatomic, assign) CGFloat selectedColorG;
51 | @property (nonatomic, assign) CGFloat selectedColorB;
52 | @property (nonatomic, assign) CGFloat unSelectedColorR;
53 | @property (nonatomic, assign) CGFloat unSelectedColorG;
54 | @property (nonatomic, assign) CGFloat unSelectedColorB;
55 |
56 | @end
57 |
58 | @implementation LXPageTabView
59 |
60 | #pragma mark - Life cycle
61 | - (instancetype)initWithChildControllers:(NSArray *)childControllers
62 | childTitles:(NSArray *)childTitles {
63 | self = [super init];
64 | if(self) {
65 | _childControllers = childControllers;
66 | _childTitles = childTitles;
67 |
68 | [self initBaseSettings];
69 | [self initTabView];
70 | [self initMainView];
71 | }
72 | return self;
73 | }
74 |
75 | - (void)layoutSubviews {
76 | if(_isNeedRefreshLayout) {
77 | //tab layout
78 | if(_tabSize.height <= 0) {
79 | _tabSize.height = kTabDefautHeight;
80 | }
81 | if(_tabSize.width <= 0) {
82 | _tabSize.width = WIDTH(self);
83 | }
84 | _tabItemWidth = _tabSize.width/(_numberOfTabItems<_maxNumberOfPageItems?_numberOfTabItems:_maxNumberOfPageItems);
85 |
86 | self.tabView.frame = CGRectMake(0, 0, _tabSize.width, _tabSize.height);
87 | self.tabView.contentSize = CGSizeMake(_tabItemWidth*_numberOfTabItems, 0);
88 |
89 | for(NSInteger i = 0; i < _tabItems.count; i++) {
90 | LXPageTabItemLable *tabItem = (LXPageTabItemLable *)_tabItems[i];
91 | tabItem.frame = CGRectMake(_tabItemWidth*i, 4, _tabItemWidth, _tabSize.height-_indicatorHeight-4);
92 | }
93 | [self layoutIndicatorViewWithStyle];
94 |
95 | //body layout
96 | self.bodyView.frame = CGRectMake(0, _tabSize.height, WIDTH(self), HEIGHT(self)-_tabSize.height);
97 | self.bodyView.contentSize = CGSizeMake(WIDTH(self)*_numberOfTabItems, 0);
98 | self.bodyView.contentOffset = CGPointMake(self.frame.size.width*_selectedTabIndex, 0);
99 | [self reviseTabContentOffsetBySelectedIndex:NO];
100 |
101 | for(NSInteger i = 0; i < _numberOfTabItems; i++) {
102 | UIViewController *childController = _childControllers[i];
103 | childController.view.frame = CGRectMake(WIDTH(self)*i, 0, WIDTH(self), HEIGHT(self)-_tabSize.height);
104 | }
105 | }
106 | }
107 |
108 | #pragma mark - Layout
109 | - (void)initBaseSettings {
110 | _selectedTabIndex = 0;
111 | _lastSelectedTabIndex = 0;
112 | _tabSize = CGSizeZero;
113 | _numberOfTabItems = _childControllers.count>_childTitles.count?_childTitles.count:_childControllers.count;
114 | _tabItemFont = [UIFont systemFontOfSize:kTabDefautFontSize];
115 | _indicatorHeight = kIndicatorHeight;
116 | _indicatorWidth = kIndicatorWidth;
117 | _maxNumberOfPageItems = kMaxNumberOfPageItems;
118 | _tabItems = [NSMutableArray array];
119 | _tabBackgroundColor = [UIColor whiteColor];
120 | _bodyBackgroundColor = [UIColor whiteColor];
121 | _unSelectedColor = [UIColor blackColor];
122 | _selectedColor = [UIColor redColor];
123 | _isNeedRefreshLayout = YES;
124 | _isChangeByClick = NO;
125 | _bodyBounces = YES;
126 | _titleStyle = LXPageTabTitleStyleDefault;
127 | _indicatorStyle = LXPageTabIndicatorStyleDefault;
128 | _minScale = kMinScale;
129 | _selectedColorR = 1;
130 | _selectedColorG = 0;
131 | _selectedColorB = 0;
132 | _unSelectedColorR = 0;
133 | _unSelectedColorG = 0;
134 | _unSelectedColorB = 0;
135 | }
136 |
137 | - (void)initTabView {
138 | [self addSubview:self.bgView];
139 | [self addSubview:self.tabView];
140 |
141 | for(NSInteger i = 0; i < _numberOfTabItems; i++) {
142 | LXPageTabItemLable *tabItem = [[LXPageTabItemLable alloc] init];
143 | tabItem.font = _tabItemFont;
144 | tabItem.text = _childTitles[i];
145 | tabItem.textColor = i==_selectedTabIndex?_selectedColor:_unSelectedColor;
146 | tabItem.textAlignment = NSTextAlignmentCenter;
147 | tabItem.userInteractionEnabled = YES;
148 |
149 | UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(changeChildControllerOnClick:)];
150 | [tabItem addGestureRecognizer:tapRecognizer];
151 | [_tabItems addObject:tabItem];
152 | [self.tabView addSubview:tabItem];
153 | }
154 | }
155 |
156 | - (void)initMainView {
157 | [self addSubview:self.bodyView];
158 | for(NSInteger i = 0; i < _numberOfTabItems; i++) {
159 | UIViewController *childController = _childControllers[i];
160 | [self.bodyView addSubview:childController.view];
161 | }
162 | }
163 |
164 | /**
165 | 根据选择项修正tab的展示区域
166 | */
167 | - (void)reviseTabContentOffsetBySelectedIndex:(BOOL)isAnimate {
168 | LXPageTabItemLable *currentTabItem = _tabItems[_selectedTabIndex];
169 | CGFloat selectedItemCenterX = currentTabItem.center.x;
170 |
171 | CGFloat reviseX;
172 | if(selectedItemCenterX + _tabSize.width/2.0 >= self.tabView.contentSize.width) {
173 | reviseX = self.tabView.contentSize.width - _tabSize.width; //不足以到中心,靠右
174 | } else if(selectedItemCenterX - _tabSize.width/2.0 <= 0) {
175 | reviseX = 0; //不足以到中心,靠左
176 | } else {
177 | reviseX = selectedItemCenterX - _tabSize.width/2.0; //修正至中心
178 | }
179 | //如果前后没有偏移量差,setContentOffset实际不起作用;或者没有动画效果
180 | if(fabs(self.tabView.contentOffset.x - reviseX)<1 || !isAnimate) {
181 | [self finishReviseTabContentOffset];
182 | }
183 | [self.tabView setContentOffset:CGPointMake(reviseX, 0) animated:isAnimate];
184 | }
185 |
186 | /**
187 | tabview修正完成后的操作,无论是点击还是滑动body,此方法都是真正意义上的最后一步
188 | */
189 | - (void)finishReviseTabContentOffset {
190 | _tabView.userInteractionEnabled = YES;
191 | _isNeedRefreshLayout = YES;
192 | _isChangeByClick = NO;
193 | if([self.delegate respondsToSelector:@selector(pageTabViewDidEndChange)]) {
194 | if(_lastSelectedTabIndex != _selectedTabIndex) {
195 | [self.delegate pageTabViewDidEndChange];
196 | }
197 | }
198 | _lastSelectedTabIndex = _selectedTabIndex;
199 | }
200 |
201 | /**
202 | 一般常用改变selected Item方法(无动画效果,直接变色)
203 | */
204 | - (void)changeSelectedItemToNextItem:(NSInteger)nextIndex {
205 | LXPageTabItemLable *currentTabItem = _tabItems[_selectedTabIndex];
206 | LXPageTabItemLable *nextTabItem = _tabItems[nextIndex];
207 | currentTabItem.textColor = _unSelectedColor;
208 | nextTabItem.textColor = _selectedColor;
209 | }
210 |
211 | #pragma mark -Title layout
212 | /**
213 | 重新设置item的缩放比例
214 | */
215 | - (void)resetTabItemScale {
216 | for(NSInteger i = 0; i < _numberOfTabItems; i++) {
217 | LXPageTabItemLable *tabItem = _tabItems[i];
218 | if(i != _selectedTabIndex) {
219 | tabItem.transform = CGAffineTransformMakeScale(_minScale, _minScale);
220 | } else {
221 | tabItem.transform = CGAffineTransformMakeScale(1, 1);
222 | }
223 | }
224 | }
225 |
226 | #pragma mark -Indicator layout
227 | /**
228 | 根据不同风格添加相应下标
229 | */
230 | - (void)addIndicatorViewWithStyle {
231 | switch (_indicatorStyle) {
232 | case LXPageTabIndicatorStyleDefault:
233 | case LXPageTabIndicatorStyleFollowText:
234 | case LXPageTabIndicatorStyleStretch:
235 | [self addSubview:self.indicatorView];
236 | break;
237 | default:
238 | break;
239 | }
240 | }
241 |
242 | /**
243 | 根据不同风格对下标layout
244 | */
245 | - (void)layoutIndicatorViewWithStyle {
246 | switch (_indicatorStyle) {
247 | case LXPageTabIndicatorStyleDefault:
248 | case LXPageTabIndicatorStyleFollowText:
249 | case LXPageTabIndicatorStyleStretch:
250 | [self layoutIndicatorView];
251 | break;
252 | default:
253 | break;
254 | }
255 | }
256 |
257 | - (void)layoutIndicatorView {
258 | // CGFloat indicatorWidth = [self getIndicatorWidthWithTitle:_childTitles[_selectedTabIndex]];
259 | LXPageTabItemLable *selecedTabItem = _tabItems[_selectedTabIndex];
260 | self.indicatorView.frame = CGRectMake(selecedTabItem.center.x-_indicatorWidth/2.0-_tabView.contentOffset.x, _tabSize.height-_indicatorHeight+1, _indicatorWidth, _indicatorHeight);
261 | }
262 |
263 | #pragma mark - Event response
264 | - (void)changeChildControllerOnClick:(UITapGestureRecognizer *)tap {
265 | NSInteger nextIndex = [_tabItems indexOfObject:tap.view];
266 | if(nextIndex != _selectedTabIndex) {
267 | if(_titleStyle == LXPageTabTitleStyleDefault) {
268 | [self changeSelectedItemToNextItem:nextIndex];
269 | }
270 |
271 | _isChangeByClick = YES;
272 | _tabView.userInteractionEnabled = NO; //防止快速切换
273 | _leftItemIndex = nextIndex > _selectedTabIndex?_selectedTabIndex:nextIndex;
274 | _rightItemIndex = nextIndex > _selectedTabIndex?nextIndex:_selectedTabIndex;
275 | _selectedTabIndex = nextIndex;
276 | [self.bodyView setContentOffset:CGPointMake(self.frame.size.width*_selectedTabIndex, 0) animated:YES];
277 | }
278 | }
279 |
280 | #pragma mark - UIScrollViewDelegate
281 | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
282 | if(scrollView == self.bodyView) {
283 | _selectedTabIndex = self.bodyView.contentOffset.x/WIDTH(self.bodyView);
284 | [self reviseTabContentOffsetBySelectedIndex:YES];
285 | }
286 | }
287 |
288 | - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
289 | if(scrollView == self.bodyView) {
290 | [self reviseTabContentOffsetBySelectedIndex:YES];
291 | } else {
292 | [self finishReviseTabContentOffset];
293 | }
294 | }
295 |
296 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
297 | if(scrollView == self.tabView) {
298 | _isNeedRefreshLayout = NO;
299 | if(self.indicatorView.superview) {
300 | LXPageTabItemLable *selecedTabItem = _tabItems[_selectedTabIndex];
301 | self.indicatorView.frame = CGRectMake(selecedTabItem.center.x-WIDTH(self.indicatorView)/2.0-scrollView.contentOffset.x, ORIGIN_Y(self.indicatorView), WIDTH(self.indicatorView), HEIGHT(self.indicatorView));
302 | }
303 | } else if(scrollView == self.bodyView) {
304 | //未初始化时不处理
305 | if(self.bodyView.contentSize.width <= 0) {
306 | return;
307 | }
308 | //滚动过程中不允许layout
309 | _isNeedRefreshLayout = NO;
310 | //获取当前左右item index(点击方式已获知左右index,无需根据contentoffset计算)
311 | if(!_isChangeByClick) {
312 | if(self.bodyView.contentOffset.x <= 0) { //左边界
313 | _leftItemIndex = 0;
314 | _rightItemIndex = 0;
315 |
316 | } else if(self.bodyView.contentOffset.x >= self.bodyView.contentSize.width-WIDTH(self.bodyView)) { //右边界
317 | _leftItemIndex = _numberOfTabItems-1;
318 | _rightItemIndex = _numberOfTabItems-1;
319 |
320 | } else {
321 | _leftItemIndex = (int)(self.bodyView.contentOffset.x/WIDTH(self.bodyView));
322 | _rightItemIndex = _leftItemIndex + 1;
323 | }
324 | }
325 |
326 | //调整title
327 | switch (_titleStyle) {
328 | case LXPageTabTitleStyleDefault:
329 | [self changeTitleWithDefault];
330 | break;
331 | case LXPageTabTitleStyleGradient:
332 | [self changeTitleWithGradient];
333 | break;
334 | case LXPageTabTitleStyleBlend:
335 | [self changeTitleWithBlend];
336 | break;
337 | default:
338 | break;
339 | }
340 |
341 | //调整indicator
342 | switch (_indicatorStyle) {
343 | case LXPageTabIndicatorStyleDefault:
344 | case LXPageTabIndicatorStyleFollowText:
345 | [self changeIndicatorFrame];
346 | break;
347 | case LXPageTabIndicatorStyleStretch:
348 | {
349 | if(_isChangeByClick) {
350 | [self changeIndicatorFrame];
351 | } else {
352 | [self changeIndicatorFrameByStretch];
353 | }
354 | }
355 | break;
356 | default:
357 | break;
358 | }
359 | }
360 | }
361 |
362 | #pragma mark - Title animation
363 | - (void)changeTitleWithDefault {
364 | CGFloat relativeLocation = self.bodyView.contentOffset.x/WIDTH(self.bodyView)-_leftItemIndex;
365 | if(!_isChangeByClick) {
366 | if(relativeLocation > 0.5) {
367 | [self changeSelectedItemToNextItem:_rightItemIndex];
368 | _selectedTabIndex = _rightItemIndex;
369 | } else {
370 | [self changeSelectedItemToNextItem:_leftItemIndex];
371 | _selectedTabIndex = _leftItemIndex;
372 | }
373 | }
374 | }
375 |
376 | - (void)changeTitleWithGradient {
377 | if(_leftItemIndex != _rightItemIndex) {
378 | CGFloat rightScale = (self.bodyView.contentOffset.x/WIDTH(self.bodyView)-_leftItemIndex)/(_rightItemIndex-_leftItemIndex);
379 | CGFloat leftScale = 1-rightScale;
380 |
381 | //颜色渐变
382 | CGFloat difR = _selectedColorR-_unSelectedColorR;
383 | CGFloat difG = _selectedColorG-_unSelectedColorG;
384 | CGFloat difB = _selectedColorB-_unSelectedColorB;
385 |
386 | UIColor *leftItemColor = [UIColor colorWithRed:_unSelectedColorR+leftScale*difR green:_unSelectedColorG+leftScale*difG blue:_unSelectedColorB+leftScale*difB alpha:1];
387 | UIColor *rightItemColor = [UIColor colorWithRed:_unSelectedColorR+rightScale*difR green:_unSelectedColorG+rightScale*difG blue:_unSelectedColorB+rightScale*difB alpha:1];
388 |
389 | LXPageTabItemLable *leftTabItem = _tabItems[_leftItemIndex];
390 | LXPageTabItemLable *rightTabItem = _tabItems[_rightItemIndex];
391 | leftTabItem.textColor = leftItemColor;
392 | rightTabItem.textColor = rightItemColor;
393 |
394 | //字体渐变
395 | leftTabItem.transform = CGAffineTransformMakeScale(_minScale+(1-_minScale)*leftScale, _minScale+(1-_minScale)*leftScale);
396 | rightTabItem.transform = CGAffineTransformMakeScale(_minScale+(1-_minScale)*rightScale, _minScale+(1-_minScale)*rightScale);
397 | }
398 | }
399 |
400 | - (void)changeTitleWithBlend {
401 | CGFloat leftScale = self.bodyView.contentOffset.x/WIDTH(self.bodyView)-_leftItemIndex;
402 | if(leftScale == 0) {
403 | return; //起点和终点不处理,终点时左右index已更新,会绘画错误(你可以注释看看)
404 | }
405 |
406 | LXPageTabItemLable *leftTabItem = _tabItems[_leftItemIndex];
407 | LXPageTabItemLable *rightTabItem = _tabItems[_rightItemIndex];
408 |
409 | leftTabItem.textColor = _selectedColor;
410 | rightTabItem.textColor = _unSelectedColor;
411 | leftTabItem.process = leftScale;
412 | rightTabItem.process = leftScale;
413 | }
414 |
415 | #pragma mark - Indicator animation
416 | - (void)changeIndicatorFrame {
417 | //计算indicator此时的centerx
418 | CGFloat nowIndicatorCenterX = _tabItemWidth*(0.5+self.bodyView.contentOffset.x/WIDTH(self.bodyView));
419 | //计算此时body的偏移量在一页中的占比
420 | CGFloat relativeLocation = (self.bodyView.contentOffset.x/WIDTH(self.bodyView)-_leftItemIndex)/(_rightItemIndex-_leftItemIndex);
421 | //记录左右对应的indicator宽度
422 | CGFloat leftIndicatorWidth = [self getIndicatorWidthWithTitle:_childTitles[_leftItemIndex]];
423 | CGFloat rightIndicatorWidth = [self getIndicatorWidthWithTitle:_childTitles[_rightItemIndex]];
424 |
425 | //左右边界的时候,占比清0
426 | if(_leftItemIndex == _rightItemIndex) {
427 | relativeLocation = 0;
428 | }
429 | //基于从左到右方向(无需考虑滑动方向),计算当前中心轴所处位置的长度
430 | // CGFloat nowIndicatorWidth = leftIndicatorWidth + (rightIndicatorWidth-leftIndicatorWidth)*relativeLocation;
431 |
432 | self.indicatorView.frame = CGRectMake(nowIndicatorCenterX-WIDTH(self.indicatorView)/2.0-_tabView.contentOffset.x, ORIGIN_Y(self.indicatorView), WIDTH(self.indicatorView), HEIGHT(self.indicatorView));
433 | }
434 |
435 | - (void)changeIndicatorFrameByStretch {
436 | if(_indicatorWidth <= 0) {
437 | return;
438 | }
439 |
440 | //计算此时body的偏移量在一页中的占比
441 | CGFloat relativeLocation = (self.bodyView.contentOffset.x/WIDTH(self.bodyView)-_leftItemIndex)/(_rightItemIndex-_leftItemIndex);
442 | //左右边界的时候,占比清0
443 | if(_leftItemIndex == _rightItemIndex) {
444 | relativeLocation = 0;
445 | }
446 |
447 | LXPageTabItemLable *leftTabItem = _tabItems[_leftItemIndex];
448 | LXPageTabItemLable *rightTabItem = _tabItems[_rightItemIndex];
449 |
450 | //当前的frame
451 | CGRect nowFrame = CGRectMake(0, ORIGIN_Y(self.indicatorView), 0, HEIGHT(self.indicatorView));
452 |
453 | //计算宽度
454 | if(relativeLocation <= 0.5) {
455 | nowFrame.size.width = _indicatorWidth+_tabItemWidth*(relativeLocation/0.5);
456 | nowFrame.origin.x = (leftTabItem.center.x-self.tabView.contentOffset.x)-_indicatorWidth/2.0;
457 | } else {
458 | nowFrame.size.width = _indicatorWidth+_tabItemWidth*((1-relativeLocation)/0.5);
459 | nowFrame.origin.x = (rightTabItem.center.x-self.tabView.contentOffset.x)+_indicatorWidth/2.0-nowFrame.size.width;
460 | }
461 |
462 | self.indicatorView.frame = nowFrame;
463 | }
464 |
465 | #pragma mark - Tool
466 | /**
467 | 根据对应文本计算下标线宽度
468 | */
469 | - (CGFloat)getIndicatorWidthWithTitle:(NSString *)title {
470 | if(_indicatorStyle == LXPageTabIndicatorStyleDefault || _indicatorStyle == LXPageTabIndicatorStyleStretch) {
471 | return _indicatorWidth;
472 | } else {
473 | if(title.length <= 2) {
474 | return 40;
475 | } else {
476 | return title.length * _tabItemFont.pointSize + 12;
477 | }
478 | }
479 | }
480 |
481 | /**
482 | 获取color的rgb值
483 | */
484 | - (NSArray *)getRGBWithColor:(UIColor *)color {
485 | CGFloat R, G, B;
486 | NSInteger numComponents = CGColorGetNumberOfComponents(color.CGColor);
487 | if(numComponents == 4) {
488 | const CGFloat *components = CGColorGetComponents(color.CGColor);
489 | R = components[0];
490 | G = components[1];
491 | B = components[2];
492 | }
493 | return @[@(R), @(G), @(B)];
494 | }
495 |
496 | #pragma mark - Getter/setter
497 | - (UIView *)bgView {
498 | if(!_bgView) {
499 | _bgView = [UIView new];
500 | }
501 | return _bgView;
502 | }
503 |
504 | - (UIScrollView *)tabView {
505 | if(!_tabView) {
506 | _tabView = [UIScrollView new];
507 | _tabView.showsVerticalScrollIndicator = NO;
508 | _tabView.showsHorizontalScrollIndicator = NO;
509 | _tabView.backgroundColor = _tabBackgroundColor;
510 | _tabView.delegate = self;
511 | _tabView.clipsToBounds = YES;
512 | }
513 | return _tabView;
514 | }
515 |
516 | - (UIScrollView *)bodyView {
517 | if(!_bodyView) {
518 | _bodyView = [UIScrollView new];
519 | _bodyView.pagingEnabled = YES;
520 | _bodyView.showsVerticalScrollIndicator = NO;
521 | _bodyView.showsHorizontalScrollIndicator = NO;
522 | _bodyView.delegate = self;
523 | _bodyView.bounces = _bodyBounces;
524 | _bodyView.backgroundColor = _bodyBackgroundColor;
525 | }
526 | return _bodyView;
527 | }
528 |
529 | - (UIImageView *)indicatorView {
530 | if(!_indicatorView) {
531 | _indicatorView = [UIImageView new];
532 | _indicatorView.image = [UIImage imageNamed:@"三角形"];
533 | }
534 | return _indicatorView;
535 | }
536 |
537 | - (void)setTabBackgroundColor:(UIColor *)tabBackgroundColor {
538 | _tabBackgroundColor = tabBackgroundColor;
539 | self.tabView.backgroundColor = _tabBackgroundColor;
540 | }
541 |
542 | - (void)setBodyBackgroundColor:(UIColor *)bodyBackgroundColor {
543 | _bodyBackgroundColor = bodyBackgroundColor;
544 | self.bodyView.backgroundColor = _bodyBackgroundColor;
545 | }
546 |
547 | - (void)setSelectedTabIndex:(NSInteger)selectedTabIndex {
548 | if(selectedTabIndex >= 0 && selectedTabIndex < _numberOfTabItems && _selectedTabIndex != selectedTabIndex) {
549 | [self changeSelectedItemToNextItem:selectedTabIndex];
550 | _selectedTabIndex = selectedTabIndex;
551 | _lastSelectedTabIndex = selectedTabIndex;
552 | [self layoutIndicatorViewWithStyle];
553 | self.bodyView.contentOffset = CGPointMake(WIDTH(self)*_selectedTabIndex, 0);
554 |
555 | if(_titleStyle == LXPageTabTitleStyleGradient) {
556 | [self resetTabItemScale];
557 | }
558 | }
559 | }
560 |
561 | - (void)setUnSelectedColor:(UIColor *)unSelectedColor {
562 | _unSelectedColor = unSelectedColor;
563 | for(NSInteger i = 0; i < _numberOfTabItems; i++) {
564 | LXPageTabItemLable *tabItem = _tabItems[i];
565 | tabItem.textColor = i==_selectedTabIndex?_selectedColor:_unSelectedColor;
566 | }
567 | NSArray *rgb = [self getRGBWithColor:_unSelectedColor];
568 | _unSelectedColorR = [rgb[0] floatValue];
569 | _unSelectedColorG = [rgb[1] floatValue];
570 | _unSelectedColorB = [rgb[2] floatValue];
571 | }
572 |
573 | - (void)setSelectedColor:(UIColor *)selectedColor {
574 | _selectedColor = selectedColor;
575 | LXPageTabItemLable *tabItem = _tabItems[_selectedTabIndex];
576 | tabItem.textColor = _selectedColor;
577 |
578 | NSArray *rgb = [self getRGBWithColor:_selectedColor];
579 | _selectedColorR = [rgb[0] floatValue];
580 | _selectedColorG = [rgb[1] floatValue];
581 | _selectedColorB = [rgb[2] floatValue];
582 | }
583 |
584 | - (void)setBodyBounces:(BOOL)bodyBounces {
585 | _bodyBounces = bodyBounces;
586 | self.bodyView.bounces = _bodyBounces;
587 | }
588 |
589 | - (void)setTabItemFont:(UIFont *)tabItemFont {
590 | _tabItemFont = tabItemFont;
591 | for(NSInteger i = 0; i < _numberOfTabItems; i++) {
592 | LXPageTabItemLable *tabItem = _tabItems[i];
593 | tabItem.font = _tabItemFont;
594 | }
595 | }
596 |
597 | - (void)setTitleStyle:(LXPageTabTitleStyle)titleStyle {
598 | if(_titleStyle == LXPageTabTitleStyleDefault) {
599 | _titleStyle = titleStyle;
600 | if(_titleStyle == LXPageTabTitleStyleGradient) {
601 | [self resetTabItemScale];
602 | }
603 | }
604 | }
605 |
606 | - (void)setIndicatorStyle:(LXPageTabIndicatorStyle)indicatorStyle {
607 | if(_indicatorStyle == LXPageTabIndicatorStyleDefault) {
608 | _indicatorStyle = indicatorStyle;
609 | [self addIndicatorViewWithStyle];
610 | }
611 | }
612 |
613 | - (void)setMinScale:(CGFloat)minScale {
614 | if(minScale > 0 && minScale <= 1) {
615 | _minScale = minScale;
616 | if(_titleStyle == LXPageTabTitleStyleGradient) {
617 | [self resetTabItemScale];
618 | }
619 | }
620 | }
621 |
622 | @end
623 |
--------------------------------------------------------------------------------
/LXSegmentControl/Lib/XXPageTab/XXPageTabView.m:
--------------------------------------------------------------------------------
1 | //
2 | // XXPageTabView.m
3 | // XXPageTabDemo
4 | //
5 | // Created by HJTXX on 2017/2/27.
6 | // Copyright © 2017年 HJTXX. All rights reserved.
7 | //
8 |
9 | #import "XXPageTabView.h"
10 |
11 | #define kTabDefautHeight 38.0
12 | #define kTabDefautFontSize 15.0
13 | #define kMaxNumberOfPageItems 4
14 | #define kIndicatorHeight 2.0
15 | #define kIndicatorWidth 20
16 | #define kMinScale 0.8
17 |
18 | #define HEIGHT(view) view.bounds.size.height
19 | #define WIDTH(view) view.bounds.size.width
20 | #define ORIGIN_X(view) view.frame.origin.x
21 | #define ORIGIN_Y(view) view.frame.origin.y
22 |
23 | @interface XXPageTabView ()
24 | //bg
25 | @property (nonatomic, strong) UIView *bgView; //由于遇到nav->vc,vc的第一个子试图是UIScrollView会自动产生64像素偏移,所以加上一个虚拟背景(没有尺寸)
26 |
27 | //tab
28 | @property (nonatomic, strong) UIScrollView *tabView;
29 | @property (nonatomic, strong) UIView *indicatorView;
30 |
31 | //body
32 | @property (nonatomic, strong) UIScrollView *bodyView;
33 |
34 | //data
35 | @property (nonatomic, assign) NSInteger lastSelectedTabIndex; //记录上一次的索引
36 | @property (nonatomic, assign) NSInteger numberOfTabItems;
37 | @property (nonatomic, assign) CGFloat tabItemWidth;
38 | @property (nonatomic, strong) NSMutableArray *tabItems;
39 | @property (nonatomic, strong) NSArray *childControllers;
40 | @property (nonatomic, strong) NSArray *childTitles;
41 |
42 | //animation
43 | @property (nonatomic, assign) BOOL isNeedRefreshLayout; //滑动过程中不允许layoutSubviews
44 | @property (nonatomic, assign) BOOL isChangeByClick; //是否是通过点击改变的。因为点击可以长距离点击,部分效果不作处理会出现途中经过的按钮也会依次有效果(仿网易客户端有此效果,个人觉得并不好,头条的客户端更合理)
45 | @property (nonatomic, assign) NSInteger leftItemIndex; //记录滑动时左边的itemIndex
46 | @property (nonatomic, assign) NSInteger rightItemIndex; //记录滑动时右边的itemIndex
47 |
48 | /*XXPageTabTitleStyleScale*/
49 | @property (nonatomic, assign) CGFloat selectedColorR;
50 | @property (nonatomic, assign) CGFloat selectedColorG;
51 | @property (nonatomic, assign) CGFloat selectedColorB;
52 | @property (nonatomic, assign) CGFloat unSelectedColorR;
53 | @property (nonatomic, assign) CGFloat unSelectedColorG;
54 | @property (nonatomic, assign) CGFloat unSelectedColorB;
55 |
56 | @end
57 |
58 | @implementation XXPageTabView
59 |
60 | #pragma mark - Life cycle
61 | - (instancetype)initWithChildControllers:(NSArray *)childControllers
62 | childTitles:(NSArray *)childTitles {
63 | self = [super init];
64 | if(self) {
65 | _childControllers = childControllers;
66 | _childTitles = childTitles;
67 |
68 | [self initBaseSettings];
69 | [self initTabView];
70 | [self initMainView];
71 | }
72 | return self;
73 | }
74 |
75 | - (void)layoutSubviews {
76 | if(_isNeedRefreshLayout) {
77 | //tab layout
78 | if(_tabSize.height <= 0) {
79 | _tabSize.height = kTabDefautHeight;
80 | }
81 | if(_tabSize.width <= 0) {
82 | _tabSize.width = WIDTH(self);
83 | }
84 | _tabItemWidth = _tabSize.width/(_numberOfTabItems<_maxNumberOfPageItems?_numberOfTabItems:_maxNumberOfPageItems);
85 |
86 | self.tabView.frame = CGRectMake(0, 0, _tabSize.width, _tabSize.height);
87 | self.tabView.contentSize = CGSizeMake(_tabItemWidth*_numberOfTabItems, 0);
88 |
89 | for(NSInteger i = 0; i < _tabItems.count; i++) {
90 | XXPageTabItemLable *tabItem = (XXPageTabItemLable *)_tabItems[i];
91 | tabItem.frame = CGRectMake(_tabItemWidth*i, 0, _tabItemWidth, _tabSize.height);
92 | }
93 | [self layoutIndicatorViewWithStyle];
94 |
95 | //body layout
96 | self.bodyView.frame = CGRectMake(0, _tabSize.height, WIDTH(self), HEIGHT(self)-_tabSize.height);
97 | self.bodyView.contentSize = CGSizeMake(WIDTH(self)*_numberOfTabItems, 0);
98 | self.bodyView.contentOffset = CGPointMake(self.frame.size.width*_selectedTabIndex, 0);
99 | [self reviseTabContentOffsetBySelectedIndex:NO];
100 |
101 | for(NSInteger i = 0; i < _numberOfTabItems; i++) {
102 | UIViewController *childController = _childControllers[i];
103 | childController.view.frame = CGRectMake(WIDTH(self)*i, 0, WIDTH(self), HEIGHT(self)-_tabSize.height);
104 | }
105 | }
106 | }
107 |
108 | #pragma mark - Layout
109 | - (void)initBaseSettings {
110 | _selectedTabIndex = 0;
111 | _lastSelectedTabIndex = 0;
112 | _tabSize = CGSizeZero;
113 | _numberOfTabItems = _childControllers.count>_childTitles.count?_childTitles.count:_childControllers.count;
114 | _tabItemFont = [UIFont systemFontOfSize:kTabDefautFontSize];
115 | _indicatorHeight = kIndicatorHeight;
116 | _indicatorWidth = kIndicatorWidth;
117 | _maxNumberOfPageItems = kMaxNumberOfPageItems;
118 | _tabItems = [NSMutableArray array];
119 | _tabBackgroundColor = [UIColor whiteColor];
120 | _bodyBackgroundColor = [UIColor whiteColor];
121 | _unSelectedColor = [UIColor blackColor];
122 | _selectedColor = [UIColor redColor];
123 | _isNeedRefreshLayout = YES;
124 | _isChangeByClick = NO;
125 | _bodyBounces = YES;
126 | _titleStyle = XXPageTabTitleStyleDefault;
127 | _indicatorStyle = XXPageTabIndicatorStyleDefault;
128 | _minScale = kMinScale;
129 | _selectedColorR = 1;
130 | _selectedColorG = 0;
131 | _selectedColorB = 0;
132 | _unSelectedColorR = 0;
133 | _unSelectedColorG = 0;
134 | _unSelectedColorB = 0;
135 | }
136 |
137 | - (void)initTabView {
138 | [self addSubview:self.bgView];
139 | [self addSubview:self.tabView];
140 |
141 | for(NSInteger i = 0; i < _numberOfTabItems; i++) {
142 | XXPageTabItemLable *tabItem = [[XXPageTabItemLable alloc] init];
143 | tabItem.font = _tabItemFont;
144 | tabItem.text = _childTitles[i];
145 | tabItem.textColor = i==_selectedTabIndex?_selectedColor:_unSelectedColor;
146 | tabItem.textAlignment = NSTextAlignmentCenter;
147 | tabItem.userInteractionEnabled = YES;
148 |
149 | UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(changeChildControllerOnClick:)];
150 | [tabItem addGestureRecognizer:tapRecognizer];
151 | [_tabItems addObject:tabItem];
152 | [self.tabView addSubview:tabItem];
153 | }
154 | }
155 |
156 | - (void)initMainView {
157 | [self addSubview:self.bodyView];
158 | for(NSInteger i = 0; i < _numberOfTabItems; i++) {
159 | UIViewController *childController = _childControllers[i];
160 | [self.bodyView addSubview:childController.view];
161 | }
162 | }
163 |
164 | /**
165 | 根据选择项修正tab的展示区域
166 | */
167 | - (void)reviseTabContentOffsetBySelectedIndex:(BOOL)isAnimate {
168 | XXPageTabItemLable *currentTabItem = _tabItems[_selectedTabIndex];
169 | CGFloat selectedItemCenterX = currentTabItem.center.x;
170 |
171 | CGFloat reviseX;
172 | if(selectedItemCenterX + _tabSize.width/2.0 >= self.tabView.contentSize.width) {
173 | reviseX = self.tabView.contentSize.width - _tabSize.width; //不足以到中心,靠右
174 | } else if(selectedItemCenterX - _tabSize.width/2.0 <= 0) {
175 | reviseX = 0; //不足以到中心,靠左
176 | } else {
177 | reviseX = selectedItemCenterX - _tabSize.width/2.0; //修正至中心
178 | }
179 | //如果前后没有偏移量差,setContentOffset实际不起作用;或者没有动画效果
180 | if(fabs(self.tabView.contentOffset.x - reviseX)<1 || !isAnimate) {
181 | [self finishReviseTabContentOffset];
182 | }
183 | [self.tabView setContentOffset:CGPointMake(reviseX, 0) animated:isAnimate];
184 | }
185 |
186 | /**
187 | tabview修正完成后的操作,无论是点击还是滑动body,此方法都是真正意义上的最后一步
188 | */
189 | - (void)finishReviseTabContentOffset {
190 | _tabView.userInteractionEnabled = YES;
191 | _isNeedRefreshLayout = YES;
192 | _isChangeByClick = NO;
193 | if([self.delegate respondsToSelector:@selector(pageTabViewDidEndChange)]) {
194 | if(_lastSelectedTabIndex != _selectedTabIndex) {
195 | [self.delegate pageTabViewDidEndChange];
196 | }
197 | }
198 | _lastSelectedTabIndex = _selectedTabIndex;
199 | }
200 |
201 | /**
202 | 一般常用改变selected Item方法(无动画效果,直接变色)
203 | */
204 | - (void)changeSelectedItemToNextItem:(NSInteger)nextIndex {
205 | XXPageTabItemLable *currentTabItem = _tabItems[_selectedTabIndex];
206 | XXPageTabItemLable *nextTabItem = _tabItems[nextIndex];
207 | currentTabItem.textColor = _unSelectedColor;
208 | nextTabItem.textColor = _selectedColor;
209 | }
210 |
211 | #pragma mark -Title layout
212 | /**
213 | 重新设置item的缩放比例
214 | */
215 | - (void)resetTabItemScale {
216 | for(NSInteger i = 0; i < _numberOfTabItems; i++) {
217 | XXPageTabItemLable *tabItem = _tabItems[i];
218 | if(i != _selectedTabIndex) {
219 | tabItem.transform = CGAffineTransformMakeScale(_minScale, _minScale);
220 | } else {
221 | tabItem.transform = CGAffineTransformMakeScale(1, 1);
222 | }
223 | }
224 | }
225 |
226 | #pragma mark -Indicator layout
227 | /**
228 | 根据不同风格添加相应下标
229 | */
230 | - (void)addIndicatorViewWithStyle {
231 | switch (_indicatorStyle) {
232 | case XXPageTabIndicatorStyleDefault:
233 | case XXPageTabIndicatorStyleFollowText:
234 | case XXPageTabIndicatorStyleStretch:
235 | [self addSubview:self.indicatorView];
236 | break;
237 | default:
238 | break;
239 | }
240 | }
241 |
242 | /**
243 | 根据不同风格对下标layout
244 | */
245 | - (void)layoutIndicatorViewWithStyle {
246 | switch (_indicatorStyle) {
247 | case XXPageTabIndicatorStyleDefault:
248 | case XXPageTabIndicatorStyleFollowText:
249 | case XXPageTabIndicatorStyleStretch:
250 | [self layoutIndicatorView];
251 | break;
252 | default:
253 | break;
254 | }
255 | }
256 |
257 | - (void)layoutIndicatorView {
258 | CGFloat indicatorWidth = [self getIndicatorWidthWithTitle:_childTitles[_selectedTabIndex]];
259 | XXPageTabItemLable *selecedTabItem = _tabItems[_selectedTabIndex];
260 | self.indicatorView.frame = CGRectMake(selecedTabItem.center.x-indicatorWidth/2.0-_tabView.contentOffset.x, _tabSize.height-_indicatorHeight, indicatorWidth, _indicatorHeight);
261 | }
262 |
263 | #pragma mark - Event response
264 | - (void)changeChildControllerOnClick:(UITapGestureRecognizer *)tap {
265 | NSInteger nextIndex = [_tabItems indexOfObject:tap.view];
266 | if(nextIndex != _selectedTabIndex) {
267 | if(_titleStyle == XXPageTabTitleStyleDefault) {
268 | [self changeSelectedItemToNextItem:nextIndex];
269 | }
270 |
271 | _isChangeByClick = YES;
272 | _tabView.userInteractionEnabled = NO; //防止快速切换
273 | _leftItemIndex = nextIndex > _selectedTabIndex?_selectedTabIndex:nextIndex;
274 | _rightItemIndex = nextIndex > _selectedTabIndex?nextIndex:_selectedTabIndex;
275 | _selectedTabIndex = nextIndex;
276 | [self.bodyView setContentOffset:CGPointMake(self.frame.size.width*_selectedTabIndex, 0) animated:YES];
277 | }
278 | }
279 |
280 | #pragma mark - UIScrollViewDelegate
281 | - (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
282 | if(scrollView == self.bodyView) {
283 | _selectedTabIndex = self.bodyView.contentOffset.x/WIDTH(self.bodyView);
284 | [self reviseTabContentOffsetBySelectedIndex:YES];
285 | }
286 | }
287 |
288 | - (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView {
289 | if(scrollView == self.bodyView) {
290 | [self reviseTabContentOffsetBySelectedIndex:YES];
291 | } else {
292 | [self finishReviseTabContentOffset];
293 | }
294 | }
295 |
296 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView {
297 | if(scrollView == self.tabView) {
298 | _isNeedRefreshLayout = NO;
299 | if(self.indicatorView.superview) {
300 | XXPageTabItemLable *selecedTabItem = _tabItems[_selectedTabIndex];
301 | self.indicatorView.frame = CGRectMake(selecedTabItem.center.x-WIDTH(self.indicatorView)/2.0-scrollView.contentOffset.x, ORIGIN_Y(self.indicatorView), WIDTH(self.indicatorView), HEIGHT(self.indicatorView));
302 | }
303 | } else if(scrollView == self.bodyView) {
304 | //未初始化时不处理
305 | if(self.bodyView.contentSize.width <= 0) {
306 | return;
307 | }
308 | //滚动过程中不允许layout
309 | _isNeedRefreshLayout = NO;
310 | //获取当前左右item index(点击方式已获知左右index,无需根据contentoffset计算)
311 | if(!_isChangeByClick) {
312 | if(self.bodyView.contentOffset.x <= 0) { //左边界
313 | _leftItemIndex = 0;
314 | _rightItemIndex = 0;
315 |
316 | } else if(self.bodyView.contentOffset.x >= self.bodyView.contentSize.width-WIDTH(self.bodyView)) { //右边界
317 | _leftItemIndex = _numberOfTabItems-1;
318 | _rightItemIndex = _numberOfTabItems-1;
319 |
320 | } else {
321 | _leftItemIndex = (int)(self.bodyView.contentOffset.x/WIDTH(self.bodyView));
322 | _rightItemIndex = _leftItemIndex + 1;
323 | }
324 | }
325 |
326 | //调整title
327 | switch (_titleStyle) {
328 | case XXPageTabTitleStyleDefault:
329 | [self changeTitleWithDefault];
330 | break;
331 | case XXPageTabTitleStyleGradient:
332 | [self changeTitleWithGradient];
333 | break;
334 | case XXPageTabTitleStyleBlend:
335 | [self changeTitleWithBlend];
336 | break;
337 | default:
338 | break;
339 | }
340 |
341 | //调整indicator
342 | switch (_indicatorStyle) {
343 | case XXPageTabIndicatorStyleDefault:
344 | case XXPageTabIndicatorStyleFollowText:
345 | [self changeIndicatorFrame];
346 | break;
347 | case XXPageTabIndicatorStyleStretch:
348 | {
349 | if(_isChangeByClick) {
350 | [self changeIndicatorFrame];
351 | } else {
352 | [self changeIndicatorFrameByStretch];
353 | }
354 | }
355 | break;
356 | default:
357 | break;
358 | }
359 | }
360 | }
361 |
362 | #pragma mark - Title animation
363 | - (void)changeTitleWithDefault {
364 | CGFloat relativeLocation = self.bodyView.contentOffset.x/WIDTH(self.bodyView)-_leftItemIndex;
365 | if(!_isChangeByClick) {
366 | if(relativeLocation > 0.5) {
367 | [self changeSelectedItemToNextItem:_rightItemIndex];
368 | _selectedTabIndex = _rightItemIndex;
369 | } else {
370 | [self changeSelectedItemToNextItem:_leftItemIndex];
371 | _selectedTabIndex = _leftItemIndex;
372 | }
373 | }
374 | }
375 |
376 | - (void)changeTitleWithGradient {
377 | if(_leftItemIndex != _rightItemIndex) {
378 | CGFloat rightScale = (self.bodyView.contentOffset.x/WIDTH(self.bodyView)-_leftItemIndex)/(_rightItemIndex-_leftItemIndex);
379 | CGFloat leftScale = 1-rightScale;
380 |
381 | //颜色渐变
382 | CGFloat difR = _selectedColorR-_unSelectedColorR;
383 | CGFloat difG = _selectedColorG-_unSelectedColorG;
384 | CGFloat difB = _selectedColorB-_unSelectedColorB;
385 |
386 | UIColor *leftItemColor = [UIColor colorWithRed:_unSelectedColorR+leftScale*difR green:_unSelectedColorG+leftScale*difG blue:_unSelectedColorB+leftScale*difB alpha:1];
387 | UIColor *rightItemColor = [UIColor colorWithRed:_unSelectedColorR+rightScale*difR green:_unSelectedColorG+rightScale*difG blue:_unSelectedColorB+rightScale*difB alpha:1];
388 |
389 | XXPageTabItemLable *leftTabItem = _tabItems[_leftItemIndex];
390 | XXPageTabItemLable *rightTabItem = _tabItems[_rightItemIndex];
391 | leftTabItem.textColor = leftItemColor;
392 | rightTabItem.textColor = rightItemColor;
393 |
394 | //字体渐变
395 | leftTabItem.transform = CGAffineTransformMakeScale(_minScale+(1-_minScale)*leftScale, _minScale+(1-_minScale)*leftScale);
396 | rightTabItem.transform = CGAffineTransformMakeScale(_minScale+(1-_minScale)*rightScale, _minScale+(1-_minScale)*rightScale);
397 | }
398 | }
399 |
400 | - (void)changeTitleWithBlend {
401 | CGFloat leftScale = self.bodyView.contentOffset.x/WIDTH(self.bodyView)-_leftItemIndex;
402 | if(leftScale == 0) {
403 | return; //起点和终点不处理,终点时左右index已更新,会绘画错误(你可以注释看看)
404 | }
405 |
406 | XXPageTabItemLable *leftTabItem = _tabItems[_leftItemIndex];
407 | XXPageTabItemLable *rightTabItem = _tabItems[_rightItemIndex];
408 |
409 | leftTabItem.textColor = _selectedColor;
410 | rightTabItem.textColor = _unSelectedColor;
411 | leftTabItem.fillColor = _unSelectedColor;
412 | rightTabItem.fillColor = _selectedColor;
413 | leftTabItem.process = leftScale;
414 | rightTabItem.process = leftScale;
415 | }
416 |
417 | #pragma mark - Indicator animation
418 | - (void)changeIndicatorFrame {
419 | //计算indicator此时的centerx
420 | CGFloat nowIndicatorCenterX = _tabItemWidth*(0.5+self.bodyView.contentOffset.x/WIDTH(self.bodyView));
421 | //计算此时body的偏移量在一页中的占比
422 | CGFloat relativeLocation = (self.bodyView.contentOffset.x/WIDTH(self.bodyView)-_leftItemIndex)/(_rightItemIndex-_leftItemIndex);
423 | //记录左右对应的indicator宽度
424 | CGFloat leftIndicatorWidth = [self getIndicatorWidthWithTitle:_childTitles[_leftItemIndex]];
425 | CGFloat rightIndicatorWidth = [self getIndicatorWidthWithTitle:_childTitles[_rightItemIndex]];
426 |
427 | //左右边界的时候,占比清0
428 | if(_leftItemIndex == _rightItemIndex) {
429 | relativeLocation = 0;
430 | }
431 | //基于从左到右方向(无需考虑滑动方向),计算当前中心轴所处位置的长度
432 | CGFloat nowIndicatorWidth = leftIndicatorWidth + (rightIndicatorWidth-leftIndicatorWidth)*relativeLocation;
433 |
434 | self.indicatorView.frame = CGRectMake(nowIndicatorCenterX-nowIndicatorWidth/2.0-_tabView.contentOffset.x, ORIGIN_Y(self.indicatorView), nowIndicatorWidth, HEIGHT(self.indicatorView));
435 | }
436 |
437 | - (void)changeIndicatorFrameByStretch {
438 | if(_indicatorWidth <= 0) {
439 | return;
440 | }
441 |
442 | //计算此时body的偏移量在一页中的占比
443 | CGFloat relativeLocation = (self.bodyView.contentOffset.x/WIDTH(self.bodyView)-_leftItemIndex)/(_rightItemIndex-_leftItemIndex);
444 | //左右边界的时候,占比清0
445 | if(_leftItemIndex == _rightItemIndex) {
446 | relativeLocation = 0;
447 | }
448 |
449 | XXPageTabItemLable *leftTabItem = _tabItems[_leftItemIndex];
450 | XXPageTabItemLable *rightTabItem = _tabItems[_rightItemIndex];
451 |
452 | //当前的frame
453 | CGRect nowFrame = CGRectMake(0, ORIGIN_Y(self.indicatorView), 0, HEIGHT(self.indicatorView));
454 |
455 | //计算宽度
456 | if(relativeLocation <= 0.5) {
457 | nowFrame.size.width = _indicatorWidth+_tabItemWidth*(relativeLocation/0.5);
458 | nowFrame.origin.x = (leftTabItem.center.x-self.tabView.contentOffset.x)-_indicatorWidth/2.0;
459 | } else {
460 | nowFrame.size.width = _indicatorWidth+_tabItemWidth*((1-relativeLocation)/0.5);
461 | nowFrame.origin.x = (rightTabItem.center.x-self.tabView.contentOffset.x)+_indicatorWidth/2.0-nowFrame.size.width;
462 | }
463 |
464 | self.indicatorView.frame = nowFrame;
465 | }
466 |
467 | #pragma mark - Tool
468 | /**
469 | 根据对应文本计算下标线宽度
470 | */
471 | - (CGFloat)getIndicatorWidthWithTitle:(NSString *)title {
472 | if(_indicatorStyle == XXPageTabIndicatorStyleDefault || _indicatorStyle == XXPageTabIndicatorStyleStretch) {
473 | return _indicatorWidth;
474 | } else {
475 | if(title.length <= 2) {
476 | return 40;
477 | } else {
478 | return title.length * _tabItemFont.pointSize + 12;
479 | }
480 | }
481 | }
482 |
483 | /**
484 | 获取color的rgb值
485 | */
486 | - (NSArray *)getRGBWithColor:(UIColor *)color {
487 | CGFloat R, G, B;
488 | NSInteger numComponents = CGColorGetNumberOfComponents(color.CGColor);
489 | if(numComponents == 4) {
490 | const CGFloat *components = CGColorGetComponents(color.CGColor);
491 | R = components[0];
492 | G = components[1];
493 | B = components[2];
494 | }
495 | return @[@(R), @(G), @(B)];
496 | }
497 |
498 | #pragma mark - Getter/setter
499 | - (UIView *)bgView {
500 | if(!_bgView) {
501 | _bgView = [UIView new];
502 | }
503 | return _bgView;
504 | }
505 |
506 | - (UIScrollView *)tabView {
507 | if(!_tabView) {
508 | _tabView = [UIScrollView new];
509 | _tabView.showsVerticalScrollIndicator = NO;
510 | _tabView.showsHorizontalScrollIndicator = NO;
511 | _tabView.backgroundColor = _tabBackgroundColor;
512 | _tabView.delegate = self;
513 | _tabView.clipsToBounds = YES;
514 | }
515 | return _tabView;
516 | }
517 |
518 | - (UIScrollView *)bodyView {
519 | if(!_bodyView) {
520 | _bodyView = [UIScrollView new];
521 | _bodyView.pagingEnabled = YES;
522 | _bodyView.showsVerticalScrollIndicator = NO;
523 | _bodyView.showsHorizontalScrollIndicator = NO;
524 | _bodyView.delegate = self;
525 | _bodyView.bounces = _bodyBounces;
526 | _bodyView.backgroundColor = _bodyBackgroundColor;
527 | }
528 | return _bodyView;
529 | }
530 |
531 | - (UIView *)indicatorView {
532 | if(!_indicatorView) {
533 | _indicatorView = [UIView new];
534 | _indicatorView.backgroundColor = _selectedColor;
535 | }
536 | return _indicatorView;
537 | }
538 |
539 | - (void)setTabBackgroundColor:(UIColor *)tabBackgroundColor {
540 | _tabBackgroundColor = tabBackgroundColor;
541 | self.tabView.backgroundColor = _tabBackgroundColor;
542 | }
543 |
544 | - (void)setBodyBackgroundColor:(UIColor *)bodyBackgroundColor {
545 | _bodyBackgroundColor = bodyBackgroundColor;
546 | self.bodyView.backgroundColor = _bodyBackgroundColor;
547 | }
548 |
549 | - (void)setSelectedTabIndex:(NSInteger)selectedTabIndex {
550 | if(selectedTabIndex >= 0 && selectedTabIndex < _numberOfTabItems && _selectedTabIndex != selectedTabIndex) {
551 | [self changeSelectedItemToNextItem:selectedTabIndex];
552 | _selectedTabIndex = selectedTabIndex;
553 | _lastSelectedTabIndex = selectedTabIndex;
554 | [self layoutIndicatorViewWithStyle];
555 | self.bodyView.contentOffset = CGPointMake(WIDTH(self)*_selectedTabIndex, 0);
556 |
557 | if(_titleStyle == XXPageTabTitleStyleGradient) {
558 | [self resetTabItemScale];
559 | }
560 | }
561 | }
562 |
563 | - (void)setUnSelectedColor:(UIColor *)unSelectedColor {
564 | _unSelectedColor = unSelectedColor;
565 | for(NSInteger i = 0; i < _numberOfTabItems; i++) {
566 | XXPageTabItemLable *tabItem = _tabItems[i];
567 | tabItem.textColor = i==_selectedTabIndex?_selectedColor:_unSelectedColor;
568 | }
569 | NSArray *rgb = [self getRGBWithColor:_unSelectedColor];
570 | _unSelectedColorR = [rgb[0] floatValue];
571 | _unSelectedColorG = [rgb[1] floatValue];
572 | _unSelectedColorB = [rgb[2] floatValue];
573 | }
574 |
575 | - (void)setSelectedColor:(UIColor *)selectedColor {
576 | _selectedColor = selectedColor;
577 | XXPageTabItemLable *tabItem = _tabItems[_selectedTabIndex];
578 | tabItem.textColor = _selectedColor;
579 | self.indicatorView.backgroundColor = _selectedColor;
580 |
581 | NSArray *rgb = [self getRGBWithColor:_selectedColor];
582 | _selectedColorR = [rgb[0] floatValue];
583 | _selectedColorG = [rgb[1] floatValue];
584 | _selectedColorB = [rgb[2] floatValue];
585 | }
586 |
587 | - (void)setBodyBounces:(BOOL)bodyBounces {
588 | _bodyBounces = bodyBounces;
589 | self.bodyView.bounces = _bodyBounces;
590 | }
591 |
592 | - (void)setTabItemFont:(UIFont *)tabItemFont {
593 | _tabItemFont = tabItemFont;
594 | for(NSInteger i = 0; i < _numberOfTabItems; i++) {
595 | XXPageTabItemLable *tabItem = _tabItems[i];
596 | tabItem.font = _tabItemFont;
597 | }
598 | }
599 |
600 | - (void)setTitleStyle:(XXPageTabTitleStyle)titleStyle {
601 | if(_titleStyle == XXPageTabTitleStyleDefault) {
602 | _titleStyle = titleStyle;
603 | if(_titleStyle == XXPageTabTitleStyleGradient) {
604 | [self resetTabItemScale];
605 | }
606 | }
607 | }
608 |
609 | - (void)setIndicatorStyle:(XXPageTabIndicatorStyle)indicatorStyle {
610 | if(_indicatorStyle == XXPageTabIndicatorStyleDefault) {
611 | _indicatorStyle = indicatorStyle;
612 | [self addIndicatorViewWithStyle];
613 | }
614 | }
615 |
616 | - (void)setMinScale:(CGFloat)minScale {
617 | if(minScale > 0 && minScale <= 1) {
618 | _minScale = minScale;
619 | if(_titleStyle == XXPageTabTitleStyleGradient) {
620 | [self resetTabItemScale];
621 | }
622 | }
623 | }
624 |
625 | @end
626 |
--------------------------------------------------------------------------------
/LXSegmentControl.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 2436BCF121B4CDC500E8D063 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 2436BCF021B4CDC500E8D063 /* AppDelegate.m */; };
11 | 2436BCF421B4CDC500E8D063 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2436BCF321B4CDC500E8D063 /* ViewController.m */; };
12 | 2436BCF721B4CDC500E8D063 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2436BCF521B4CDC500E8D063 /* Main.storyboard */; };
13 | 2436BCF921B4CDC700E8D063 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 2436BCF821B4CDC700E8D063 /* Assets.xcassets */; };
14 | 2436BCFC21B4CDC700E8D063 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2436BCFA21B4CDC700E8D063 /* LaunchScreen.storyboard */; };
15 | 2436BCFF21B4CDC700E8D063 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 2436BCFE21B4CDC700E8D063 /* main.m */; };
16 | 2436BD0921B4CDC700E8D063 /* LXSegmentControlTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2436BD0821B4CDC700E8D063 /* LXSegmentControlTests.m */; };
17 | 2436BD1421B4CDC700E8D063 /* LXSegmentControlUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = 2436BD1321B4CDC700E8D063 /* LXSegmentControlUITests.m */; };
18 | 2436BD3B21B4CFD000E8D063 /* UIColor+LX.m in Sources */ = {isa = PBXBuildFile; fileRef = 2436BD2421B4CFD000E8D063 /* UIColor+LX.m */; };
19 | 2436BD3C21B4CFD000E8D063 /* UIImage+LX.m in Sources */ = {isa = PBXBuildFile; fileRef = 2436BD2621B4CFD000E8D063 /* UIImage+LX.m */; };
20 | 2436BD5B21B4D22F00E8D063 /* LXSegmentType_0ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2436BD5A21B4D22F00E8D063 /* LXSegmentType_0ViewController.m */; };
21 | 2436BD5E21B4D23A00E8D063 /* LXSegmentType_1ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2436BD5D21B4D23A00E8D063 /* LXSegmentType_1ViewController.m */; };
22 | 2436BD6121B4D57800E8D063 /* LXSegmentTitleViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 2436BD6021B4D57800E8D063 /* LXSegmentTitleViewController.m */; };
23 | 2436BD6721B4FCEB00E8D063 /* XXPageTabItemLable.m in Sources */ = {isa = PBXBuildFile; fileRef = 2436BD6321B4FCEB00E8D063 /* XXPageTabItemLable.m */; };
24 | 2436BD6821B4FCEB00E8D063 /* XXPageTabView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2436BD6421B4FCEB00E8D063 /* XXPageTabView.m */; };
25 | 2436BD6F21B4FCF200E8D063 /* 三角形@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 2436BD6B21B4FCF200E8D063 /* 三角形@2x.png */; };
26 | 2436BD7021B4FCF200E8D063 /* LXPageTabItemLable.m in Sources */ = {isa = PBXBuildFile; fileRef = 2436BD6C21B4FCF200E8D063 /* LXPageTabItemLable.m */; };
27 | 2436BD7121B4FCF200E8D063 /* LXPageTabView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2436BD6D21B4FCF200E8D063 /* LXPageTabView.m */; };
28 | /* End PBXBuildFile section */
29 |
30 | /* Begin PBXContainerItemProxy section */
31 | 2436BD0521B4CDC700E8D063 /* PBXContainerItemProxy */ = {
32 | isa = PBXContainerItemProxy;
33 | containerPortal = 2436BCE421B4CDC500E8D063 /* Project object */;
34 | proxyType = 1;
35 | remoteGlobalIDString = 2436BCEB21B4CDC500E8D063;
36 | remoteInfo = LXSegmentControl;
37 | };
38 | 2436BD1021B4CDC700E8D063 /* PBXContainerItemProxy */ = {
39 | isa = PBXContainerItemProxy;
40 | containerPortal = 2436BCE421B4CDC500E8D063 /* Project object */;
41 | proxyType = 1;
42 | remoteGlobalIDString = 2436BCEB21B4CDC500E8D063;
43 | remoteInfo = LXSegmentControl;
44 | };
45 | /* End PBXContainerItemProxy section */
46 |
47 | /* Begin PBXFileReference section */
48 | 2436BCEC21B4CDC500E8D063 /* LXSegmentControl.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LXSegmentControl.app; sourceTree = BUILT_PRODUCTS_DIR; };
49 | 2436BCEF21B4CDC500E8D063 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
50 | 2436BCF021B4CDC500E8D063 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
51 | 2436BCF221B4CDC500E8D063 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
52 | 2436BCF321B4CDC500E8D063 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
53 | 2436BCF621B4CDC500E8D063 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
54 | 2436BCF821B4CDC700E8D063 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
55 | 2436BCFB21B4CDC700E8D063 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
56 | 2436BCFD21B4CDC700E8D063 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
57 | 2436BCFE21B4CDC700E8D063 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
58 | 2436BD0421B4CDC700E8D063 /* LXSegmentControlTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LXSegmentControlTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
59 | 2436BD0821B4CDC700E8D063 /* LXSegmentControlTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LXSegmentControlTests.m; sourceTree = ""; };
60 | 2436BD0A21B4CDC700E8D063 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
61 | 2436BD0F21B4CDC700E8D063 /* LXSegmentControlUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = LXSegmentControlUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
62 | 2436BD1321B4CDC700E8D063 /* LXSegmentControlUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LXSegmentControlUITests.m; sourceTree = ""; };
63 | 2436BD1521B4CDC700E8D063 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
64 | 2436BD2321B4CFD000E8D063 /* UIImage+LX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+LX.h"; sourceTree = ""; };
65 | 2436BD2421B4CFD000E8D063 /* UIColor+LX.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIColor+LX.m"; sourceTree = ""; };
66 | 2436BD2621B4CFD000E8D063 /* UIImage+LX.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+LX.m"; sourceTree = ""; };
67 | 2436BD2721B4CFD000E8D063 /* UIColor+LX.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor+LX.h"; sourceTree = ""; };
68 | 2436BD4521B4CFD500E8D063 /* LX_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LX_Prefix.pch; sourceTree = ""; };
69 | 2436BD5921B4D22F00E8D063 /* LXSegmentType_0ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LXSegmentType_0ViewController.h; sourceTree = ""; };
70 | 2436BD5A21B4D22F00E8D063 /* LXSegmentType_0ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LXSegmentType_0ViewController.m; sourceTree = ""; };
71 | 2436BD5C21B4D23A00E8D063 /* LXSegmentType_1ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LXSegmentType_1ViewController.h; sourceTree = ""; };
72 | 2436BD5D21B4D23A00E8D063 /* LXSegmentType_1ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LXSegmentType_1ViewController.m; sourceTree = ""; };
73 | 2436BD5F21B4D57800E8D063 /* LXSegmentTitleViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LXSegmentTitleViewController.h; sourceTree = ""; };
74 | 2436BD6021B4D57800E8D063 /* LXSegmentTitleViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LXSegmentTitleViewController.m; sourceTree = ""; };
75 | 2436BD6321B4FCEB00E8D063 /* XXPageTabItemLable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XXPageTabItemLable.m; sourceTree = ""; };
76 | 2436BD6421B4FCEB00E8D063 /* XXPageTabView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XXPageTabView.m; sourceTree = ""; };
77 | 2436BD6521B4FCEB00E8D063 /* XXPageTabView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XXPageTabView.h; sourceTree = ""; };
78 | 2436BD6621B4FCEB00E8D063 /* XXPageTabItemLable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XXPageTabItemLable.h; sourceTree = ""; };
79 | 2436BD6A21B4FCF200E8D063 /* LXPageTabView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXPageTabView.h; sourceTree = ""; };
80 | 2436BD6B21B4FCF200E8D063 /* 三角形@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "三角形@2x.png"; sourceTree = ""; };
81 | 2436BD6C21B4FCF200E8D063 /* LXPageTabItemLable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXPageTabItemLable.m; sourceTree = ""; };
82 | 2436BD6D21B4FCF200E8D063 /* LXPageTabView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LXPageTabView.m; sourceTree = ""; };
83 | 2436BD6E21B4FCF200E8D063 /* LXPageTabItemLable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LXPageTabItemLable.h; sourceTree = ""; };
84 | /* End PBXFileReference section */
85 |
86 | /* Begin PBXFrameworksBuildPhase section */
87 | 2436BCE921B4CDC500E8D063 /* Frameworks */ = {
88 | isa = PBXFrameworksBuildPhase;
89 | buildActionMask = 2147483647;
90 | files = (
91 | );
92 | runOnlyForDeploymentPostprocessing = 0;
93 | };
94 | 2436BD0121B4CDC700E8D063 /* Frameworks */ = {
95 | isa = PBXFrameworksBuildPhase;
96 | buildActionMask = 2147483647;
97 | files = (
98 | );
99 | runOnlyForDeploymentPostprocessing = 0;
100 | };
101 | 2436BD0C21B4CDC700E8D063 /* Frameworks */ = {
102 | isa = PBXFrameworksBuildPhase;
103 | buildActionMask = 2147483647;
104 | files = (
105 | );
106 | runOnlyForDeploymentPostprocessing = 0;
107 | };
108 | /* End PBXFrameworksBuildPhase section */
109 |
110 | /* Begin PBXGroup section */
111 | 2436BCE321B4CDC500E8D063 = {
112 | isa = PBXGroup;
113 | children = (
114 | 2436BCEE21B4CDC500E8D063 /* LXSegmentControl */,
115 | 2436BD0721B4CDC700E8D063 /* LXSegmentControlTests */,
116 | 2436BD1221B4CDC700E8D063 /* LXSegmentControlUITests */,
117 | 2436BCED21B4CDC500E8D063 /* Products */,
118 | );
119 | sourceTree = "";
120 | };
121 | 2436BCED21B4CDC500E8D063 /* Products */ = {
122 | isa = PBXGroup;
123 | children = (
124 | 2436BCEC21B4CDC500E8D063 /* LXSegmentControl.app */,
125 | 2436BD0421B4CDC700E8D063 /* LXSegmentControlTests.xctest */,
126 | 2436BD0F21B4CDC700E8D063 /* LXSegmentControlUITests.xctest */,
127 | );
128 | name = Products;
129 | sourceTree = "";
130 | };
131 | 2436BCEE21B4CDC500E8D063 /* LXSegmentControl */ = {
132 | isa = PBXGroup;
133 | children = (
134 | 2436BD4521B4CFD500E8D063 /* LX_Prefix.pch */,
135 | 2436BD2821B4CFD000E8D063 /* Lib */,
136 | 2436BD2121B4CFD000E8D063 /* Category */,
137 | 2436BCEF21B4CDC500E8D063 /* AppDelegate.h */,
138 | 2436BCF021B4CDC500E8D063 /* AppDelegate.m */,
139 | 2436BCF221B4CDC500E8D063 /* ViewController.h */,
140 | 2436BCF321B4CDC500E8D063 /* ViewController.m */,
141 | 2436BD5921B4D22F00E8D063 /* LXSegmentType_0ViewController.h */,
142 | 2436BD5A21B4D22F00E8D063 /* LXSegmentType_0ViewController.m */,
143 | 2436BD5C21B4D23A00E8D063 /* LXSegmentType_1ViewController.h */,
144 | 2436BD5D21B4D23A00E8D063 /* LXSegmentType_1ViewController.m */,
145 | 2436BD5F21B4D57800E8D063 /* LXSegmentTitleViewController.h */,
146 | 2436BD6021B4D57800E8D063 /* LXSegmentTitleViewController.m */,
147 | 2436BCF521B4CDC500E8D063 /* Main.storyboard */,
148 | 2436BCF821B4CDC700E8D063 /* Assets.xcassets */,
149 | 2436BCFA21B4CDC700E8D063 /* LaunchScreen.storyboard */,
150 | 2436BCFD21B4CDC700E8D063 /* Info.plist */,
151 | 2436BCFE21B4CDC700E8D063 /* main.m */,
152 | );
153 | path = LXSegmentControl;
154 | sourceTree = "";
155 | };
156 | 2436BD0721B4CDC700E8D063 /* LXSegmentControlTests */ = {
157 | isa = PBXGroup;
158 | children = (
159 | 2436BD0821B4CDC700E8D063 /* LXSegmentControlTests.m */,
160 | 2436BD0A21B4CDC700E8D063 /* Info.plist */,
161 | );
162 | path = LXSegmentControlTests;
163 | sourceTree = "";
164 | };
165 | 2436BD1221B4CDC700E8D063 /* LXSegmentControlUITests */ = {
166 | isa = PBXGroup;
167 | children = (
168 | 2436BD1321B4CDC700E8D063 /* LXSegmentControlUITests.m */,
169 | 2436BD1521B4CDC700E8D063 /* Info.plist */,
170 | );
171 | path = LXSegmentControlUITests;
172 | sourceTree = "";
173 | };
174 | 2436BD2121B4CFD000E8D063 /* Category */ = {
175 | isa = PBXGroup;
176 | children = (
177 | 2436BD2721B4CFD000E8D063 /* UIColor+LX.h */,
178 | 2436BD2421B4CFD000E8D063 /* UIColor+LX.m */,
179 | 2436BD2321B4CFD000E8D063 /* UIImage+LX.h */,
180 | 2436BD2621B4CFD000E8D063 /* UIImage+LX.m */,
181 | );
182 | path = Category;
183 | sourceTree = "";
184 | };
185 | 2436BD2821B4CFD000E8D063 /* Lib */ = {
186 | isa = PBXGroup;
187 | children = (
188 | 2436BD6221B4FCEB00E8D063 /* XXPageTab */,
189 | 2436BD6921B4FCF200E8D063 /* LXPageTab */,
190 | );
191 | path = Lib;
192 | sourceTree = "";
193 | };
194 | 2436BD6221B4FCEB00E8D063 /* XXPageTab */ = {
195 | isa = PBXGroup;
196 | children = (
197 | 2436BD6521B4FCEB00E8D063 /* XXPageTabView.h */,
198 | 2436BD6421B4FCEB00E8D063 /* XXPageTabView.m */,
199 | 2436BD6621B4FCEB00E8D063 /* XXPageTabItemLable.h */,
200 | 2436BD6321B4FCEB00E8D063 /* XXPageTabItemLable.m */,
201 | );
202 | path = XXPageTab;
203 | sourceTree = "";
204 | };
205 | 2436BD6921B4FCF200E8D063 /* LXPageTab */ = {
206 | isa = PBXGroup;
207 | children = (
208 | 2436BD6A21B4FCF200E8D063 /* LXPageTabView.h */,
209 | 2436BD6D21B4FCF200E8D063 /* LXPageTabView.m */,
210 | 2436BD6E21B4FCF200E8D063 /* LXPageTabItemLable.h */,
211 | 2436BD6C21B4FCF200E8D063 /* LXPageTabItemLable.m */,
212 | 2436BD6B21B4FCF200E8D063 /* 三角形@2x.png */,
213 | );
214 | path = LXPageTab;
215 | sourceTree = "";
216 | };
217 | /* End PBXGroup section */
218 |
219 | /* Begin PBXNativeTarget section */
220 | 2436BCEB21B4CDC500E8D063 /* LXSegmentControl */ = {
221 | isa = PBXNativeTarget;
222 | buildConfigurationList = 2436BD1821B4CDC700E8D063 /* Build configuration list for PBXNativeTarget "LXSegmentControl" */;
223 | buildPhases = (
224 | 2436BCE821B4CDC500E8D063 /* Sources */,
225 | 2436BCE921B4CDC500E8D063 /* Frameworks */,
226 | 2436BCEA21B4CDC500E8D063 /* Resources */,
227 | );
228 | buildRules = (
229 | );
230 | dependencies = (
231 | );
232 | name = LXSegmentControl;
233 | productName = LXSegmentControl;
234 | productReference = 2436BCEC21B4CDC500E8D063 /* LXSegmentControl.app */;
235 | productType = "com.apple.product-type.application";
236 | };
237 | 2436BD0321B4CDC700E8D063 /* LXSegmentControlTests */ = {
238 | isa = PBXNativeTarget;
239 | buildConfigurationList = 2436BD1B21B4CDC700E8D063 /* Build configuration list for PBXNativeTarget "LXSegmentControlTests" */;
240 | buildPhases = (
241 | 2436BD0021B4CDC700E8D063 /* Sources */,
242 | 2436BD0121B4CDC700E8D063 /* Frameworks */,
243 | 2436BD0221B4CDC700E8D063 /* Resources */,
244 | );
245 | buildRules = (
246 | );
247 | dependencies = (
248 | 2436BD0621B4CDC700E8D063 /* PBXTargetDependency */,
249 | );
250 | name = LXSegmentControlTests;
251 | productName = LXSegmentControlTests;
252 | productReference = 2436BD0421B4CDC700E8D063 /* LXSegmentControlTests.xctest */;
253 | productType = "com.apple.product-type.bundle.unit-test";
254 | };
255 | 2436BD0E21B4CDC700E8D063 /* LXSegmentControlUITests */ = {
256 | isa = PBXNativeTarget;
257 | buildConfigurationList = 2436BD1E21B4CDC700E8D063 /* Build configuration list for PBXNativeTarget "LXSegmentControlUITests" */;
258 | buildPhases = (
259 | 2436BD0B21B4CDC700E8D063 /* Sources */,
260 | 2436BD0C21B4CDC700E8D063 /* Frameworks */,
261 | 2436BD0D21B4CDC700E8D063 /* Resources */,
262 | );
263 | buildRules = (
264 | );
265 | dependencies = (
266 | 2436BD1121B4CDC700E8D063 /* PBXTargetDependency */,
267 | );
268 | name = LXSegmentControlUITests;
269 | productName = LXSegmentControlUITests;
270 | productReference = 2436BD0F21B4CDC700E8D063 /* LXSegmentControlUITests.xctest */;
271 | productType = "com.apple.product-type.bundle.ui-testing";
272 | };
273 | /* End PBXNativeTarget section */
274 |
275 | /* Begin PBXProject section */
276 | 2436BCE421B4CDC500E8D063 /* Project object */ = {
277 | isa = PBXProject;
278 | attributes = {
279 | LastUpgradeCheck = 1000;
280 | ORGANIZATIONNAME = "https://github.com/nick8brown";
281 | TargetAttributes = {
282 | 2436BCEB21B4CDC500E8D063 = {
283 | CreatedOnToolsVersion = 10.0;
284 | };
285 | 2436BD0321B4CDC700E8D063 = {
286 | CreatedOnToolsVersion = 10.0;
287 | TestTargetID = 2436BCEB21B4CDC500E8D063;
288 | };
289 | 2436BD0E21B4CDC700E8D063 = {
290 | CreatedOnToolsVersion = 10.0;
291 | TestTargetID = 2436BCEB21B4CDC500E8D063;
292 | };
293 | };
294 | };
295 | buildConfigurationList = 2436BCE721B4CDC500E8D063 /* Build configuration list for PBXProject "LXSegmentControl" */;
296 | compatibilityVersion = "Xcode 9.3";
297 | developmentRegion = en;
298 | hasScannedForEncodings = 0;
299 | knownRegions = (
300 | en,
301 | Base,
302 | );
303 | mainGroup = 2436BCE321B4CDC500E8D063;
304 | productRefGroup = 2436BCED21B4CDC500E8D063 /* Products */;
305 | projectDirPath = "";
306 | projectRoot = "";
307 | targets = (
308 | 2436BCEB21B4CDC500E8D063 /* LXSegmentControl */,
309 | 2436BD0321B4CDC700E8D063 /* LXSegmentControlTests */,
310 | 2436BD0E21B4CDC700E8D063 /* LXSegmentControlUITests */,
311 | );
312 | };
313 | /* End PBXProject section */
314 |
315 | /* Begin PBXResourcesBuildPhase section */
316 | 2436BCEA21B4CDC500E8D063 /* Resources */ = {
317 | isa = PBXResourcesBuildPhase;
318 | buildActionMask = 2147483647;
319 | files = (
320 | 2436BD6F21B4FCF200E8D063 /* 三角形@2x.png in Resources */,
321 | 2436BCFC21B4CDC700E8D063 /* LaunchScreen.storyboard in Resources */,
322 | 2436BCF921B4CDC700E8D063 /* Assets.xcassets in Resources */,
323 | 2436BCF721B4CDC500E8D063 /* Main.storyboard in Resources */,
324 | );
325 | runOnlyForDeploymentPostprocessing = 0;
326 | };
327 | 2436BD0221B4CDC700E8D063 /* Resources */ = {
328 | isa = PBXResourcesBuildPhase;
329 | buildActionMask = 2147483647;
330 | files = (
331 | );
332 | runOnlyForDeploymentPostprocessing = 0;
333 | };
334 | 2436BD0D21B4CDC700E8D063 /* Resources */ = {
335 | isa = PBXResourcesBuildPhase;
336 | buildActionMask = 2147483647;
337 | files = (
338 | );
339 | runOnlyForDeploymentPostprocessing = 0;
340 | };
341 | /* End PBXResourcesBuildPhase section */
342 |
343 | /* Begin PBXSourcesBuildPhase section */
344 | 2436BCE821B4CDC500E8D063 /* Sources */ = {
345 | isa = PBXSourcesBuildPhase;
346 | buildActionMask = 2147483647;
347 | files = (
348 | 2436BD6121B4D57800E8D063 /* LXSegmentTitleViewController.m in Sources */,
349 | 2436BCF421B4CDC500E8D063 /* ViewController.m in Sources */,
350 | 2436BD7021B4FCF200E8D063 /* LXPageTabItemLable.m in Sources */,
351 | 2436BD3C21B4CFD000E8D063 /* UIImage+LX.m in Sources */,
352 | 2436BCFF21B4CDC700E8D063 /* main.m in Sources */,
353 | 2436BD3B21B4CFD000E8D063 /* UIColor+LX.m in Sources */,
354 | 2436BD5B21B4D22F00E8D063 /* LXSegmentType_0ViewController.m in Sources */,
355 | 2436BD6721B4FCEB00E8D063 /* XXPageTabItemLable.m in Sources */,
356 | 2436BD6821B4FCEB00E8D063 /* XXPageTabView.m in Sources */,
357 | 2436BD7121B4FCF200E8D063 /* LXPageTabView.m in Sources */,
358 | 2436BCF121B4CDC500E8D063 /* AppDelegate.m in Sources */,
359 | 2436BD5E21B4D23A00E8D063 /* LXSegmentType_1ViewController.m in Sources */,
360 | );
361 | runOnlyForDeploymentPostprocessing = 0;
362 | };
363 | 2436BD0021B4CDC700E8D063 /* Sources */ = {
364 | isa = PBXSourcesBuildPhase;
365 | buildActionMask = 2147483647;
366 | files = (
367 | 2436BD0921B4CDC700E8D063 /* LXSegmentControlTests.m in Sources */,
368 | );
369 | runOnlyForDeploymentPostprocessing = 0;
370 | };
371 | 2436BD0B21B4CDC700E8D063 /* Sources */ = {
372 | isa = PBXSourcesBuildPhase;
373 | buildActionMask = 2147483647;
374 | files = (
375 | 2436BD1421B4CDC700E8D063 /* LXSegmentControlUITests.m in Sources */,
376 | );
377 | runOnlyForDeploymentPostprocessing = 0;
378 | };
379 | /* End PBXSourcesBuildPhase section */
380 |
381 | /* Begin PBXTargetDependency section */
382 | 2436BD0621B4CDC700E8D063 /* PBXTargetDependency */ = {
383 | isa = PBXTargetDependency;
384 | target = 2436BCEB21B4CDC500E8D063 /* LXSegmentControl */;
385 | targetProxy = 2436BD0521B4CDC700E8D063 /* PBXContainerItemProxy */;
386 | };
387 | 2436BD1121B4CDC700E8D063 /* PBXTargetDependency */ = {
388 | isa = PBXTargetDependency;
389 | target = 2436BCEB21B4CDC500E8D063 /* LXSegmentControl */;
390 | targetProxy = 2436BD1021B4CDC700E8D063 /* PBXContainerItemProxy */;
391 | };
392 | /* End PBXTargetDependency section */
393 |
394 | /* Begin PBXVariantGroup section */
395 | 2436BCF521B4CDC500E8D063 /* Main.storyboard */ = {
396 | isa = PBXVariantGroup;
397 | children = (
398 | 2436BCF621B4CDC500E8D063 /* Base */,
399 | );
400 | name = Main.storyboard;
401 | sourceTree = "";
402 | };
403 | 2436BCFA21B4CDC700E8D063 /* LaunchScreen.storyboard */ = {
404 | isa = PBXVariantGroup;
405 | children = (
406 | 2436BCFB21B4CDC700E8D063 /* Base */,
407 | );
408 | name = LaunchScreen.storyboard;
409 | sourceTree = "";
410 | };
411 | /* End PBXVariantGroup section */
412 |
413 | /* Begin XCBuildConfiguration section */
414 | 2436BD1621B4CDC700E8D063 /* Debug */ = {
415 | isa = XCBuildConfiguration;
416 | buildSettings = {
417 | ALWAYS_SEARCH_USER_PATHS = NO;
418 | CLANG_ANALYZER_NONNULL = YES;
419 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
420 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
421 | CLANG_CXX_LIBRARY = "libc++";
422 | CLANG_ENABLE_MODULES = YES;
423 | CLANG_ENABLE_OBJC_ARC = YES;
424 | CLANG_ENABLE_OBJC_WEAK = YES;
425 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
426 | CLANG_WARN_BOOL_CONVERSION = YES;
427 | CLANG_WARN_COMMA = YES;
428 | CLANG_WARN_CONSTANT_CONVERSION = YES;
429 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
430 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
431 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
432 | CLANG_WARN_EMPTY_BODY = YES;
433 | CLANG_WARN_ENUM_CONVERSION = YES;
434 | CLANG_WARN_INFINITE_RECURSION = YES;
435 | CLANG_WARN_INT_CONVERSION = YES;
436 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
437 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
438 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
439 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
440 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
441 | CLANG_WARN_STRICT_PROTOTYPES = YES;
442 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
443 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
444 | CLANG_WARN_UNREACHABLE_CODE = YES;
445 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
446 | CODE_SIGN_IDENTITY = "iPhone Developer";
447 | COPY_PHASE_STRIP = NO;
448 | DEBUG_INFORMATION_FORMAT = dwarf;
449 | ENABLE_STRICT_OBJC_MSGSEND = YES;
450 | ENABLE_TESTABILITY = YES;
451 | GCC_C_LANGUAGE_STANDARD = gnu11;
452 | GCC_DYNAMIC_NO_PIC = NO;
453 | GCC_NO_COMMON_BLOCKS = YES;
454 | GCC_OPTIMIZATION_LEVEL = 0;
455 | GCC_PREPROCESSOR_DEFINITIONS = (
456 | "DEBUG=1",
457 | "$(inherited)",
458 | );
459 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
460 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
461 | GCC_WARN_UNDECLARED_SELECTOR = YES;
462 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
463 | GCC_WARN_UNUSED_FUNCTION = YES;
464 | GCC_WARN_UNUSED_VARIABLE = YES;
465 | IPHONEOS_DEPLOYMENT_TARGET = 12.0;
466 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
467 | MTL_FAST_MATH = YES;
468 | ONLY_ACTIVE_ARCH = YES;
469 | SDKROOT = iphoneos;
470 | };
471 | name = Debug;
472 | };
473 | 2436BD1721B4CDC700E8D063 /* Release */ = {
474 | isa = XCBuildConfiguration;
475 | buildSettings = {
476 | ALWAYS_SEARCH_USER_PATHS = NO;
477 | CLANG_ANALYZER_NONNULL = YES;
478 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
479 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
480 | CLANG_CXX_LIBRARY = "libc++";
481 | CLANG_ENABLE_MODULES = YES;
482 | CLANG_ENABLE_OBJC_ARC = YES;
483 | CLANG_ENABLE_OBJC_WEAK = YES;
484 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
485 | CLANG_WARN_BOOL_CONVERSION = YES;
486 | CLANG_WARN_COMMA = YES;
487 | CLANG_WARN_CONSTANT_CONVERSION = YES;
488 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
489 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
490 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
491 | CLANG_WARN_EMPTY_BODY = YES;
492 | CLANG_WARN_ENUM_CONVERSION = YES;
493 | CLANG_WARN_INFINITE_RECURSION = YES;
494 | CLANG_WARN_INT_CONVERSION = YES;
495 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
496 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
497 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
498 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
499 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
500 | CLANG_WARN_STRICT_PROTOTYPES = YES;
501 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
502 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
503 | CLANG_WARN_UNREACHABLE_CODE = YES;
504 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
505 | CODE_SIGN_IDENTITY = "iPhone Developer";
506 | COPY_PHASE_STRIP = NO;
507 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
508 | ENABLE_NS_ASSERTIONS = NO;
509 | ENABLE_STRICT_OBJC_MSGSEND = YES;
510 | GCC_C_LANGUAGE_STANDARD = gnu11;
511 | GCC_NO_COMMON_BLOCKS = YES;
512 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
513 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
514 | GCC_WARN_UNDECLARED_SELECTOR = YES;
515 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
516 | GCC_WARN_UNUSED_FUNCTION = YES;
517 | GCC_WARN_UNUSED_VARIABLE = YES;
518 | IPHONEOS_DEPLOYMENT_TARGET = 12.0;
519 | MTL_ENABLE_DEBUG_INFO = NO;
520 | MTL_FAST_MATH = YES;
521 | SDKROOT = iphoneos;
522 | VALIDATE_PRODUCT = YES;
523 | };
524 | name = Release;
525 | };
526 | 2436BD1921B4CDC700E8D063 /* Debug */ = {
527 | isa = XCBuildConfiguration;
528 | buildSettings = {
529 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
530 | CODE_SIGN_STYLE = Automatic;
531 | GCC_PREFIX_HEADER = "$(SRCROOT)/$(PROJECT_NAME)/LX_Prefix.pch";
532 | INFOPLIST_FILE = LXSegmentControl/Info.plist;
533 | LD_RUNPATH_SEARCH_PATHS = (
534 | "$(inherited)",
535 | "@executable_path/Frameworks",
536 | );
537 | PRODUCT_BUNDLE_IDENTIFIER = "https---github.com-nick8brown.LXSegmentControl";
538 | PRODUCT_NAME = "$(TARGET_NAME)";
539 | TARGETED_DEVICE_FAMILY = "1,2";
540 | };
541 | name = Debug;
542 | };
543 | 2436BD1A21B4CDC700E8D063 /* Release */ = {
544 | isa = XCBuildConfiguration;
545 | buildSettings = {
546 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
547 | CODE_SIGN_STYLE = Automatic;
548 | GCC_PREFIX_HEADER = "$(SRCROOT)/$(PROJECT_NAME)/LX_Prefix.pch";
549 | INFOPLIST_FILE = LXSegmentControl/Info.plist;
550 | LD_RUNPATH_SEARCH_PATHS = (
551 | "$(inherited)",
552 | "@executable_path/Frameworks",
553 | );
554 | PRODUCT_BUNDLE_IDENTIFIER = "https---github.com-nick8brown.LXSegmentControl";
555 | PRODUCT_NAME = "$(TARGET_NAME)";
556 | TARGETED_DEVICE_FAMILY = "1,2";
557 | };
558 | name = Release;
559 | };
560 | 2436BD1C21B4CDC700E8D063 /* Debug */ = {
561 | isa = XCBuildConfiguration;
562 | buildSettings = {
563 | BUNDLE_LOADER = "$(TEST_HOST)";
564 | CODE_SIGN_STYLE = Automatic;
565 | INFOPLIST_FILE = LXSegmentControlTests/Info.plist;
566 | LD_RUNPATH_SEARCH_PATHS = (
567 | "$(inherited)",
568 | "@executable_path/Frameworks",
569 | "@loader_path/Frameworks",
570 | );
571 | PRODUCT_BUNDLE_IDENTIFIER = "https---github.com-nick8brown.LXSegmentControlTests";
572 | PRODUCT_NAME = "$(TARGET_NAME)";
573 | TARGETED_DEVICE_FAMILY = "1,2";
574 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/LXSegmentControl.app/LXSegmentControl";
575 | };
576 | name = Debug;
577 | };
578 | 2436BD1D21B4CDC700E8D063 /* Release */ = {
579 | isa = XCBuildConfiguration;
580 | buildSettings = {
581 | BUNDLE_LOADER = "$(TEST_HOST)";
582 | CODE_SIGN_STYLE = Automatic;
583 | INFOPLIST_FILE = LXSegmentControlTests/Info.plist;
584 | LD_RUNPATH_SEARCH_PATHS = (
585 | "$(inherited)",
586 | "@executable_path/Frameworks",
587 | "@loader_path/Frameworks",
588 | );
589 | PRODUCT_BUNDLE_IDENTIFIER = "https---github.com-nick8brown.LXSegmentControlTests";
590 | PRODUCT_NAME = "$(TARGET_NAME)";
591 | TARGETED_DEVICE_FAMILY = "1,2";
592 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/LXSegmentControl.app/LXSegmentControl";
593 | };
594 | name = Release;
595 | };
596 | 2436BD1F21B4CDC700E8D063 /* Debug */ = {
597 | isa = XCBuildConfiguration;
598 | buildSettings = {
599 | CODE_SIGN_STYLE = Automatic;
600 | INFOPLIST_FILE = LXSegmentControlUITests/Info.plist;
601 | LD_RUNPATH_SEARCH_PATHS = (
602 | "$(inherited)",
603 | "@executable_path/Frameworks",
604 | "@loader_path/Frameworks",
605 | );
606 | PRODUCT_BUNDLE_IDENTIFIER = "https---github.com-nick8brown.LXSegmentControlUITests";
607 | PRODUCT_NAME = "$(TARGET_NAME)";
608 | TARGETED_DEVICE_FAMILY = "1,2";
609 | TEST_TARGET_NAME = LXSegmentControl;
610 | };
611 | name = Debug;
612 | };
613 | 2436BD2021B4CDC700E8D063 /* Release */ = {
614 | isa = XCBuildConfiguration;
615 | buildSettings = {
616 | CODE_SIGN_STYLE = Automatic;
617 | INFOPLIST_FILE = LXSegmentControlUITests/Info.plist;
618 | LD_RUNPATH_SEARCH_PATHS = (
619 | "$(inherited)",
620 | "@executable_path/Frameworks",
621 | "@loader_path/Frameworks",
622 | );
623 | PRODUCT_BUNDLE_IDENTIFIER = "https---github.com-nick8brown.LXSegmentControlUITests";
624 | PRODUCT_NAME = "$(TARGET_NAME)";
625 | TARGETED_DEVICE_FAMILY = "1,2";
626 | TEST_TARGET_NAME = LXSegmentControl;
627 | };
628 | name = Release;
629 | };
630 | /* End XCBuildConfiguration section */
631 |
632 | /* Begin XCConfigurationList section */
633 | 2436BCE721B4CDC500E8D063 /* Build configuration list for PBXProject "LXSegmentControl" */ = {
634 | isa = XCConfigurationList;
635 | buildConfigurations = (
636 | 2436BD1621B4CDC700E8D063 /* Debug */,
637 | 2436BD1721B4CDC700E8D063 /* Release */,
638 | );
639 | defaultConfigurationIsVisible = 0;
640 | defaultConfigurationName = Release;
641 | };
642 | 2436BD1821B4CDC700E8D063 /* Build configuration list for PBXNativeTarget "LXSegmentControl" */ = {
643 | isa = XCConfigurationList;
644 | buildConfigurations = (
645 | 2436BD1921B4CDC700E8D063 /* Debug */,
646 | 2436BD1A21B4CDC700E8D063 /* Release */,
647 | );
648 | defaultConfigurationIsVisible = 0;
649 | defaultConfigurationName = Release;
650 | };
651 | 2436BD1B21B4CDC700E8D063 /* Build configuration list for PBXNativeTarget "LXSegmentControlTests" */ = {
652 | isa = XCConfigurationList;
653 | buildConfigurations = (
654 | 2436BD1C21B4CDC700E8D063 /* Debug */,
655 | 2436BD1D21B4CDC700E8D063 /* Release */,
656 | );
657 | defaultConfigurationIsVisible = 0;
658 | defaultConfigurationName = Release;
659 | };
660 | 2436BD1E21B4CDC700E8D063 /* Build configuration list for PBXNativeTarget "LXSegmentControlUITests" */ = {
661 | isa = XCConfigurationList;
662 | buildConfigurations = (
663 | 2436BD1F21B4CDC700E8D063 /* Debug */,
664 | 2436BD2021B4CDC700E8D063 /* Release */,
665 | );
666 | defaultConfigurationIsVisible = 0;
667 | defaultConfigurationName = Release;
668 | };
669 | /* End XCConfigurationList section */
670 | };
671 | rootObject = 2436BCE421B4CDC500E8D063 /* Project object */;
672 | }
673 |
--------------------------------------------------------------------------------