├── Demo
├── LGFilterViewDemo
│ ├── Images.xcassets
│ │ ├── Contents.json
│ │ ├── Arrow.imageset
│ │ │ ├── Arrow.png
│ │ │ ├── Arrow-1.png
│ │ │ ├── Arrow-2.png
│ │ │ └── Contents.json
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ ├── Filter.imageset
│ │ │ ├── Filter@1x.png
│ │ │ ├── Filter@2x.png
│ │ │ ├── Filter@3x.png
│ │ │ └── Contents.json
│ │ └── LaunchImage.launchimage
│ │ │ ├── Launch-Pad-L@1x.png
│ │ │ ├── Launch-Pad-L@2x.png
│ │ │ ├── Launch-Pad-P@1x.png
│ │ │ ├── Launch-Pad-P@2x.png
│ │ │ ├── Launch-Phone-35-P@1x.png
│ │ │ ├── Launch-Phone-35-P@2x.png
│ │ │ ├── Launch-Phone-40-P@2x.png
│ │ │ ├── Launch-Phone-47-P@2x.png
│ │ │ ├── Launch-Phone-55-L@3x.png
│ │ │ ├── Launch-Phone-55-P@3x.png
│ │ │ └── Contents.json
│ ├── ViewController.h
│ ├── NavigationController.h
│ ├── AppDelegate.h
│ ├── main.m
│ ├── NavigationController.m
│ ├── Info.plist
│ ├── AppDelegate.m
│ └── ViewController.m
└── LGFilterViewDemo.xcodeproj
│ ├── project.xcworkspace
│ └── contents.xcworkspacedata
│ └── project.pbxproj
├── Framework
├── LGFilterViewFramework.xcodeproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ ├── xcshareddata
│ │ └── xcschemes
│ │ │ └── LGFilterViewFramework.xcscheme
│ └── project.pbxproj
└── LGFilterViewFramework
│ ├── LGFilterViewFramework.h
│ └── Info.plist
├── LGFilterView.podspec
├── .gitignore
├── LICENSE
├── LGFilterView
├── LGFilterViewCell.h
├── LGFilterViewCell.m
├── LGFilterView.h
└── LGFilterView.m
└── README.md
/Demo/LGFilterViewDemo/Images.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/Images.xcassets/Arrow.imageset/Arrow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Friend-LGA/LGFilterView/HEAD/Demo/LGFilterViewDemo/Images.xcassets/Arrow.imageset/Arrow.png
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 |
4 | ],
5 | "info" : {
6 | "version" : 1,
7 | "author" : "xcode"
8 | }
9 | }
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/Images.xcassets/Arrow.imageset/Arrow-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Friend-LGA/LGFilterView/HEAD/Demo/LGFilterViewDemo/Images.xcassets/Arrow.imageset/Arrow-1.png
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/Images.xcassets/Arrow.imageset/Arrow-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Friend-LGA/LGFilterView/HEAD/Demo/LGFilterViewDemo/Images.xcassets/Arrow.imageset/Arrow-2.png
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/Images.xcassets/Filter.imageset/Filter@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Friend-LGA/LGFilterView/HEAD/Demo/LGFilterViewDemo/Images.xcassets/Filter.imageset/Filter@1x.png
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/Images.xcassets/Filter.imageset/Filter@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Friend-LGA/LGFilterView/HEAD/Demo/LGFilterViewDemo/Images.xcassets/Filter.imageset/Filter@2x.png
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/Images.xcassets/Filter.imageset/Filter@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Friend-LGA/LGFilterView/HEAD/Demo/LGFilterViewDemo/Images.xcassets/Filter.imageset/Filter@3x.png
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-L@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Friend-LGA/LGFilterView/HEAD/Demo/LGFilterViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-L@1x.png
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-L@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Friend-LGA/LGFilterView/HEAD/Demo/LGFilterViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-L@2x.png
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-P@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Friend-LGA/LGFilterView/HEAD/Demo/LGFilterViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-P@1x.png
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-P@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Friend-LGA/LGFilterView/HEAD/Demo/LGFilterViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Pad-P@2x.png
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-35-P@1x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Friend-LGA/LGFilterView/HEAD/Demo/LGFilterViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-35-P@1x.png
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-35-P@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Friend-LGA/LGFilterView/HEAD/Demo/LGFilterViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-35-P@2x.png
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-40-P@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Friend-LGA/LGFilterView/HEAD/Demo/LGFilterViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-40-P@2x.png
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-47-P@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Friend-LGA/LGFilterView/HEAD/Demo/LGFilterViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-47-P@2x.png
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-55-L@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Friend-LGA/LGFilterView/HEAD/Demo/LGFilterViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-55-L@3x.png
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-55-P@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Friend-LGA/LGFilterView/HEAD/Demo/LGFilterViewDemo/Images.xcassets/LaunchImage.launchimage/Launch-Phone-55-P@3x.png
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Framework/LGFilterViewFramework.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // LGFilterViewDemo
4 | //
5 | // Created by Grigory Lutkov on 27.03.15.
6 | // Copyright (c) 2015 Grigory Lutkov. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/NavigationController.h:
--------------------------------------------------------------------------------
1 | //
2 | // NavigationController.h
3 | // LGFilterViewDemo
4 | //
5 | // Created by Grigory Lutkov on 18.02.15.
6 | // Copyright (c) 2015 Grigory Lutkov. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NavigationController : UINavigationController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // LGFilterViewDemo
4 | //
5 | // Created by Grigory Lutkov on 18.02.15.
6 | // Copyright (c) 2015 Grigory Lutkov. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // LGFilterViewDemo
4 | //
5 | // Created by Friend_LGA on 30.03.15.
6 | // Copyright (c) 2015 Grigory Lutkov. 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 |
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/Images.xcassets/Arrow.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "filename" : "Arrow.png",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "filename" : "Arrow-1.png",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "filename" : "Arrow-2.png",
16 | "scale" : "3x"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/Images.xcassets/Filter.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x",
6 | "filename" : "Filter@1x.png"
7 | },
8 | {
9 | "idiom" : "universal",
10 | "scale" : "2x",
11 | "filename" : "Filter@2x.png"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x",
16 | "filename" : "Filter@3x.png"
17 | }
18 | ],
19 | "info" : {
20 | "version" : 1,
21 | "author" : "xcode"
22 | }
23 | }
--------------------------------------------------------------------------------
/LGFilterView.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 |
3 | s.name = 'LGFilterView'
4 | s.version = '1.0.3'
5 | s.platform = :ios, '6.0'
6 | s.license = 'MIT'
7 | s.homepage = 'https://github.com/Friend-LGA/LGFilterView'
8 | s.author = { 'Grigory Lutkov' => 'Friend.LGA@gmail.com' }
9 | s.source = { :git => 'https://github.com/Friend-LGA/LGFilterView.git', :tag => s.version }
10 | s.summary = 'View shows and applies different filters in iOS app'
11 |
12 | s.requires_arc = true
13 |
14 | s.source_files = 'LGFilterView/*.{h,m}'
15 |
16 | end
17 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | build/
4 | *.pbxuser
5 | !default.pbxuser
6 | *.mode1v3
7 | !default.mode1v3
8 | *.mode2v3
9 | !default.mode2v3
10 | *.perspectivev3
11 | !default.perspectivev3
12 | xcuserdata
13 | *.xccheckout
14 | *.moved-aside
15 | DerivedData
16 | *.hmap
17 | *.ipa
18 | *.xcuserstate
19 |
20 | # CocoaPods
21 | #
22 | # We recommend against adding the Pods directory to your .gitignore. However
23 | # you should judge for yourself, the pros and cons are mentioned at:
24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
25 | #
26 | Pods/
27 |
28 | ###
29 | ._*
30 |
31 | .hgignore
32 |
33 | .DS_Store
34 |
--------------------------------------------------------------------------------
/Framework/LGFilterViewFramework/LGFilterViewFramework.h:
--------------------------------------------------------------------------------
1 | //
2 | // LGFilterViewFramework.h
3 | // LGFilterViewFramework
4 | //
5 | // Created by Grigory Lutkov on 11.11.15.
6 | // Copyright © 2015 Grigory Lutkov. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | //! Project version number for LGFilterViewFramework.
12 | FOUNDATION_EXPORT double LGFilterViewFrameworkVersionNumber;
13 |
14 | //! Project version string for LGFilterViewFramework.
15 | FOUNDATION_EXPORT const unsigned char LGFilterViewFrameworkVersionString[];
16 |
17 | #pragma mark -
18 |
19 | #import
20 | #import
21 |
--------------------------------------------------------------------------------
/Framework/LGFilterViewFramework/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/NavigationController.m:
--------------------------------------------------------------------------------
1 | //
2 | // NavigationController.m
3 | // LGFilterViewDemo
4 | //
5 | // Created by Grigory Lutkov on 18.02.15.
6 | // Copyright (c) 2015 Grigory Lutkov. All rights reserved.
7 | //
8 |
9 | #import "NavigationController.h"
10 |
11 | @interface NavigationController ()
12 |
13 | @end
14 |
15 | @implementation NavigationController
16 |
17 | - (void)viewDidLoad
18 | {
19 | [super viewDidLoad];
20 |
21 | self.navigationBar.translucent = YES;
22 | self.navigationBar.barTintColor = [UIColor colorWithRed:0.f green:0.5 blue:1.f alpha:1.f];
23 | self.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName: [UIColor whiteColor]};
24 | self.navigationBar.tintColor = [UIColor whiteColor];
25 | }
26 |
27 | - (BOOL)shouldAutorotate
28 | {
29 | return YES;
30 | }
31 |
32 | - (BOOL)prefersStatusBarHidden
33 | {
34 | return UIInterfaceOrientationIsLandscape([UIApplication sharedApplication].statusBarOrientation);
35 | }
36 |
37 | - (UIStatusBarStyle)preferredStatusBarStyle
38 | {
39 | return UIStatusBarStyleLightContent;
40 | }
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2015 Grigory Lutkov
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UIRequiredDeviceCapabilities
26 |
27 | armv7
28 |
29 | UISupportedInterfaceOrientations
30 |
31 | UIInterfaceOrientationPortrait
32 | UIInterfaceOrientationLandscapeLeft
33 | UIInterfaceOrientationLandscapeRight
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/LGFilterView/LGFilterViewCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // LGFilterViewCell.h
3 | // LGFilterView
4 | //
5 | //
6 | // The MIT License (MIT)
7 | //
8 | // Copyright (c) 2015 Grigory Lutkov
9 | // (https://github.com/Friend-LGA/LGFilterView)
10 | //
11 | // Permission is hereby granted, free of charge, to any person obtaining a copy
12 | // of this software and associated documentation files (the "Software"), to deal
13 | // in the Software without restriction, including without limitation the rights
14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 | // copies of the Software, and to permit persons to whom the Software is
16 | // furnished to do so, subject to the following conditions:
17 | //
18 | // The above copyright notice and this permission notice shall be included in all
19 | // copies or substantial portions of the Software.
20 | //
21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 | // SOFTWARE.
28 | //
29 |
30 | #import
31 |
32 | @interface LGFilterViewCell : UITableViewCell
33 |
34 | @property (strong, nonatomic) NSString *title;
35 |
36 | @property (strong, nonatomic) UIColor *titleColor;
37 | @property (strong, nonatomic) UIColor *titleColorHighlighted;
38 | @property (strong, nonatomic) UIColor *titleColorSelected;
39 |
40 | @property (strong, nonatomic) UIColor *backgroundColorHighlighted;
41 | @property (strong, nonatomic) UIColor *backgroundColorSelected;
42 |
43 | @property (assign, nonatomic, getter=isSeparatorVisible) BOOL separatorVisible;
44 | @property (strong, nonatomic) UIColor *separatorColor;
45 | @property (assign, nonatomic) UIEdgeInsets separatorEdgeInsets;
46 |
47 | @property (strong, nonatomic) UIFont *font;
48 | @property (assign, nonatomic) NSUInteger numberOfLines;
49 | @property (assign, nonatomic) NSLineBreakMode lineBreakMode;
50 | @property (assign, nonatomic) NSTextAlignment textAlignment;
51 | @property (assign, nonatomic) BOOL adjustsFontSizeToFitWidth;
52 | @property (assign, nonatomic) CGFloat minimumScaleFactor;
53 |
54 | @end
55 |
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // LGFilterViewDemo
4 | //
5 | // Created by Grigory Lutkov on 18.02.15.
6 | // Copyright (c) 2015 Grigory Lutkov. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import "NavigationController.h"
11 | #import "ViewController.h"
12 |
13 | @implementation AppDelegate
14 |
15 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
16 | {
17 | ViewController *viewController = [ViewController new];
18 | NavigationController *navigationController = [[NavigationController alloc] initWithRootViewController:viewController];
19 |
20 | self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
21 | self.window.rootViewController = navigationController;
22 | self.window.backgroundColor = [UIColor whiteColor];
23 | [self.window makeKeyAndVisible];
24 |
25 | return YES;
26 | }
27 |
28 | - (void)applicationWillResignActive:(UIApplication *)application
29 | {
30 | // 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.
31 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
32 | }
33 |
34 | - (void)applicationDidEnterBackground:(UIApplication *)application
35 | {
36 | // 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.
37 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
38 | }
39 |
40 | - (void)applicationWillEnterForeground:(UIApplication *)application
41 | {
42 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
43 | }
44 |
45 | - (void)applicationDidBecomeActive:(UIApplication *)application
46 | {
47 | // 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.
48 | }
49 |
50 | - (void)applicationWillTerminate:(UIApplication *)application
51 | {
52 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
53 | }
54 |
55 | @end
56 |
--------------------------------------------------------------------------------
/Framework/LGFilterViewFramework.xcodeproj/xcshareddata/xcschemes/LGFilterViewFramework.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
35 |
45 |
46 |
52 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
70 |
71 |
72 |
73 |
75 |
76 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/Images.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "extent" : "full-screen",
5 | "idiom" : "iphone",
6 | "subtype" : "736h",
7 | "filename" : "Launch-Phone-55-P@3x.png",
8 | "minimum-system-version" : "8.0",
9 | "orientation" : "portrait",
10 | "scale" : "3x"
11 | },
12 | {
13 | "extent" : "full-screen",
14 | "idiom" : "iphone",
15 | "subtype" : "736h",
16 | "filename" : "Launch-Phone-55-L@3x.png",
17 | "minimum-system-version" : "8.0",
18 | "orientation" : "landscape",
19 | "scale" : "3x"
20 | },
21 | {
22 | "extent" : "full-screen",
23 | "idiom" : "iphone",
24 | "subtype" : "667h",
25 | "filename" : "Launch-Phone-47-P@2x.png",
26 | "minimum-system-version" : "8.0",
27 | "orientation" : "portrait",
28 | "scale" : "2x"
29 | },
30 | {
31 | "orientation" : "portrait",
32 | "idiom" : "iphone",
33 | "extent" : "full-screen",
34 | "minimum-system-version" : "7.0",
35 | "filename" : "Launch-Phone-35-P@2x.png",
36 | "scale" : "2x"
37 | },
38 | {
39 | "extent" : "full-screen",
40 | "idiom" : "iphone",
41 | "subtype" : "retina4",
42 | "filename" : "Launch-Phone-40-P@2x.png",
43 | "minimum-system-version" : "7.0",
44 | "orientation" : "portrait",
45 | "scale" : "2x"
46 | },
47 | {
48 | "orientation" : "portrait",
49 | "idiom" : "ipad",
50 | "extent" : "full-screen",
51 | "minimum-system-version" : "7.0",
52 | "filename" : "Launch-Pad-P@1x.png",
53 | "scale" : "1x"
54 | },
55 | {
56 | "orientation" : "landscape",
57 | "idiom" : "ipad",
58 | "extent" : "full-screen",
59 | "minimum-system-version" : "7.0",
60 | "filename" : "Launch-Pad-L@1x.png",
61 | "scale" : "1x"
62 | },
63 | {
64 | "orientation" : "portrait",
65 | "idiom" : "ipad",
66 | "extent" : "full-screen",
67 | "minimum-system-version" : "7.0",
68 | "filename" : "Launch-Pad-P@2x.png",
69 | "scale" : "2x"
70 | },
71 | {
72 | "orientation" : "landscape",
73 | "idiom" : "ipad",
74 | "extent" : "full-screen",
75 | "minimum-system-version" : "7.0",
76 | "filename" : "Launch-Pad-L@2x.png",
77 | "scale" : "2x"
78 | },
79 | {
80 | "orientation" : "portrait",
81 | "idiom" : "iphone",
82 | "extent" : "full-screen",
83 | "filename" : "Launch-Phone-35-P@1x.png",
84 | "scale" : "1x"
85 | },
86 | {
87 | "orientation" : "portrait",
88 | "idiom" : "iphone",
89 | "extent" : "full-screen",
90 | "filename" : "Launch-Phone-35-P@2x.png",
91 | "scale" : "2x"
92 | },
93 | {
94 | "orientation" : "portrait",
95 | "idiom" : "iphone",
96 | "extent" : "full-screen",
97 | "filename" : "Launch-Phone-40-P@2x.png",
98 | "subtype" : "retina4",
99 | "scale" : "2x"
100 | },
101 | {
102 | "orientation" : "portrait",
103 | "idiom" : "ipad",
104 | "extent" : "full-screen",
105 | "filename" : "Launch-Pad-P@1x.png",
106 | "scale" : "1x"
107 | },
108 | {
109 | "orientation" : "landscape",
110 | "idiom" : "ipad",
111 | "extent" : "full-screen",
112 | "filename" : "Launch-Pad-L@1x.png",
113 | "scale" : "1x"
114 | },
115 | {
116 | "orientation" : "portrait",
117 | "idiom" : "ipad",
118 | "extent" : "full-screen",
119 | "filename" : "Launch-Pad-P@2x.png",
120 | "scale" : "2x"
121 | },
122 | {
123 | "orientation" : "landscape",
124 | "idiom" : "ipad",
125 | "extent" : "full-screen",
126 | "filename" : "Launch-Pad-L@2x.png",
127 | "scale" : "2x"
128 | }
129 | ],
130 | "info" : {
131 | "version" : 1,
132 | "author" : "xcode"
133 | }
134 | }
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # LGFilterView
2 |
3 | View shows and applies different filters in iOS app.
4 |
5 | ## Preview
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | ## Installation
14 |
15 | ### With source code
16 |
17 | [Download repository](https://github.com/Friend-LGA/LGFilterView/archive/master.zip), then add [LGFilterView directory](https://github.com/Friend-LGA/LGFilterView/blob/master/LGFilterView/) to your project.
18 |
19 | ### With CocoaPods
20 |
21 | CocoaPods is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries in your projects. To install with cocoaPods, follow the "Get Started" section on [CocoaPods](https://cocoapods.org/).
22 |
23 | #### Podfile
24 | ```ruby
25 | platform :ios, '6.0'
26 | pod 'LGFilterView', '~> 1.0.0'
27 | ```
28 |
29 | ### With Carthage
30 |
31 | Carthage is a lightweight dependency manager for Swift and Objective-C. It leverages CocoaTouch modules and is less invasive than CocoaPods. To install with carthage, follow the instruction on [Carthage](https://github.com/Carthage/Carthage/).
32 |
33 | #### Cartfile
34 | ```
35 | github "Friend-LGA/LGFilterView" ~> 1.0.0
36 | ```
37 |
38 | ## Usage
39 |
40 | In the source files where you need to use the library, import the header file:
41 |
42 | ```objective-c
43 | #import "LGFilterView.h"
44 | ```
45 |
46 | ### Initialization
47 |
48 | You have several methods for initialization:
49 |
50 | ```objective-c
51 | - (instancetype)initWithView:(UIView *)view;
52 | - (instancetype)initWithTitles:(NSArray *)titles;
53 | ```
54 |
55 | More init methods you can find in [LGFilterView.h](https://github.com/Friend-LGA/LGFilterView/blob/master/LGFilterView/LGFilterView.h)
56 |
57 | ### Handle actions
58 |
59 | To handle actions you can use initialization methods with blocks or delegate, or implement it after initialization.
60 |
61 | #### Delegate
62 |
63 | ```objective-c
64 | @property (assign, nonatomic) id delegate;
65 |
66 | - (void)filterViewWillShow:(LGFilterView *)filterView;
67 | - (void)filterViewWillDismiss:(LGFilterView *)filterView;
68 | - (void)filterViewDidShow:(LGFilterView *)filterView;
69 | - (void)filterViewDidDismiss:(LGFilterView *)filterView;
70 | - (void)filterView:(LGFilterView *)filterView buttonPressedWithTitle:(NSString *)title index:(NSUInteger)index;
71 | - (void)filterViewCancelled:(LGFilterView *)filterView;
72 | ```
73 |
74 | #### Blocks
75 |
76 | ```objective-c
77 | @property (strong, nonatomic) void (^willShowHandler)(LGFilterView *filterView);
78 | @property (strong, nonatomic) void (^willDismissHandler)(LGFilterView *filterView);
79 | @property (strong, nonatomic) void (^didShowHandler)(LGFilterView *filterView);
80 | @property (strong, nonatomic) void (^didDismissHandler)(LGFilterView *filterView);
81 | @property (strong, nonatomic) void (^actionHandler)(LGFilterView *filterView, NSString *title, NSUInteger index);
82 | @property (strong, nonatomic) void (^cancelHandler)(LGFilterView *filterView);
83 | ```
84 |
85 | #### Notifications
86 |
87 | Here is also some notifications, that you can add to NSNotificationsCenter:
88 |
89 | ```objective-c
90 | kLGFilterViewWillShowNotification;
91 | kLGFilterViewWillDismissNotification;
92 | kLGFilterViewDidShowNotification;
93 | kLGFilterViewDidDismissNotification;
94 | ```
95 |
96 | ### More
97 |
98 | For more details try Xcode [Demo project](https://github.com/Friend-LGA/LGFilterView/blob/master/Demo) and see [LGFilterView.h](https://github.com/Friend-LGA/LGFilterView/blob/master/LGFilterView/LGFilterView.h)
99 |
100 | ## License
101 |
102 | LGFilterView is released under the MIT license. See [LICENSE](https://raw.githubusercontent.com/Friend-LGA/LGFilterView/master/LICENSE) for details.
103 |
--------------------------------------------------------------------------------
/LGFilterView/LGFilterViewCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // LGFilterViewCell.m
3 | // LGFilterView
4 | //
5 | //
6 | // The MIT License (MIT)
7 | //
8 | // Copyright (c) 2015 Grigory Lutkov
9 | // (https://github.com/Friend-LGA/LGFilterView)
10 | //
11 | // Permission is hereby granted, free of charge, to any person obtaining a copy
12 | // of this software and associated documentation files (the "Software"), to deal
13 | // in the Software without restriction, including without limitation the rights
14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 | // copies of the Software, and to permit persons to whom the Software is
16 | // furnished to do so, subject to the following conditions:
17 | //
18 | // The above copyright notice and this permission notice shall be included in all
19 | // copies or substantial portions of the Software.
20 | //
21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 | // SOFTWARE.
28 | //
29 |
30 | #import "LGFilterViewCell.h"
31 |
32 | @interface LGFilterViewCell ()
33 |
34 | @property (strong, nonatomic) UILabel *titleLabel;
35 | @property (strong, nonatomic) UIView *separatorView;
36 |
37 | @end
38 |
39 | @implementation LGFilterViewCell
40 |
41 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
42 | {
43 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
44 | if (self)
45 | {
46 | self.selectionStyle = UITableViewCellSelectionStyleNone;
47 |
48 | _titleLabel = [UILabel new];
49 | _titleLabel.backgroundColor = [UIColor clearColor];
50 | [self addSubview:_titleLabel];
51 |
52 | _separatorView = [UIView new];
53 | [self addSubview:_separatorView];
54 | }
55 | return self;
56 | }
57 |
58 | - (void)layoutSubviews
59 | {
60 | [super layoutSubviews];
61 |
62 | _titleLabel.text = _title;
63 | _titleLabel.textAlignment = _textAlignment;
64 | _titleLabel.font = _font;
65 | _titleLabel.numberOfLines = _numberOfLines;
66 | _titleLabel.lineBreakMode = _lineBreakMode;
67 | _titleLabel.adjustsFontSizeToFitWidth = _adjustsFontSizeToFitWidth;
68 | _titleLabel.minimumScaleFactor = _minimumScaleFactor;
69 |
70 | CGRect titleLabelFrame = CGRectMake(10.f, 0.f, self.frame.size.width-20.f, self.frame.size.height);
71 | if ([UIScreen mainScreen].scale == 1.f)
72 | titleLabelFrame = CGRectIntegral(titleLabelFrame);
73 | _titleLabel.frame = titleLabelFrame;
74 |
75 | if (self.isSeparatorVisible)
76 | {
77 | _separatorView.hidden = NO;
78 |
79 | _separatorView.backgroundColor = _separatorColor;
80 |
81 | CGFloat separatorHeight = ([UIScreen mainScreen].scale == 1.f ? 1.f : 0.5);
82 |
83 | _separatorView.frame = CGRectMake(_separatorEdgeInsets.left, self.frame.size.height-separatorHeight, self.frame.size.width-_separatorEdgeInsets.left-_separatorEdgeInsets.right, separatorHeight);
84 | }
85 | else _separatorView.hidden = YES;
86 | }
87 |
88 | - (void)setHighlighted:(BOOL)highlighted animated:(BOOL)animated
89 | {
90 | [super setHighlighted:highlighted animated:animated];
91 |
92 | if (!self.isSelected)
93 | {
94 | if (highlighted)
95 | {
96 | _titleLabel.textColor = _titleColorHighlighted;
97 | self.backgroundColor = _backgroundColorHighlighted;
98 | }
99 | else
100 | {
101 | _titleLabel.textColor = _titleColor;
102 | self.backgroundColor = [UIColor clearColor];
103 | }
104 | }
105 | }
106 |
107 | - (void)setSelected:(BOOL)selected animated:(BOOL)animated
108 | {
109 | [super setSelected:selected animated:animated];
110 |
111 | if (selected)
112 | {
113 | _titleLabel.textColor = _titleColorSelected;
114 | self.backgroundColor = _backgroundColorSelected;
115 | }
116 | else
117 | {
118 | if (self.isHighlighted)
119 | {
120 | _titleLabel.textColor = _titleColorHighlighted;
121 | self.backgroundColor = _backgroundColorHighlighted;
122 | }
123 | else
124 | {
125 | _titleLabel.textColor = _titleColor;
126 | self.backgroundColor = [UIColor clearColor];
127 | }
128 | }
129 | }
130 |
131 | @end
132 |
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // LGFilterViewDemo
4 | //
5 | // Created by Grigory Lutkov on 27.03.15.
6 | // Copyright (c) 2015 Grigory Lutkov. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "LGFilterView.h"
11 |
12 | @interface ViewController ()
13 |
14 | @property (strong, nonatomic) LGFilterView *filterView1;
15 | @property (strong, nonatomic) LGFilterView *filterView2;
16 |
17 | @property (strong, nonatomic) NSArray *titlesArray;
18 | @property (strong, nonatomic) UIButton *titleButton;
19 |
20 | @property (strong, nonatomic) UIView *innerView;
21 |
22 | @property (strong, nonatomic) UISegmentedControl *segmentControl;
23 |
24 | @end
25 |
26 | @implementation ViewController
27 |
28 | - (id)init
29 | {
30 | self = [super init];
31 | if (self)
32 | {
33 | self.title = @"LGFilterView";
34 |
35 | self.view.backgroundColor = [UIColor whiteColor];
36 |
37 | // -----
38 |
39 | _innerView = [UIView new];
40 | _innerView.backgroundColor = [UIColor clearColor];
41 | _innerView.frame = CGRectMake(0.f, 0.f, 200.f, 200.f);
42 |
43 | UILabel *label = [UILabel new];
44 | label.backgroundColor = [UIColor clearColor];
45 | label.text = @"UIView";
46 | label.textColor = [UIColor colorWithRed:0.f green:0.5 blue:1.f alpha:1.f];
47 | [label sizeToFit];
48 | label.center = CGPointMake(_innerView.frame.size.width/2, _innerView.frame.size.height/2);
49 | [_innerView addSubview:label];
50 |
51 | // -----
52 |
53 | _titlesArray = @[@"Title 1",
54 | @"Title 2",
55 | @"Title 3",
56 | @"Title 4",
57 | @"Title 5",
58 | @"Title 6",
59 | @"Title 7",
60 | @"Title 8",
61 | @"Title 9",
62 | @"Title 10"];
63 |
64 | UIImage *arrowImage = [UIImage imageNamed:@"Arrow"];
65 |
66 | _titleButton = [UIButton new];
67 | _titleButton.backgroundColor = [UIColor clearColor];
68 | _titleButton.tag = 0;
69 | [_titleButton setTitle:_titlesArray.firstObject forState:UIControlStateNormal];
70 | [_titleButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
71 | [_titleButton setImage:arrowImage forState:UIControlStateNormal];
72 | _titleButton.titleLabel.font = [UIFont systemFontOfSize:20.f];
73 | _titleButton.imageEdgeInsets = UIEdgeInsetsMake(0.f, -4.f, 0.f, 4.f);
74 | _titleButton.titleEdgeInsets = UIEdgeInsetsMake(0.f, 4.f, 0.f, -4.f);
75 | [_titleButton addTarget:self action:@selector(filterAction1:) forControlEvents:UIControlEventTouchUpInside];
76 | [_titleButton sizeToFit];
77 |
78 | self.navigationItem.titleView = _titleButton;
79 |
80 | // -----
81 |
82 | UIBarButtonItem *rightButton = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"Filter"] style:UIBarButtonItemStylePlain target:self action:@selector(filterAction2:)];
83 | self.navigationItem.rightBarButtonItem = rightButton;
84 |
85 | // -----
86 |
87 | _segmentControl = [[UISegmentedControl alloc] initWithItems:@[@"Top", @"Center"]];
88 | _segmentControl.selectedSegmentIndex = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone ? 0 : 1);
89 | [_segmentControl addTarget:self action:@selector(updateFilterProperties:) forControlEvents:UIControlEventValueChanged];
90 | [self.view addSubview:_segmentControl];
91 |
92 | // -----
93 |
94 | [self setupFilterViewsWithTransitionStyle:(LGFilterViewTransitionStyle)_segmentControl.selectedSegmentIndex];
95 | }
96 | return self;
97 | }
98 |
99 | #pragma mark - Dealloc
100 |
101 | - (void)dealloc
102 | {
103 | NSLog(@"%s [Line %d]", __PRETTY_FUNCTION__, __LINE__);
104 | }
105 |
106 | #pragma mark - Appearing
107 |
108 | - (void)viewWillLayoutSubviews
109 | {
110 | [super viewWillLayoutSubviews];
111 |
112 | CGFloat topInset = self.navigationController.navigationBar.frame.size.height+([UIApplication sharedApplication].isStatusBarHidden ? 0.f : [UIApplication sharedApplication].statusBarFrame.size.height);
113 | if ([UIDevice currentDevice].systemVersion.floatValue < 7.0) topInset = 0.f;
114 |
115 | _segmentControl.center = CGPointMake(self.view.frame.size.width/2, topInset+20.f+_segmentControl.frame.size.height/2);
116 | _segmentControl.frame = CGRectIntegral(_segmentControl.frame);
117 |
118 | [self updateFilterProperties:nil];
119 | }
120 |
121 | #pragma mark -
122 |
123 | - (void)filterAction1:(UIButton *)button
124 | {
125 | if (_filterView2.isShowing)
126 | [_filterView2 dismissAnimated:YES completionHandler:nil];
127 |
128 | if (!_filterView1.isShowing)
129 | {
130 | _filterView1.selectedIndex = button.tag;
131 |
132 | [_filterView1 showInView:self.view animated:YES completionHandler:nil];
133 | }
134 | else [_filterView1 dismissAnimated:YES completionHandler:nil];
135 | }
136 |
137 | - (void)filterAction2:(UIButton *)button
138 | {
139 | if (_filterView1.isShowing)
140 | [_filterView1 dismissAnimated:YES completionHandler:nil];
141 |
142 | if (!_filterView2.isShowing)
143 | [_filterView2 showInView:self.view animated:YES completionHandler:nil];
144 | else
145 | [_filterView2 dismissAnimated:YES completionHandler:nil];
146 | }
147 |
148 | - (void)updateFilterProperties:(UISegmentedControl *)segmentControl
149 | {
150 | if (segmentControl)
151 | [self setupFilterViewsWithTransitionStyle:(LGFilterViewTransitionStyle)segmentControl.selectedSegmentIndex];
152 |
153 | CGFloat topInset = self.navigationController.navigationBar.frame.size.height+([UIApplication sharedApplication].isStatusBarHidden ? 0.f : [UIApplication sharedApplication].statusBarFrame.size.height);
154 | if ([UIDevice currentDevice].systemVersion.floatValue < 7.0) topInset = 0.f;
155 |
156 | if (_filterView1.transitionStyle == LGFilterViewTransitionStyleCenter)
157 | {
158 | _filterView1.offset = CGPointMake(0.f, topInset/2);
159 | _filterView1.contentInset = UIEdgeInsetsZero;
160 | }
161 | else if (_filterView1.transitionStyle == LGFilterViewTransitionStyleTop)
162 | {
163 | _filterView1.contentInset = UIEdgeInsetsMake(topInset, 0.f, 0.f, 0.f);
164 | _filterView1.offset = CGPointZero;
165 | }
166 |
167 | _filterView2.contentInset = _filterView1.contentInset;
168 | _filterView2.offset = _filterView1.offset;
169 | }
170 |
171 | - (void)setupFilterViewsWithTransitionStyle:(LGFilterViewTransitionStyle)style
172 | {
173 | __weak typeof(self) wself = self;
174 |
175 | _filterView1 = [[LGFilterView alloc] initWithTitles:_titlesArray
176 | actionHandler:^(LGFilterView *filterView, NSString *title, NSUInteger index)
177 | {
178 | if (wself)
179 | {
180 | __strong typeof(wself) self = wself;
181 |
182 | [self.titleButton setTitle:title forState:UIControlStateNormal];
183 | self.titleButton.tag = index;
184 | [self.titleButton sizeToFit];
185 | }
186 | }
187 | cancelHandler:nil];
188 | _filterView1.transitionStyle = style;
189 | _filterView1.numberOfLines = 0;
190 |
191 | // -----
192 |
193 | _filterView2 = [[LGFilterView alloc] initWithView:_innerView];
194 | _filterView2.transitionStyle = style;
195 | _filterView2.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.8];
196 | _filterView2.cornerRadius = 15.f;
197 | _filterView2.borderColor = [UIColor colorWithRed:0.f green:0.5 blue:1.f alpha:1.f];
198 | _filterView2.borderWidth = 2.f;
199 | _filterView2.indicatorStyle = UIScrollViewIndicatorStyleWhite;
200 | }
201 |
202 | @end
203 |
--------------------------------------------------------------------------------
/LGFilterView/LGFilterView.h:
--------------------------------------------------------------------------------
1 | //
2 | // LGFilterView.h
3 | // LGFilterView
4 | //
5 | //
6 | // The MIT License (MIT)
7 | //
8 | // Copyright (c) 2015 Grigory Lutkov
9 | // (https://github.com/Friend-LGA/LGFilterView)
10 | //
11 | // Permission is hereby granted, free of charge, to any person obtaining a copy
12 | // of this software and associated documentation files (the "Software"), to deal
13 | // in the Software without restriction, including without limitation the rights
14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 | // copies of the Software, and to permit persons to whom the Software is
16 | // furnished to do so, subject to the following conditions:
17 | //
18 | // The above copyright notice and this permission notice shall be included in all
19 | // copies or substantial portions of the Software.
20 | //
21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 | // SOFTWARE.
28 | //
29 |
30 | #import
31 |
32 | @class LGFilterView;
33 |
34 | static NSString *const kLGFilterViewWillShowNotification = @"LGFilterViewWillShowNotification";
35 | static NSString *const kLGFilterViewWillDismissNotification = @"LGFilterViewWillDismissNotification";
36 | static NSString *const kLGFilterViewDidShowNotification = @"LGFilterViewDidShowNotification";
37 | static NSString *const kLGFilterViewDidDismissNotification = @"LGFilterViewDidDismissNotification";
38 |
39 | static CGFloat const kLGFilterViewWidthMargin = 8.f;
40 | static CGFloat const kLGFilterViewWidth = (320.f-kLGFilterViewWidthMargin*2);
41 |
42 | @protocol LGFilterViewDelegate
43 |
44 | @optional
45 |
46 | - (void)filterViewWillShow:(LGFilterView *)filterView;
47 | - (void)filterViewWillDismiss:(LGFilterView *)filterView;
48 | - (void)filterViewDidShow:(LGFilterView *)filterView;
49 | - (void)filterViewDidDismiss:(LGFilterView *)filterView;
50 | - (void)filterView:(LGFilterView *)filterView buttonPressedWithTitle:(NSString *)title index:(NSUInteger)index;
51 | - (void)filterViewCancelled:(LGFilterView *)filterView;
52 |
53 | @end
54 |
55 | @interface LGFilterView : UIView
56 |
57 | typedef NS_ENUM(NSUInteger, LGFilterViewTransitionStyle)
58 | {
59 | LGFilterViewTransitionStyleTop = 0,
60 | LGFilterViewTransitionStyleCenter = 1
61 | };
62 |
63 | @property (assign, nonatomic) LGFilterViewTransitionStyle transitionStyle;
64 |
65 | @property (assign, nonatomic, getter=isShowing) BOOL showing;
66 |
67 | @property (assign, nonatomic) NSInteger selectedIndex;
68 |
69 | @property (assign, nonatomic) CGPoint offset;
70 | @property (assign, nonatomic) UIEdgeInsets contentInset;
71 | @property (assign, nonatomic) CGFloat heightMax;
72 |
73 | @property (assign, nonatomic, getter=isSeparatorsVisible) BOOL separatorsVisible;
74 | @property (strong, nonatomic) UIColor *separatorsColor;
75 | @property (assign, nonatomic) UIEdgeInsets separatorsEdgeInsets;
76 |
77 | @property (strong, nonatomic) UIColor *titleColor;
78 | @property (strong, nonatomic) UIColor *titleColorHighlighted;
79 | @property (strong, nonatomic) UIColor *titleColorSelected;
80 |
81 | @property (strong, nonatomic) UIColor *backgroundColorHighlighted;
82 | @property (strong, nonatomic) UIColor *backgroundColorSelected;
83 |
84 | @property (strong, nonatomic) UIFont *font;
85 | @property (assign, nonatomic) NSUInteger numberOfLines;
86 | @property (assign, nonatomic) NSLineBreakMode lineBreakMode;
87 | @property (assign, nonatomic) NSTextAlignment textAlignment;
88 | @property (assign, nonatomic) BOOL adjustsFontSizeToFitWidth;
89 | @property (assign, nonatomic) CGFloat minimumScaleFactor;
90 |
91 | @property (assign, nonatomic) CGFloat cornerRadius;
92 | @property (assign, nonatomic) CGFloat borderWidth;
93 | @property (strong, nonatomic) UIColor *borderColor;
94 |
95 | @property (assign, nonatomic) UIScrollViewIndicatorStyle indicatorStyle;
96 |
97 | /** Do not forget about weak referens to self */
98 | @property (strong, nonatomic) void (^willShowHandler)(LGFilterView *filterView);
99 | /** Do not forget about weak referens to self */
100 | @property (strong, nonatomic) void (^willDismissHandler)(LGFilterView *filterView);
101 | /** Do not forget about weak referens to self */
102 | @property (strong, nonatomic) void (^didShowHandler)(LGFilterView *filterView);
103 | /** Do not forget about weak referens to self */
104 | @property (strong, nonatomic) void (^didDismissHandler)(LGFilterView *filterView);
105 |
106 | /** Do not forget about weak referens to self */
107 | @property (strong, nonatomic) void (^actionHandler)(LGFilterView *filterView, NSString *title, NSUInteger index);
108 | /** Do not forget about weak referens to self */
109 | @property (strong, nonatomic) void (^cancelHandler)(LGFilterView *filterView);
110 |
111 | @property (assign, nonatomic) id delegate;
112 |
113 | /** View can not be subclass of UIScrollView */
114 | - (instancetype)initWithView:(UIView *)view;
115 | - (instancetype)initWithTitles:(NSArray *)titles;
116 |
117 | /** View can not be subclass of UIScrollView */
118 | + (instancetype)filterViewWithView:(UIView *)view;
119 | + (instancetype)filterViewWithTitles:(NSArray *)titles;
120 |
121 | #pragma amrk -
122 |
123 | /**
124 | View can not be subclass of UIScrollView
125 | Do not forget about weak referens to self for cancelHandler blocks
126 | */
127 | - (instancetype)initWithView:(UIView *)view
128 | cancelHandler:(void(^)(LGFilterView *filterView))cancelHandler;
129 |
130 | /** Do not forget about weak referens to self for actionHandler and cancelHandler blocks */
131 | - (instancetype)initWithTitles:(NSArray *)titles
132 | actionHandler:(void(^)(LGFilterView *filterView, NSString *title, NSUInteger index))actionHandler
133 | cancelHandler:(void(^)(LGFilterView *filterView))cancelHandler;
134 |
135 | /**
136 | View can not be subclass of UIScrollView
137 | Do not forget about weak referens to self for cancelHandler blocks
138 | */
139 | + (instancetype)filterViewWithView:(UIView *)view
140 | cancelHandler:(void(^)(LGFilterView *filterView))cancelHandler;
141 |
142 | /** Do not forget about weak referens to self for actionHandler and cancelHandler blocks */
143 | + (instancetype)filterViewWithTitles:(NSArray *)titles
144 | actionHandler:(void(^)(LGFilterView *filterView, NSString *title, NSUInteger index))actionHandler
145 | cancelHandler:(void(^)(LGFilterView *filterView))cancelHandler;
146 |
147 | #pragma mark -
148 |
149 | /** View can not be subclass of UIScrollView */
150 | - (instancetype)initWithView:(UIView *)view
151 | delegate:(id)delegate;
152 |
153 | - (instancetype)initWithTitles:(NSArray *)titles
154 | delegate:(id)delegate;
155 |
156 | /** View can not be subclass of UIScrollView */
157 | + (instancetype)filterViewWithView:(UIView *)view
158 | delegate:(id)delegate;
159 |
160 | + (instancetype)filterViewWithTitles:(NSArray *)titles
161 | delegate:(id)delegate;
162 |
163 | #pragma mark -
164 |
165 | /** View can not be subclass of UIScrollView */
166 | - (void)showInView:(UIView *)view animated:(BOOL)animated completionHandler:(void(^)())completionHandler;
167 | - (void)dismissAnimated:(BOOL)animated completionHandler:(void(^)())completionHandler;
168 |
169 | #pragma mark -
170 |
171 | /** Unavailable, use +filterViewWith... instead */
172 | + (instancetype)new __attribute__((unavailable("use +filterViewWith... instead")));
173 | /** Unavailable, use -initWith... instead */
174 | - (instancetype)init __attribute__((unavailable("use -initWith... instead")));
175 | /** Unavailable, use -initWith... instead */
176 | - (instancetype)initWithFrame:(CGRect)frame __attribute__((unavailable("use -initWith... instead")));
177 |
178 | @end
179 |
--------------------------------------------------------------------------------
/Framework/LGFilterViewFramework.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 4A2C41CD1BF4DD6D00D071CD /* LGFilterView.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A2C41C91BF4DD6D00D071CD /* LGFilterView.h */; settings = {ATTRIBUTES = (Public, ); }; };
11 | 4A2C41CE1BF4DD6D00D071CD /* LGFilterView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A2C41CA1BF4DD6D00D071CD /* LGFilterView.m */; };
12 | 4A2C41CF1BF4DD6D00D071CD /* LGFilterViewCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 4A2C41CB1BF4DD6D00D071CD /* LGFilterViewCell.h */; settings = {ATTRIBUTES = (Private, ); }; };
13 | 4A2C41D01BF4DD6D00D071CD /* LGFilterViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A2C41CC1BF4DD6D00D071CD /* LGFilterViewCell.m */; };
14 | 4AF139461BF384430037B073 /* LGFilterViewFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = 4AF139451BF384430037B073 /* LGFilterViewFramework.h */; };
15 | /* End PBXBuildFile section */
16 |
17 | /* Begin PBXFileReference section */
18 | 4A2C41C91BF4DD6D00D071CD /* LGFilterView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LGFilterView.h; sourceTree = ""; };
19 | 4A2C41CA1BF4DD6D00D071CD /* LGFilterView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LGFilterView.m; sourceTree = ""; };
20 | 4A2C41CB1BF4DD6D00D071CD /* LGFilterViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LGFilterViewCell.h; sourceTree = ""; };
21 | 4A2C41CC1BF4DD6D00D071CD /* LGFilterViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LGFilterViewCell.m; sourceTree = ""; };
22 | 4AF139421BF384430037B073 /* LGFilterViewFramework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LGFilterViewFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; };
23 | 4AF139451BF384430037B073 /* LGFilterViewFramework.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LGFilterViewFramework.h; sourceTree = ""; };
24 | 4AF139471BF384430037B073 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
25 | /* End PBXFileReference section */
26 |
27 | /* Begin PBXFrameworksBuildPhase section */
28 | 4AF1393E1BF384430037B073 /* Frameworks */ = {
29 | isa = PBXFrameworksBuildPhase;
30 | buildActionMask = 2147483647;
31 | files = (
32 | );
33 | runOnlyForDeploymentPostprocessing = 0;
34 | };
35 | /* End PBXFrameworksBuildPhase section */
36 |
37 | /* Begin PBXGroup section */
38 | 4A2C41C81BF4DD6D00D071CD /* LGFilterView */ = {
39 | isa = PBXGroup;
40 | children = (
41 | 4A2C41C91BF4DD6D00D071CD /* LGFilterView.h */,
42 | 4A2C41CA1BF4DD6D00D071CD /* LGFilterView.m */,
43 | 4A2C41CB1BF4DD6D00D071CD /* LGFilterViewCell.h */,
44 | 4A2C41CC1BF4DD6D00D071CD /* LGFilterViewCell.m */,
45 | );
46 | name = LGFilterView;
47 | path = ../LGFilterView;
48 | sourceTree = "";
49 | };
50 | 4AF139381BF384430037B073 = {
51 | isa = PBXGroup;
52 | children = (
53 | 4A2C41C81BF4DD6D00D071CD /* LGFilterView */,
54 | 4AF139441BF384430037B073 /* LGFilterViewFramework */,
55 | 4AF139431BF384430037B073 /* Products */,
56 | );
57 | sourceTree = "";
58 | };
59 | 4AF139431BF384430037B073 /* Products */ = {
60 | isa = PBXGroup;
61 | children = (
62 | 4AF139421BF384430037B073 /* LGFilterViewFramework.framework */,
63 | );
64 | name = Products;
65 | sourceTree = "";
66 | };
67 | 4AF139441BF384430037B073 /* LGFilterViewFramework */ = {
68 | isa = PBXGroup;
69 | children = (
70 | 4AF139451BF384430037B073 /* LGFilterViewFramework.h */,
71 | 4AF139471BF384430037B073 /* Info.plist */,
72 | );
73 | path = LGFilterViewFramework;
74 | sourceTree = "";
75 | };
76 | /* End PBXGroup section */
77 |
78 | /* Begin PBXHeadersBuildPhase section */
79 | 4AF1393F1BF384430037B073 /* Headers */ = {
80 | isa = PBXHeadersBuildPhase;
81 | buildActionMask = 2147483647;
82 | files = (
83 | 4A2C41CD1BF4DD6D00D071CD /* LGFilterView.h in Headers */,
84 | 4A2C41CF1BF4DD6D00D071CD /* LGFilterViewCell.h in Headers */,
85 | 4AF139461BF384430037B073 /* LGFilterViewFramework.h in Headers */,
86 | );
87 | runOnlyForDeploymentPostprocessing = 0;
88 | };
89 | /* End PBXHeadersBuildPhase section */
90 |
91 | /* Begin PBXNativeTarget section */
92 | 4AF139411BF384430037B073 /* LGFilterViewFramework */ = {
93 | isa = PBXNativeTarget;
94 | buildConfigurationList = 4AF1394A1BF384430037B073 /* Build configuration list for PBXNativeTarget "LGFilterViewFramework" */;
95 | buildPhases = (
96 | 4AF1393D1BF384430037B073 /* Sources */,
97 | 4AF1393E1BF384430037B073 /* Frameworks */,
98 | 4AF1393F1BF384430037B073 /* Headers */,
99 | 4AF139401BF384430037B073 /* Resources */,
100 | );
101 | buildRules = (
102 | );
103 | dependencies = (
104 | );
105 | name = LGFilterViewFramework;
106 | productName = LGFilterViewFramework;
107 | productReference = 4AF139421BF384430037B073 /* LGFilterViewFramework.framework */;
108 | productType = "com.apple.product-type.framework";
109 | };
110 | /* End PBXNativeTarget section */
111 |
112 | /* Begin PBXProject section */
113 | 4AF139391BF384430037B073 /* Project object */ = {
114 | isa = PBXProject;
115 | attributes = {
116 | LastUpgradeCheck = 0710;
117 | ORGANIZATIONNAME = "Grigory Lutkov";
118 | TargetAttributes = {
119 | 4AF139411BF384430037B073 = {
120 | CreatedOnToolsVersion = 7.1.1;
121 | };
122 | };
123 | };
124 | buildConfigurationList = 4AF1393C1BF384430037B073 /* Build configuration list for PBXProject "LGFilterViewFramework" */;
125 | compatibilityVersion = "Xcode 3.2";
126 | developmentRegion = English;
127 | hasScannedForEncodings = 0;
128 | knownRegions = (
129 | en,
130 | );
131 | mainGroup = 4AF139381BF384430037B073;
132 | productRefGroup = 4AF139431BF384430037B073 /* Products */;
133 | projectDirPath = "";
134 | projectRoot = "";
135 | targets = (
136 | 4AF139411BF384430037B073 /* LGFilterViewFramework */,
137 | );
138 | };
139 | /* End PBXProject section */
140 |
141 | /* Begin PBXResourcesBuildPhase section */
142 | 4AF139401BF384430037B073 /* Resources */ = {
143 | isa = PBXResourcesBuildPhase;
144 | buildActionMask = 2147483647;
145 | files = (
146 | );
147 | runOnlyForDeploymentPostprocessing = 0;
148 | };
149 | /* End PBXResourcesBuildPhase section */
150 |
151 | /* Begin PBXSourcesBuildPhase section */
152 | 4AF1393D1BF384430037B073 /* Sources */ = {
153 | isa = PBXSourcesBuildPhase;
154 | buildActionMask = 2147483647;
155 | files = (
156 | 4A2C41CE1BF4DD6D00D071CD /* LGFilterView.m in Sources */,
157 | 4A2C41D01BF4DD6D00D071CD /* LGFilterViewCell.m in Sources */,
158 | );
159 | runOnlyForDeploymentPostprocessing = 0;
160 | };
161 | /* End PBXSourcesBuildPhase section */
162 |
163 | /* Begin XCBuildConfiguration section */
164 | 4AF139481BF384430037B073 /* Debug */ = {
165 | isa = XCBuildConfiguration;
166 | buildSettings = {
167 | ALWAYS_SEARCH_USER_PATHS = NO;
168 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
169 | CLANG_CXX_LIBRARY = "libc++";
170 | CLANG_ENABLE_MODULES = YES;
171 | CLANG_ENABLE_OBJC_ARC = YES;
172 | CLANG_WARN_BOOL_CONVERSION = YES;
173 | CLANG_WARN_CONSTANT_CONVERSION = YES;
174 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
175 | CLANG_WARN_EMPTY_BODY = YES;
176 | CLANG_WARN_ENUM_CONVERSION = YES;
177 | CLANG_WARN_INT_CONVERSION = YES;
178 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
179 | CLANG_WARN_UNREACHABLE_CODE = YES;
180 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
181 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
182 | COPY_PHASE_STRIP = NO;
183 | CURRENT_PROJECT_VERSION = 1;
184 | DEBUG_INFORMATION_FORMAT = dwarf;
185 | ENABLE_STRICT_OBJC_MSGSEND = YES;
186 | ENABLE_TESTABILITY = YES;
187 | GCC_C_LANGUAGE_STANDARD = gnu99;
188 | GCC_DYNAMIC_NO_PIC = NO;
189 | GCC_NO_COMMON_BLOCKS = YES;
190 | GCC_OPTIMIZATION_LEVEL = 0;
191 | GCC_PREPROCESSOR_DEFINITIONS = (
192 | "DEBUG=1",
193 | "$(inherited)",
194 | );
195 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
196 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
197 | GCC_WARN_UNDECLARED_SELECTOR = YES;
198 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
199 | GCC_WARN_UNUSED_FUNCTION = YES;
200 | GCC_WARN_UNUSED_VARIABLE = YES;
201 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
202 | MTL_ENABLE_DEBUG_INFO = YES;
203 | ONLY_ACTIVE_ARCH = YES;
204 | SDKROOT = iphoneos;
205 | TARGETED_DEVICE_FAMILY = "1,2";
206 | VERSIONING_SYSTEM = "apple-generic";
207 | VERSION_INFO_PREFIX = "";
208 | };
209 | name = Debug;
210 | };
211 | 4AF139491BF384430037B073 /* Release */ = {
212 | isa = XCBuildConfiguration;
213 | buildSettings = {
214 | ALWAYS_SEARCH_USER_PATHS = NO;
215 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
216 | CLANG_CXX_LIBRARY = "libc++";
217 | CLANG_ENABLE_MODULES = YES;
218 | CLANG_ENABLE_OBJC_ARC = YES;
219 | CLANG_WARN_BOOL_CONVERSION = YES;
220 | CLANG_WARN_CONSTANT_CONVERSION = YES;
221 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
222 | CLANG_WARN_EMPTY_BODY = YES;
223 | CLANG_WARN_ENUM_CONVERSION = YES;
224 | CLANG_WARN_INT_CONVERSION = YES;
225 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
226 | CLANG_WARN_UNREACHABLE_CODE = YES;
227 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
228 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
229 | COPY_PHASE_STRIP = NO;
230 | CURRENT_PROJECT_VERSION = 1;
231 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
232 | ENABLE_NS_ASSERTIONS = NO;
233 | ENABLE_STRICT_OBJC_MSGSEND = YES;
234 | GCC_C_LANGUAGE_STANDARD = gnu99;
235 | GCC_NO_COMMON_BLOCKS = YES;
236 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
237 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
238 | GCC_WARN_UNDECLARED_SELECTOR = YES;
239 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
240 | GCC_WARN_UNUSED_FUNCTION = YES;
241 | GCC_WARN_UNUSED_VARIABLE = YES;
242 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
243 | MTL_ENABLE_DEBUG_INFO = NO;
244 | SDKROOT = iphoneos;
245 | TARGETED_DEVICE_FAMILY = "1,2";
246 | VALIDATE_PRODUCT = YES;
247 | VERSIONING_SYSTEM = "apple-generic";
248 | VERSION_INFO_PREFIX = "";
249 | };
250 | name = Release;
251 | };
252 | 4AF1394B1BF384430037B073 /* Debug */ = {
253 | isa = XCBuildConfiguration;
254 | buildSettings = {
255 | CODE_SIGN_IDENTITY = "iPhone Developer";
256 | DEFINES_MODULE = YES;
257 | DYLIB_COMPATIBILITY_VERSION = 1;
258 | DYLIB_CURRENT_VERSION = 1;
259 | DYLIB_INSTALL_NAME_BASE = "@rpath";
260 | INFOPLIST_FILE = LGFilterViewFramework/Info.plist;
261 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
262 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
263 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
264 | PRODUCT_BUNDLE_IDENTIFIER = "com.Friend-LGA.LGFilterViewFramework";
265 | PRODUCT_NAME = "$(TARGET_NAME)";
266 | SKIP_INSTALL = YES;
267 | };
268 | name = Debug;
269 | };
270 | 4AF1394C1BF384430037B073 /* Release */ = {
271 | isa = XCBuildConfiguration;
272 | buildSettings = {
273 | CODE_SIGN_IDENTITY = "iPhone Developer";
274 | DEFINES_MODULE = YES;
275 | DYLIB_COMPATIBILITY_VERSION = 1;
276 | DYLIB_CURRENT_VERSION = 1;
277 | DYLIB_INSTALL_NAME_BASE = "@rpath";
278 | INFOPLIST_FILE = LGFilterViewFramework/Info.plist;
279 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
280 | IPHONEOS_DEPLOYMENT_TARGET = 8.0;
281 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
282 | PRODUCT_BUNDLE_IDENTIFIER = "com.Friend-LGA.LGFilterViewFramework";
283 | PRODUCT_NAME = "$(TARGET_NAME)";
284 | SKIP_INSTALL = YES;
285 | };
286 | name = Release;
287 | };
288 | /* End XCBuildConfiguration section */
289 |
290 | /* Begin XCConfigurationList section */
291 | 4AF1393C1BF384430037B073 /* Build configuration list for PBXProject "LGFilterViewFramework" */ = {
292 | isa = XCConfigurationList;
293 | buildConfigurations = (
294 | 4AF139481BF384430037B073 /* Debug */,
295 | 4AF139491BF384430037B073 /* Release */,
296 | );
297 | defaultConfigurationIsVisible = 0;
298 | defaultConfigurationName = Release;
299 | };
300 | 4AF1394A1BF384430037B073 /* Build configuration list for PBXNativeTarget "LGFilterViewFramework" */ = {
301 | isa = XCConfigurationList;
302 | buildConfigurations = (
303 | 4AF1394B1BF384430037B073 /* Debug */,
304 | 4AF1394C1BF384430037B073 /* Release */,
305 | );
306 | defaultConfigurationIsVisible = 0;
307 | defaultConfigurationName = Release;
308 | };
309 | /* End XCConfigurationList section */
310 | };
311 | rootObject = 4AF139391BF384430037B073 /* Project object */;
312 | }
313 |
--------------------------------------------------------------------------------
/Demo/LGFilterViewDemo.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 4A2C41C61BF4D8CA00D071CD /* LGFilterView.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A2C41C31BF4D8CA00D071CD /* LGFilterView.m */; };
11 | 4A2C41C71BF4D8CA00D071CD /* LGFilterViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A2C41C51BF4D8CA00D071CD /* LGFilterViewCell.m */; };
12 | 4A6355F61AC96C0800F51478 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A6355F51AC96C0800F51478 /* main.m */; };
13 | 4A6355F91AC96C0800F51478 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A6355F81AC96C0800F51478 /* AppDelegate.m */; };
14 | 4A6355FC1AC96C0800F51478 /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A6355FB1AC96C0800F51478 /* ViewController.m */; };
15 | 4A6356011AC96C0800F51478 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4A6356001AC96C0800F51478 /* Images.xcassets */; };
16 | 4A63561B1AC96CF900F51478 /* NavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = 4A63561A1AC96CF900F51478 /* NavigationController.m */; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXFileReference section */
20 | 4A2C41C21BF4D8CA00D071CD /* LGFilterView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LGFilterView.h; sourceTree = ""; };
21 | 4A2C41C31BF4D8CA00D071CD /* LGFilterView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LGFilterView.m; sourceTree = ""; };
22 | 4A2C41C41BF4D8CA00D071CD /* LGFilterViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LGFilterViewCell.h; sourceTree = ""; };
23 | 4A2C41C51BF4D8CA00D071CD /* LGFilterViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LGFilterViewCell.m; sourceTree = ""; };
24 | 4A6355F01AC96C0800F51478 /* LGFilterViewDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = LGFilterViewDemo.app; sourceTree = BUILT_PRODUCTS_DIR; };
25 | 4A6355F41AC96C0800F51478 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
26 | 4A6355F51AC96C0800F51478 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
27 | 4A6355F71AC96C0800F51478 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
28 | 4A6355F81AC96C0800F51478 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
29 | 4A6355FA1AC96C0800F51478 /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; };
30 | 4A6355FB1AC96C0800F51478 /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; };
31 | 4A6356001AC96C0800F51478 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
32 | 4A6356191AC96CF900F51478 /* NavigationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NavigationController.h; sourceTree = ""; };
33 | 4A63561A1AC96CF900F51478 /* NavigationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NavigationController.m; sourceTree = ""; };
34 | /* End PBXFileReference section */
35 |
36 | /* Begin PBXFrameworksBuildPhase section */
37 | 4A6355ED1AC96C0800F51478 /* Frameworks */ = {
38 | isa = PBXFrameworksBuildPhase;
39 | buildActionMask = 2147483647;
40 | files = (
41 | );
42 | runOnlyForDeploymentPostprocessing = 0;
43 | };
44 | /* End PBXFrameworksBuildPhase section */
45 |
46 | /* Begin PBXGroup section */
47 | 13E45E08B4F64F8B8933F5A0 /* Frameworks */ = {
48 | isa = PBXGroup;
49 | children = (
50 | );
51 | name = Frameworks;
52 | sourceTree = "";
53 | };
54 | 4A2C41C11BF4D8CA00D071CD /* LGFilterView */ = {
55 | isa = PBXGroup;
56 | children = (
57 | 4A2C41C21BF4D8CA00D071CD /* LGFilterView.h */,
58 | 4A2C41C31BF4D8CA00D071CD /* LGFilterView.m */,
59 | 4A2C41C41BF4D8CA00D071CD /* LGFilterViewCell.h */,
60 | 4A2C41C51BF4D8CA00D071CD /* LGFilterViewCell.m */,
61 | );
62 | name = LGFilterView;
63 | path = ../LGFilterView;
64 | sourceTree = "";
65 | };
66 | 4A6355E71AC96C0800F51478 = {
67 | isa = PBXGroup;
68 | children = (
69 | 4A2C41C11BF4D8CA00D071CD /* LGFilterView */,
70 | 4A6355F21AC96C0800F51478 /* LGFilterViewDemo */,
71 | 4A6355F11AC96C0800F51478 /* Products */,
72 | 13E45E08B4F64F8B8933F5A0 /* Frameworks */,
73 | );
74 | sourceTree = "";
75 | };
76 | 4A6355F11AC96C0800F51478 /* Products */ = {
77 | isa = PBXGroup;
78 | children = (
79 | 4A6355F01AC96C0800F51478 /* LGFilterViewDemo.app */,
80 | );
81 | name = Products;
82 | sourceTree = "";
83 | };
84 | 4A6355F21AC96C0800F51478 /* LGFilterViewDemo */ = {
85 | isa = PBXGroup;
86 | children = (
87 | 4A6355F71AC96C0800F51478 /* AppDelegate.h */,
88 | 4A6355F81AC96C0800F51478 /* AppDelegate.m */,
89 | 4A6356191AC96CF900F51478 /* NavigationController.h */,
90 | 4A63561A1AC96CF900F51478 /* NavigationController.m */,
91 | 4A6355FA1AC96C0800F51478 /* ViewController.h */,
92 | 4A6355FB1AC96C0800F51478 /* ViewController.m */,
93 | 4A6356001AC96C0800F51478 /* Images.xcassets */,
94 | 4A6355F31AC96C0800F51478 /* Supporting Files */,
95 | );
96 | path = LGFilterViewDemo;
97 | sourceTree = "";
98 | };
99 | 4A6355F31AC96C0800F51478 /* Supporting Files */ = {
100 | isa = PBXGroup;
101 | children = (
102 | 4A6355F41AC96C0800F51478 /* Info.plist */,
103 | 4A6355F51AC96C0800F51478 /* main.m */,
104 | );
105 | name = "Supporting Files";
106 | sourceTree = "";
107 | };
108 | /* End PBXGroup section */
109 |
110 | /* Begin PBXNativeTarget section */
111 | 4A6355EF1AC96C0800F51478 /* LGFilterViewDemo */ = {
112 | isa = PBXNativeTarget;
113 | buildConfigurationList = 4A6356131AC96C0800F51478 /* Build configuration list for PBXNativeTarget "LGFilterViewDemo" */;
114 | buildPhases = (
115 | 4A6355EC1AC96C0800F51478 /* Sources */,
116 | 4A6355ED1AC96C0800F51478 /* Frameworks */,
117 | 4A6355EE1AC96C0800F51478 /* Resources */,
118 | );
119 | buildRules = (
120 | );
121 | dependencies = (
122 | );
123 | name = LGFilterViewDemo;
124 | productName = LGFilterViewDemo;
125 | productReference = 4A6355F01AC96C0800F51478 /* LGFilterViewDemo.app */;
126 | productType = "com.apple.product-type.application";
127 | };
128 | /* End PBXNativeTarget section */
129 |
130 | /* Begin PBXProject section */
131 | 4A6355E81AC96C0800F51478 /* Project object */ = {
132 | isa = PBXProject;
133 | attributes = {
134 | LastUpgradeCheck = 0710;
135 | ORGANIZATIONNAME = "Grigory Lutkov";
136 | TargetAttributes = {
137 | 4A6355EF1AC96C0800F51478 = {
138 | CreatedOnToolsVersion = 6.2;
139 | };
140 | };
141 | };
142 | buildConfigurationList = 4A6355EB1AC96C0800F51478 /* Build configuration list for PBXProject "LGFilterViewDemo" */;
143 | compatibilityVersion = "Xcode 3.2";
144 | developmentRegion = English;
145 | hasScannedForEncodings = 0;
146 | knownRegions = (
147 | en,
148 | Base,
149 | );
150 | mainGroup = 4A6355E71AC96C0800F51478;
151 | productRefGroup = 4A6355F11AC96C0800F51478 /* Products */;
152 | projectDirPath = "";
153 | projectRoot = "";
154 | targets = (
155 | 4A6355EF1AC96C0800F51478 /* LGFilterViewDemo */,
156 | );
157 | };
158 | /* End PBXProject section */
159 |
160 | /* Begin PBXResourcesBuildPhase section */
161 | 4A6355EE1AC96C0800F51478 /* Resources */ = {
162 | isa = PBXResourcesBuildPhase;
163 | buildActionMask = 2147483647;
164 | files = (
165 | 4A6356011AC96C0800F51478 /* Images.xcassets in Resources */,
166 | );
167 | runOnlyForDeploymentPostprocessing = 0;
168 | };
169 | /* End PBXResourcesBuildPhase section */
170 |
171 | /* Begin PBXSourcesBuildPhase section */
172 | 4A6355EC1AC96C0800F51478 /* Sources */ = {
173 | isa = PBXSourcesBuildPhase;
174 | buildActionMask = 2147483647;
175 | files = (
176 | 4A6355FC1AC96C0800F51478 /* ViewController.m in Sources */,
177 | 4A2C41C71BF4D8CA00D071CD /* LGFilterViewCell.m in Sources */,
178 | 4A2C41C61BF4D8CA00D071CD /* LGFilterView.m in Sources */,
179 | 4A63561B1AC96CF900F51478 /* NavigationController.m in Sources */,
180 | 4A6355F91AC96C0800F51478 /* AppDelegate.m in Sources */,
181 | 4A6355F61AC96C0800F51478 /* main.m in Sources */,
182 | );
183 | runOnlyForDeploymentPostprocessing = 0;
184 | };
185 | /* End PBXSourcesBuildPhase section */
186 |
187 | /* Begin XCBuildConfiguration section */
188 | 4A6356111AC96C0800F51478 /* Debug */ = {
189 | isa = XCBuildConfiguration;
190 | buildSettings = {
191 | ALWAYS_SEARCH_USER_PATHS = NO;
192 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
193 | CLANG_CXX_LIBRARY = "libc++";
194 | CLANG_ENABLE_MODULES = YES;
195 | CLANG_ENABLE_OBJC_ARC = YES;
196 | CLANG_WARN_BOOL_CONVERSION = YES;
197 | CLANG_WARN_CONSTANT_CONVERSION = YES;
198 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
199 | CLANG_WARN_EMPTY_BODY = YES;
200 | CLANG_WARN_ENUM_CONVERSION = YES;
201 | CLANG_WARN_INT_CONVERSION = YES;
202 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
203 | CLANG_WARN_UNREACHABLE_CODE = YES;
204 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
205 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
206 | COPY_PHASE_STRIP = NO;
207 | ENABLE_STRICT_OBJC_MSGSEND = YES;
208 | ENABLE_TESTABILITY = YES;
209 | GCC_C_LANGUAGE_STANDARD = gnu99;
210 | GCC_DYNAMIC_NO_PIC = NO;
211 | GCC_OPTIMIZATION_LEVEL = 0;
212 | GCC_PREPROCESSOR_DEFINITIONS = (
213 | "DEBUG=1",
214 | "$(inherited)",
215 | );
216 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
217 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
218 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
219 | GCC_WARN_UNDECLARED_SELECTOR = YES;
220 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
221 | GCC_WARN_UNUSED_FUNCTION = YES;
222 | GCC_WARN_UNUSED_VARIABLE = YES;
223 | IPHONEOS_DEPLOYMENT_TARGET = 6.0;
224 | MTL_ENABLE_DEBUG_INFO = YES;
225 | ONLY_ACTIVE_ARCH = YES;
226 | SDKROOT = iphoneos;
227 | TARGETED_DEVICE_FAMILY = "1,2";
228 | };
229 | name = Debug;
230 | };
231 | 4A6356121AC96C0800F51478 /* Release */ = {
232 | isa = XCBuildConfiguration;
233 | buildSettings = {
234 | ALWAYS_SEARCH_USER_PATHS = NO;
235 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
236 | CLANG_CXX_LIBRARY = "libc++";
237 | CLANG_ENABLE_MODULES = YES;
238 | CLANG_ENABLE_OBJC_ARC = YES;
239 | CLANG_WARN_BOOL_CONVERSION = YES;
240 | CLANG_WARN_CONSTANT_CONVERSION = YES;
241 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
242 | CLANG_WARN_EMPTY_BODY = YES;
243 | CLANG_WARN_ENUM_CONVERSION = YES;
244 | CLANG_WARN_INT_CONVERSION = YES;
245 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
246 | CLANG_WARN_UNREACHABLE_CODE = YES;
247 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
248 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
249 | COPY_PHASE_STRIP = NO;
250 | ENABLE_NS_ASSERTIONS = NO;
251 | ENABLE_STRICT_OBJC_MSGSEND = YES;
252 | GCC_C_LANGUAGE_STANDARD = gnu99;
253 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
254 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
255 | GCC_WARN_UNDECLARED_SELECTOR = YES;
256 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
257 | GCC_WARN_UNUSED_FUNCTION = YES;
258 | GCC_WARN_UNUSED_VARIABLE = YES;
259 | IPHONEOS_DEPLOYMENT_TARGET = 6.0;
260 | MTL_ENABLE_DEBUG_INFO = NO;
261 | SDKROOT = iphoneos;
262 | TARGETED_DEVICE_FAMILY = "1,2";
263 | VALIDATE_PRODUCT = YES;
264 | };
265 | name = Release;
266 | };
267 | 4A6356141AC96C0800F51478 /* Debug */ = {
268 | isa = XCBuildConfiguration;
269 | buildSettings = {
270 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
271 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
272 | INFOPLIST_FILE = LGFilterViewDemo/Info.plist;
273 | IPHONEOS_DEPLOYMENT_TARGET = 6.0;
274 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
275 | PRODUCT_BUNDLE_IDENTIFIER = "com.test.$(PRODUCT_NAME)";
276 | PRODUCT_NAME = "$(TARGET_NAME)";
277 | };
278 | name = Debug;
279 | };
280 | 4A6356151AC96C0800F51478 /* Release */ = {
281 | isa = XCBuildConfiguration;
282 | buildSettings = {
283 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
284 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
285 | INFOPLIST_FILE = LGFilterViewDemo/Info.plist;
286 | IPHONEOS_DEPLOYMENT_TARGET = 6.0;
287 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
288 | PRODUCT_BUNDLE_IDENTIFIER = "com.test.$(PRODUCT_NAME)";
289 | PRODUCT_NAME = "$(TARGET_NAME)";
290 | };
291 | name = Release;
292 | };
293 | /* End XCBuildConfiguration section */
294 |
295 | /* Begin XCConfigurationList section */
296 | 4A6355EB1AC96C0800F51478 /* Build configuration list for PBXProject "LGFilterViewDemo" */ = {
297 | isa = XCConfigurationList;
298 | buildConfigurations = (
299 | 4A6356111AC96C0800F51478 /* Debug */,
300 | 4A6356121AC96C0800F51478 /* Release */,
301 | );
302 | defaultConfigurationIsVisible = 0;
303 | defaultConfigurationName = Release;
304 | };
305 | 4A6356131AC96C0800F51478 /* Build configuration list for PBXNativeTarget "LGFilterViewDemo" */ = {
306 | isa = XCConfigurationList;
307 | buildConfigurations = (
308 | 4A6356141AC96C0800F51478 /* Debug */,
309 | 4A6356151AC96C0800F51478 /* Release */,
310 | );
311 | defaultConfigurationIsVisible = 0;
312 | defaultConfigurationName = Release;
313 | };
314 | /* End XCConfigurationList section */
315 | };
316 | rootObject = 4A6355E81AC96C0800F51478 /* Project object */;
317 | }
318 |
--------------------------------------------------------------------------------
/LGFilterView/LGFilterView.m:
--------------------------------------------------------------------------------
1 | //
2 | // LGFilterView.m
3 | // LGFilterView
4 | //
5 | //
6 | // The MIT License (MIT)
7 | //
8 | // Copyright (c) 2015 Grigory Lutkov
9 | // (https://github.com/Friend-LGA/LGFilterView)
10 | //
11 | // Permission is hereby granted, free of charge, to any person obtaining a copy
12 | // of this software and associated documentation files (the "Software"), to deal
13 | // in the Software without restriction, including without limitation the rights
14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 | // copies of the Software, and to permit persons to whom the Software is
16 | // furnished to do so, subject to the following conditions:
17 | //
18 | // The above copyright notice and this permission notice shall be included in all
19 | // copies or substantial portions of the Software.
20 | //
21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 | // SOFTWARE.
28 | //
29 |
30 | #import "LGFilterView.h"
31 | #import "LGFilterViewCell.h"
32 |
33 | static CGFloat const kLGFilterViewInnerMarginW = 10.f;
34 | static CGFloat const kLGFilterViewInnerMarginH = 5.f;
35 |
36 | @interface LGFilterView ()
37 |
38 | @property (assign, nonatomic, getter=isObserversAdded) BOOL observersAdded;
39 |
40 | @property (assign, nonatomic) UIView *parentView;
41 | @property (strong, nonatomic) UIView *backgroundView;
42 |
43 | @property (strong, nonatomic) UITableView *tableView;
44 | @property (strong, nonatomic) UIScrollView *scrollView;
45 |
46 | @property (strong, nonatomic) NSArray *titles;
47 | @property (strong, nonatomic) UIView *innerView;
48 |
49 | @property (strong, nonatomic) UIColor *backgroundColorNormal;
50 |
51 | @end
52 |
53 | @implementation LGFilterView
54 |
55 | - (instancetype)initWithView:(UIView *)view
56 | {
57 | self = [super init];
58 | if (self)
59 | {
60 | if ([view isKindOfClass:[UIScrollView class]])
61 | NSLog(@"LGFilterView: WARNING !!! view can not be subclass of UIScrollView !!!");
62 |
63 | // -----
64 |
65 | _innerView = view;
66 |
67 | [self setupDefaults];
68 | }
69 | return self;
70 | }
71 |
72 | - (instancetype)initWithTitles:(NSArray *)titles
73 | {
74 | self = [super init];
75 | if (self)
76 | {
77 | _titles = titles;
78 |
79 | [self setupDefaults];
80 | }
81 | return self;
82 | }
83 |
84 | + (instancetype)filterViewWithView:(UIView *)view
85 | {
86 | return [[self alloc] initWithView:view];
87 | }
88 |
89 | + (instancetype)filterViewWithTitles:(NSArray *)titles
90 | {
91 | return [[self alloc] initWithTitles:titles];
92 | }
93 |
94 | #pragma mark -
95 |
96 | - (instancetype)initWithView:(UIView *)view
97 | cancelHandler:(void(^)(LGFilterView *filterView))cancelHandler
98 | {
99 | self = [self initWithView:view];
100 | if (self)
101 | {
102 | _cancelHandler = cancelHandler;
103 | }
104 | return self;
105 | }
106 |
107 | - (instancetype)initWithTitles:(NSArray *)titles
108 | actionHandler:(void(^)(LGFilterView *filterView, NSString *title, NSUInteger index))actionHandler
109 | cancelHandler:(void(^)(LGFilterView *filterView))cancelHandler
110 | {
111 | self = [self initWithTitles:titles];
112 | if (self)
113 | {
114 | _actionHandler = actionHandler;
115 | _cancelHandler = cancelHandler;
116 | }
117 | return self;
118 | }
119 |
120 | + (instancetype)filterViewWithView:(UIView *)view
121 | cancelHandler:(void(^)(LGFilterView *filterView))cancelHandler
122 | {
123 | return [[self alloc] initWithView:view
124 | cancelHandler:cancelHandler];
125 | }
126 |
127 | + (instancetype)filterViewWithTitles:(NSArray *)titles
128 | actionHandler:(void(^)(LGFilterView *filterView, NSString *title, NSUInteger index))actionHandler
129 | cancelHandler:(void(^)(LGFilterView *filterView))cancelHandler
130 | {
131 | return [[self alloc] initWithTitles:titles
132 | actionHandler:actionHandler
133 | cancelHandler:cancelHandler];
134 | }
135 |
136 | #pragma mark -
137 |
138 | - (instancetype)initWithView:(UIView *)view
139 | delegate:(id)delegate
140 | {
141 | self = [self initWithView:view];
142 | if (self)
143 | {
144 | _delegate = delegate;
145 | }
146 | return self;
147 | }
148 |
149 | - (instancetype)initWithTitles:(NSArray *)titles
150 | delegate:(id)delegate
151 | {
152 | self = [self initWithTitles:titles];
153 | if (self)
154 | {
155 | _delegate = delegate;
156 | }
157 | return self;
158 | }
159 |
160 | + (instancetype)filterViewWithView:(UIView *)view
161 | delegate:(id)delegate
162 | {
163 | return [[self alloc] initWithView:view
164 | delegate:delegate];
165 | }
166 |
167 | + (instancetype)filterViewWithTitles:(NSArray *)titles
168 | delegate:(id)delegate
169 | {
170 | return [[self alloc] initWithTitles:titles
171 | delegate:delegate];
172 | }
173 |
174 | - (void)setupDefaults
175 | {
176 | _transitionStyle = (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone ? LGFilterViewTransitionStyleTop : LGFilterViewTransitionStyleCenter);
177 |
178 | _selectedIndex = -1;
179 |
180 | _separatorsVisible = YES;
181 | _separatorsColor = [UIColor colorWithRed:0.85 green:0.85 blue:0.85 alpha:1.f];
182 | _separatorsEdgeInsets = UIEdgeInsetsMake(0.f, 10.f, 0.f, 10.f);
183 |
184 | _titleColor = [UIColor colorWithRed:0.f green:0.5 blue:1.f alpha:1.f];
185 | _titleColorHighlighted = [UIColor colorWithRed:0.f green:0.5 blue:1.f alpha:1.f];
186 | _titleColorSelected = [UIColor whiteColor];
187 |
188 | self.backgroundColor = [UIColor whiteColor];
189 | _backgroundColorHighlighted = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1.f];
190 | _backgroundColorSelected = [UIColor colorWithRed:0.f green:0.5 blue:1.f alpha:1.f];
191 |
192 | _font = [UIFont systemFontOfSize:20.f];
193 | _numberOfLines = 1;
194 | _lineBreakMode = NSLineBreakByTruncatingMiddle;
195 | _textAlignment = NSTextAlignmentCenter;
196 | _adjustsFontSizeToFitWidth = YES;
197 | _minimumScaleFactor = 14.f/20.f;
198 |
199 | _cornerRadius = 5.f;
200 | _borderColor = nil;
201 | _borderWidth = 0.f;
202 |
203 | _indicatorStyle = UIScrollViewIndicatorStyleBlack;
204 |
205 | // -----
206 |
207 | _backgroundView = [UIView new];
208 | _backgroundView.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0.5];
209 | _backgroundView.alpha = 0.f;
210 | [self addSubview:_backgroundView];
211 |
212 | // -----
213 |
214 | UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(cancelAction)];
215 | tapGesture.delegate = self;
216 | [_backgroundView addGestureRecognizer:tapGesture];
217 | }
218 |
219 | #pragma mark - Dealloc
220 |
221 | - (void)dealloc
222 | {
223 | #if DEBUG
224 | NSLog(@"%s [Line %d]", __PRETTY_FUNCTION__, __LINE__);
225 | #endif
226 | }
227 |
228 | #pragma mark -
229 |
230 | - (void)willMoveToSuperview:(UIView *)newSuperview
231 | {
232 | [super willMoveToSuperview:newSuperview];
233 |
234 | if (!newSuperview)
235 | [self removeObservers];
236 | else
237 | [self addObservers];
238 | }
239 |
240 | #pragma mark - Setters and Getters
241 |
242 | - (void)setBackgroundColor:(UIColor *)backgroundColor
243 | {
244 | [super setBackgroundColor:[UIColor clearColor]];
245 |
246 | _backgroundColorNormal = backgroundColor;
247 |
248 | if (_tableView)
249 | _tableView.backgroundColor = backgroundColor;
250 | else if (_scrollView)
251 | _scrollView.backgroundColor = backgroundColor;
252 | }
253 |
254 | - (void)setContentInset:(UIEdgeInsets)contentInset
255 | {
256 | if (!UIEdgeInsetsEqualToEdgeInsets(_contentInset, contentInset))
257 | {
258 | _contentInset = contentInset;
259 |
260 | [self layoutInvalidate];
261 | }
262 | }
263 |
264 | - (void)setOffset:(CGPoint)offset
265 | {
266 | if (!CGPointEqualToPoint(_offset, offset))
267 | {
268 | _offset = offset;
269 |
270 | [self layoutInvalidate];
271 | }
272 | }
273 |
274 | #pragma mark -
275 |
276 | - (void)showInView:(UIView *)view
277 | animated:(BOOL)animated
278 | completionHandler:(void(^)())completionHandler;
279 | {
280 | if (self.isShowing) return;
281 |
282 | _parentView = view;
283 |
284 | [self subviewsInvalidate];
285 | [self layoutInvalidate];
286 |
287 | _showing = YES;
288 |
289 | // -----
290 |
291 | [[NSNotificationCenter defaultCenter] postNotificationName:kLGFilterViewWillShowNotification object:self userInfo:nil];
292 |
293 | if (_willShowHandler) _willShowHandler(self);
294 |
295 | if (_delegate && [_delegate respondsToSelector:@selector(filterViewWillShow:)])
296 | [_delegate filterViewWillShow:self];
297 |
298 | // -----
299 |
300 | if (animated)
301 | {
302 | [self getParametersFromPresentation];
303 |
304 | [LGFilterView animateStandardWithAnimations:^(void)
305 | {
306 | [self showAnimations];
307 | }
308 | completion:^(BOOL finished)
309 | {
310 | if (finished)
311 | {
312 | [self showComplete];
313 |
314 | if (completionHandler) completionHandler();
315 | }
316 | }];
317 |
318 | }
319 | else
320 | {
321 | [self showAnimations];
322 |
323 | [self showComplete];
324 |
325 | if (completionHandler) completionHandler();
326 | }
327 | }
328 |
329 | - (void)showAnimations
330 | {
331 | UIScrollView *scrollView = nil;
332 |
333 | if (_tableView)
334 | scrollView = _tableView;
335 | else if (_scrollView)
336 | scrollView = _scrollView;
337 |
338 | // -----
339 |
340 | _backgroundView.alpha = 1.f;
341 |
342 | if (_transitionStyle == LGFilterViewTransitionStyleCenter)
343 | {
344 | scrollView.transform = CGAffineTransformIdentity;
345 | scrollView.alpha = 1.f;
346 | }
347 | else scrollView.center = CGPointMake(scrollView.center.x, scrollView.frame.size.height/2);
348 | }
349 |
350 | - (void)showComplete
351 | {
352 | [[NSNotificationCenter defaultCenter] postNotificationName:kLGFilterViewDidShowNotification object:self userInfo:nil];
353 |
354 | if (_didShowHandler) _didShowHandler(self);
355 |
356 | if (_delegate && [_delegate respondsToSelector:@selector(filterViewDidShow:)])
357 | [_delegate filterViewDidShow:self];
358 | }
359 |
360 | #pragma mark -
361 |
362 | - (void)dismissAnimated:(BOOL)animated
363 | completionHandler:(void(^)())completionHandler
364 | {
365 | if (!self.isShowing) return;
366 |
367 | _showing = NO;
368 |
369 | [[NSNotificationCenter defaultCenter] postNotificationName:kLGFilterViewWillDismissNotification object:self userInfo:nil];
370 |
371 | if (_willDismissHandler) _willDismissHandler(self);
372 |
373 | if (_delegate && [_delegate respondsToSelector:@selector(filterViewWillDismiss:)])
374 | [_delegate filterViewWillDismiss:self];
375 |
376 | // -----
377 |
378 | if (animated)
379 | {
380 | [self getParametersFromPresentation];
381 |
382 | [LGFilterView animateStandardWithAnimations:^(void)
383 | {
384 | [self dismissAnimations];
385 | }
386 | completion:^(BOOL finished)
387 | {
388 | if (finished)
389 | {
390 | [self dismissComplete];
391 |
392 | if (completionHandler) completionHandler();
393 | }
394 | }];
395 | }
396 | else
397 | {
398 | [self dismissAnimations];
399 |
400 | [self dismissComplete];
401 |
402 | if (completionHandler) completionHandler();
403 | }
404 | }
405 |
406 | - (void)dismissAnimations
407 | {
408 | UIScrollView *scrollView = nil;
409 |
410 | if (_tableView)
411 | scrollView = _tableView;
412 | else if (_scrollView)
413 | scrollView = _scrollView;
414 |
415 | // -----
416 |
417 | _backgroundView.alpha = 0.f;
418 |
419 | if (_transitionStyle == LGFilterViewTransitionStyleCenter)
420 | {
421 | scrollView.transform = CGAffineTransformMakeScale(0.9, 0.9);
422 | scrollView.alpha = 0.f;
423 | }
424 | else scrollView.center = CGPointMake(scrollView.center.x, -scrollView.frame.size.height/2);
425 | }
426 |
427 | - (void)dismissComplete
428 | {
429 | [self removeFromSuperview];
430 |
431 | // -----
432 |
433 | [[NSNotificationCenter defaultCenter] postNotificationName:kLGFilterViewDidDismissNotification object:self userInfo:nil];
434 |
435 | if (_didDismissHandler) _didDismissHandler(self);
436 |
437 | if (_delegate && [_delegate respondsToSelector:@selector(filterViewDidDismiss:)])
438 | [_delegate filterViewDidDismiss:self];
439 | }
440 |
441 | #pragma mark - Table View Data Source
442 |
443 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
444 | {
445 | return 1;
446 | }
447 |
448 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
449 | {
450 | return _titles.count;
451 | }
452 |
453 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
454 | {
455 | LGFilterViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
456 |
457 | cell.title = _titles[indexPath.row];
458 | cell.titleColor = _titleColor;
459 | cell.titleColorHighlighted = _titleColorHighlighted;
460 | cell.titleColorSelected = _titleColorSelected;
461 | cell.backgroundColorHighlighted = _backgroundColorHighlighted;
462 | cell.backgroundColorSelected = _backgroundColorSelected;
463 | cell.separatorVisible = (self.isSeparatorsVisible && indexPath.row != _titles.count-1);
464 | cell.separatorColor = _separatorsColor;
465 | cell.separatorEdgeInsets = _separatorsEdgeInsets;
466 | cell.textAlignment = _textAlignment;
467 | cell.font = _font;
468 | cell.numberOfLines = _numberOfLines;
469 | cell.lineBreakMode = _lineBreakMode;
470 | cell.adjustsFontSizeToFitWidth = _adjustsFontSizeToFitWidth;
471 | cell.minimumScaleFactor = _minimumScaleFactor;
472 |
473 | return cell;
474 | }
475 |
476 | #pragma mark - Table View Delegate
477 |
478 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
479 | {
480 | if (_numberOfLines == 0)
481 | {
482 | NSString *title = _titles[indexPath.row];
483 |
484 | UILabel *label = [UILabel new];
485 | label.text = title;
486 | label.textAlignment = _textAlignment;
487 | label.font = _font;
488 | label.numberOfLines = _numberOfLines;
489 | label.lineBreakMode = _lineBreakMode;
490 | label.adjustsFontSizeToFitWidth = _adjustsFontSizeToFitWidth;
491 | label.minimumScaleFactor = _minimumScaleFactor;
492 |
493 | CGSize size = [label sizeThatFits:CGSizeMake(tableView.frame.size.width-kLGFilterViewInnerMarginW*2, CGFLOAT_MAX)];
494 |
495 | size.height += kLGFilterViewInnerMarginH*2;
496 |
497 | if (size.height < 44.f)
498 | size.height = 44.f;
499 |
500 | return size.height;
501 | }
502 | else return 44.f;
503 | }
504 |
505 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
506 | {
507 | if (indexPath.row == _selectedIndex)
508 | {
509 | [self cancelAction];
510 | }
511 | else
512 | {
513 | [self dismissAnimated:YES completionHandler:nil];
514 |
515 | _selectedIndex = indexPath.row;
516 |
517 | NSString *title = _titles[indexPath.row];
518 | NSUInteger index = indexPath.row;
519 |
520 | if (_actionHandler) _actionHandler(self, title, index);
521 |
522 | if (_delegate && [_delegate respondsToSelector:@selector(filterView:buttonPressedWithTitle:index:)])
523 | [_delegate filterView:self buttonPressedWithTitle:title index:index];
524 | }
525 | }
526 |
527 | #pragma mark -
528 |
529 | - (void)subviewsInvalidate
530 | {
531 | if (_titles.count)
532 | {
533 | if (!_tableView)
534 | {
535 | _tableView = [UITableView new];
536 | _tableView.dataSource = self;
537 | _tableView.delegate = self;
538 | _tableView.alwaysBounceVertical = NO;
539 | _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
540 | [_tableView registerClass:[LGFilterViewCell class] forCellReuseIdentifier:@"cell"];
541 | [self addSubview:_tableView];
542 | }
543 |
544 | _tableView.backgroundColor = _backgroundColorNormal;
545 | _tableView.indicatorStyle = _indicatorStyle;
546 |
547 | if (_transitionStyle == LGFilterViewTransitionStyleCenter)
548 | {
549 | _tableView.layer.masksToBounds = YES;
550 | _tableView.layer.cornerRadius = _cornerRadius;
551 | _tableView.layer.borderColor = _borderColor.CGColor;
552 | _tableView.layer.borderWidth = _borderWidth;
553 | }
554 |
555 | [_tableView reloadData];
556 | }
557 | else if (_innerView)
558 | {
559 | if (!_scrollView)
560 | {
561 | _scrollView = [UIScrollView new];
562 | _scrollView.alwaysBounceVertical = NO;
563 | [_scrollView addSubview:_innerView];
564 | [self addSubview:_scrollView];
565 | }
566 |
567 | _scrollView.backgroundColor = _backgroundColorNormal;
568 | _scrollView.indicatorStyle = _indicatorStyle;
569 |
570 | if (_transitionStyle == LGFilterViewTransitionStyleCenter)
571 | {
572 | _scrollView.layer.masksToBounds = YES;
573 | _scrollView.layer.cornerRadius = _cornerRadius;
574 | _scrollView.layer.borderColor = _borderColor.CGColor;
575 | _scrollView.layer.borderWidth = _borderWidth;
576 | }
577 | }
578 |
579 | if (!self.superview)
580 | [_parentView addSubview:self];
581 | }
582 |
583 | - (void)layoutInvalidate
584 | {
585 | self.frame = CGRectMake(0.f, 0.f, _parentView.frame.size.width, _parentView.frame.size.height);
586 | _backgroundView.frame = CGRectMake(0.f, 0.f, self.frame.size.width, self.frame.size.height);
587 |
588 | // -----
589 |
590 | UIScrollView *scrollView = nil;
591 |
592 | if (_tableView)
593 | scrollView = _tableView;
594 | else if (_scrollView)
595 | scrollView = _scrollView;
596 |
597 | scrollView.contentInset = _contentInset;
598 | scrollView.scrollIndicatorInsets = _contentInset;
599 |
600 | if (_transitionStyle == LGFilterViewTransitionStyleCenter)
601 | {
602 | scrollView.transform = CGAffineTransformIdentity;
603 | scrollView.alpha = 1.f;
604 | }
605 |
606 | // -----
607 |
608 | CGFloat scrollViewHeight = _contentInset.top+_contentInset.bottom;
609 |
610 | if (_tableView)
611 | scrollViewHeight += _tableView.contentSize.height;
612 | else if (_scrollView)
613 | scrollViewHeight += _innerView.frame.size.height;
614 |
615 | if (_parentView.frame.size.height < scrollViewHeight)
616 | scrollViewHeight = _parentView.frame.size.height;
617 |
618 | if (_heightMax)
619 | {
620 | if (_heightMax < scrollViewHeight)
621 | scrollViewHeight = _heightMax;
622 | }
623 | else
624 | {
625 | if (_parentView.frame.size.height*0.5 < scrollViewHeight)
626 | scrollViewHeight = _parentView.frame.size.height*0.5;
627 | }
628 |
629 | // -----
630 |
631 | CGRect scrollViewFrame = CGRectZero;
632 |
633 | if (_transitionStyle == LGFilterViewTransitionStyleCenter)
634 | scrollViewFrame = CGRectMake(_parentView.frame.size.width/2-kLGFilterViewWidth/2,
635 | _parentView.frame.size.height/2-scrollViewHeight/2+_offset.y,
636 | kLGFilterViewWidth,
637 | scrollViewHeight);
638 | else
639 | scrollViewFrame = CGRectMake(0.f, 0.f, self.frame.size.width, scrollViewHeight);
640 |
641 | if ([UIScreen mainScreen].scale == 1.f)
642 | scrollViewFrame = CGRectIntegral(scrollViewFrame);
643 |
644 | // -----
645 |
646 | if (!self.isShowing && _transitionStyle == LGFilterViewTransitionStyleTop)
647 | scrollViewFrame.origin.y -= scrollViewFrame.size.height;
648 |
649 | scrollView.frame = scrollViewFrame;
650 |
651 | // -----
652 |
653 | if (_tableView)
654 | {
655 | if (_selectedIndex >= 0)
656 | {
657 | if (_transitionStyle == LGFilterViewTransitionStyleCenter)
658 | [_tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:_selectedIndex inSection:0] animated:NO scrollPosition:UITableViewScrollPositionMiddle];
659 | else
660 | {
661 | [_tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:_selectedIndex inSection:0] animated:NO scrollPosition:UITableViewScrollPositionNone];
662 |
663 | CGRect rect = [_tableView rectForRowAtIndexPath:[NSIndexPath indexPathForRow:_selectedIndex inSection:0]];
664 |
665 | CGFloat offsetY = rect.origin.y+rect.size.height/2-_tableView.frame.size.height/2-_tableView.contentInset.top/2;
666 | if (offsetY < -_tableView.contentInset.top)
667 | offsetY = -_tableView.contentInset.top;
668 | else if (offsetY > _tableView.contentSize.height-_tableView.frame.size.height)
669 | offsetY = _tableView.contentSize.height-_tableView.frame.size.height;
670 |
671 | _tableView.contentOffset = CGPointMake(_tableView.contentOffset.x, offsetY);
672 | }
673 | }
674 | else _tableView.contentOffset = CGPointMake(_tableView.contentOffset.x, -_tableView.contentInset.top);
675 | }
676 | else if (_scrollView)
677 | {
678 | _scrollView.contentSize = CGSizeMake(_scrollView.frame.size.width, _innerView.frame.size.height);
679 |
680 | // -----
681 |
682 | CGRect viewFrame = CGRectMake(_scrollView.frame.size.width/2-_innerView.frame.size.width/2, 0.f, _innerView.frame.size.width, _innerView.frame.size.height);
683 |
684 | if ([UIScreen mainScreen].scale == 1.f)
685 | viewFrame = CGRectIntegral(viewFrame);
686 |
687 | _innerView.frame = viewFrame;
688 | }
689 |
690 | if (!self.isShowing && _transitionStyle == LGFilterViewTransitionStyleCenter)
691 | {
692 | scrollView.transform = CGAffineTransformMakeScale(1.2, 1.2);
693 | scrollView.alpha = 0.f;
694 | }
695 | }
696 |
697 | - (void)getParametersFromPresentation
698 | {
699 | UIScrollView *scrollView = nil;
700 |
701 | if (_tableView)
702 | scrollView = _tableView;
703 | else if (_scrollView)
704 | scrollView = _scrollView;
705 |
706 | // -----
707 |
708 | if (_backgroundView.layer.animationKeys.count && scrollView.layer.animationKeys.count)
709 | {
710 | _backgroundView.alpha = [(CALayer *)_backgroundView.layer.presentationLayer opacity];
711 |
712 | if (_transitionStyle == LGFilterViewTransitionStyleCenter)
713 | {
714 | CGFloat scaleX = [[(CALayer *)scrollView.layer.presentationLayer valueForKeyPath:@"transform.scale.x"] floatValue];
715 | CGFloat scaleY = [[(CALayer *)scrollView.layer.presentationLayer valueForKeyPath:@"transform.scale.y"] floatValue];
716 |
717 | if (scaleX && scaleY)
718 | scrollView.transform = CGAffineTransformMakeScale(scaleX, scaleY);
719 |
720 | scrollView.alpha = [(CALayer *)scrollView.layer.presentationLayer opacity];
721 | }
722 | else scrollView.center = [(CALayer *)scrollView.layer.presentationLayer position];
723 |
724 | [_backgroundView.layer removeAllAnimations];
725 | [scrollView.layer removeAllAnimations];
726 | }
727 | }
728 |
729 | #pragma mark -
730 |
731 | - (void)cancelAction
732 | {
733 | [self dismissAnimated:YES completionHandler:nil];
734 |
735 | // -----
736 |
737 | if (_cancelHandler) _cancelHandler(self);
738 |
739 | if (_delegate && [_delegate respondsToSelector:@selector(filterViewCancelled:)])
740 | [_delegate filterViewCancelled:self];
741 | }
742 |
743 | #pragma mark - Observers
744 |
745 | - (void)addObservers
746 | {
747 | if (!self.isObserversAdded && _parentView)
748 | {
749 | _observersAdded = YES;
750 |
751 | [_parentView addObserver:self forKeyPath:@"frame" options:NSKeyValueObservingOptionNew context:nil];
752 | }
753 | }
754 |
755 | - (void)removeObservers
756 | {
757 | if (self.isObserversAdded && _parentView)
758 | {
759 | _observersAdded = NO;
760 |
761 | [_parentView removeObserver:self forKeyPath:@"frame"];
762 | }
763 | }
764 |
765 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
766 | {
767 | if ([keyPath isEqualToString:@"frame"])
768 | [self layoutInvalidate];
769 | else
770 | [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
771 | }
772 |
773 | #pragma mark - Support
774 |
775 | + (void)animateStandardWithAnimations:(void(^)())animations completion:(void(^)(BOOL finished))completion
776 | {
777 | if ([UIDevice currentDevice].systemVersion.floatValue >= 7.0)
778 | {
779 | [UIView animateWithDuration:0.5
780 | delay:0.0
781 | usingSpringWithDamping:1.f
782 | initialSpringVelocity:0.5
783 | options:0
784 | animations:animations
785 | completion:completion];
786 | }
787 | else
788 | {
789 | [UIView animateWithDuration:0.5*0.66
790 | delay:0.0
791 | options:UIViewAnimationOptionCurveEaseInOut
792 | animations:animations
793 | completion:completion];
794 | }
795 | }
796 |
797 | @end
798 |
--------------------------------------------------------------------------------