├── 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 | --------------------------------------------------------------------------------