├── .gitignore ├── Example ├── LWCalendar.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── xcshareddata │ │ └── xcschemes │ │ └── LWCalendar-Example.xcscheme ├── LWCalendar.xcworkspace │ └── contents.xcworkspacedata ├── LWCalendar │ ├── Images.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── LaunchImage.launchimage │ │ │ └── Contents.json │ ├── LWAppDelegate.h │ ├── LWAppDelegate.m │ ├── LWCalendar-Info.plist │ ├── LWCalendar-Prefix.pch │ ├── LWViewController.h │ ├── LWViewController.m │ ├── Main.storyboard │ ├── en.lproj │ │ └── InfoPlist.strings │ └── main.m ├── Podfile ├── Podfile.lock ├── Pods │ ├── Local Podspecs │ │ └── LWCalendar.podspec.json │ ├── Manifest.lock │ ├── Pods.xcodeproj │ │ ├── project.pbxproj │ │ └── project.xcworkspace │ │ │ └── contents.xcworkspacedata │ └── Target Support Files │ │ ├── LWCalendar │ │ ├── Info.plist │ │ ├── LWCalendar-dummy.m │ │ ├── LWCalendar-prefix.pch │ │ ├── LWCalendar-umbrella.h │ │ ├── LWCalendar.modulemap │ │ └── LWCalendar.xcconfig │ │ ├── Pods-LWCalendar_Example │ │ ├── Info.plist │ │ ├── Pods-LWCalendar_Example-acknowledgements.markdown │ │ ├── Pods-LWCalendar_Example-acknowledgements.plist │ │ ├── Pods-LWCalendar_Example-dummy.m │ │ ├── Pods-LWCalendar_Example-frameworks.sh │ │ ├── Pods-LWCalendar_Example-resources.sh │ │ ├── Pods-LWCalendar_Example-umbrella.h │ │ ├── Pods-LWCalendar_Example.debug.xcconfig │ │ ├── Pods-LWCalendar_Example.modulemap │ │ └── Pods-LWCalendar_Example.release.xcconfig │ │ └── Pods-LWCalendar_Tests │ │ ├── Info.plist │ │ ├── Pods-LWCalendar_Tests-acknowledgements.markdown │ │ ├── Pods-LWCalendar_Tests-acknowledgements.plist │ │ ├── Pods-LWCalendar_Tests-dummy.m │ │ ├── Pods-LWCalendar_Tests-frameworks.sh │ │ ├── Pods-LWCalendar_Tests-resources.sh │ │ ├── Pods-LWCalendar_Tests-umbrella.h │ │ ├── Pods-LWCalendar_Tests.debug.xcconfig │ │ ├── Pods-LWCalendar_Tests.modulemap │ │ └── Pods-LWCalendar_Tests.release.xcconfig └── Tests │ ├── Tests-Info.plist │ ├── Tests-Prefix.pch │ ├── Tests.m │ └── en.lproj │ └── InfoPlist.strings ├── LICENSE ├── LWCalendar.podspec ├── LWCalendar ├── LWCalendar.bundle │ ├── circle@2x.png │ ├── end_filter@2x.png │ └── start_filter@2x.png ├── LWCalendarHeader.h ├── LWCalendarManager.h ├── LWCalendarManager.m ├── LWCalendarView.h ├── LWCalendarView.m ├── LWDateHelper.h ├── LWDateHelper.m ├── LWDateIndicator.h ├── LWDateIndicator.m ├── LWDatePickerBuilder.h ├── LWDatePickerBuilder.m ├── LWDatePickerDialog.h ├── LWDatePickerDialog.m ├── LWDatePickerView.h ├── LWDatePickerView.m ├── LWDayView.h ├── LWDayView.m ├── LWMonthView.h ├── LWMonthView.m ├── LWWeekIndicator.h ├── LWWeekIndicator.m ├── LWWeekView.h ├── LWWeekView.m ├── NSBundle+LWCalendar.h └── NSBundle+LWCalendar.m ├── README.md └── _Pods.xcodeproj /.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 | .DS_Store 20 | 21 | # CocoaPods 22 | # 23 | # We recommend against adding the Pods directory to your .gitignore. However 24 | # you should judge for yourself, the pros and cons are mentioned at: 25 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 26 | # 27 | #Pods/ -------------------------------------------------------------------------------- /Example/LWCalendar.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/LWCalendar.xcodeproj/xcshareddata/xcschemes/LWCalendar-Example.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /Example/LWCalendar.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Example/LWCalendar/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "83.5x83.5", 66 | "scale" : "2x" 67 | } 68 | ], 69 | "info" : { 70 | "version" : 1, 71 | "author" : "xcode" 72 | } 73 | } -------------------------------------------------------------------------------- /Example/LWCalendar/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "orientation" : "portrait", 20 | "idiom" : "ipad", 21 | "extent" : "full-screen", 22 | "minimum-system-version" : "7.0", 23 | "scale" : "1x" 24 | }, 25 | { 26 | "orientation" : "landscape", 27 | "idiom" : "ipad", 28 | "extent" : "full-screen", 29 | "minimum-system-version" : "7.0", 30 | "scale" : "1x" 31 | }, 32 | { 33 | "orientation" : "portrait", 34 | "idiom" : "ipad", 35 | "extent" : "full-screen", 36 | "minimum-system-version" : "7.0", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "orientation" : "landscape", 41 | "idiom" : "ipad", 42 | "extent" : "full-screen", 43 | "minimum-system-version" : "7.0", 44 | "scale" : "2x" 45 | } 46 | ], 47 | "info" : { 48 | "version" : 1, 49 | "author" : "xcode" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Example/LWCalendar/LWAppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // LWAppDelegate.h 3 | // LWCalendar 4 | // 5 | // Created by 1071932819@qq.com on 01/08/2017. 6 | // Copyright (c) 2017 1071932819@qq.com. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | @interface LWAppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /Example/LWCalendar/LWAppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // LWAppDelegate.m 3 | // LWCalendar 4 | // 5 | // Created by 1071932819@qq.com on 01/08/2017. 6 | // Copyright (c) 2017 1071932819@qq.com. All rights reserved. 7 | // 8 | 9 | #import "LWAppDelegate.h" 10 | 11 | @implementation LWAppDelegate 12 | 13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 14 | { 15 | // Override point for customization after application launch. 16 | return YES; 17 | } 18 | 19 | - (void)applicationWillResignActive:(UIApplication *)application 20 | { 21 | // 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. 22 | // 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. 23 | } 24 | 25 | - (void)applicationDidEnterBackground:(UIApplication *)application 26 | { 27 | // 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. 28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 29 | } 30 | 31 | - (void)applicationWillEnterForeground:(UIApplication *)application 32 | { 33 | // 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. 34 | } 35 | 36 | - (void)applicationDidBecomeActive:(UIApplication *)application 37 | { 38 | // 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. 39 | } 40 | 41 | - (void)applicationWillTerminate:(UIApplication *)application 42 | { 43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 44 | } 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /Example/LWCalendar/LWCalendar-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | Main 29 | UIMainStoryboardFile 30 | Main 31 | UIRequiredDeviceCapabilities 32 | 33 | armv7 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationLandscapeLeft 39 | UIInterfaceOrientationLandscapeRight 40 | 41 | UISupportedInterfaceOrientations~ipad 42 | 43 | UIInterfaceOrientationPortrait 44 | UIInterfaceOrientationPortraitUpsideDown 45 | UIInterfaceOrientationLandscapeLeft 46 | UIInterfaceOrientationLandscapeRight 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /Example/LWCalendar/LWCalendar-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | @import UIKit; 15 | @import Foundation; 16 | #endif 17 | -------------------------------------------------------------------------------- /Example/LWCalendar/LWViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // LWViewController.h 3 | // LWCalendar 4 | // 5 | // Created by 1071932819@qq.com on 01/08/2017. 6 | // Copyright (c) 2017 1071932819@qq.com. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | @import LWCalendar; 11 | 12 | @interface LWViewController : UIViewController 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Example/LWCalendar/LWViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // LWViewController.m 3 | // LWCalendar 4 | // 5 | // Created by 1071932819@qq.com on 01/08/2017. 6 | // Copyright (c) 2017 1071932819@qq.com. All rights reserved. 7 | // 8 | 9 | #import "LWViewController.h" 10 | 11 | 12 | @interface LWViewController () 13 | 14 | @end 15 | 16 | @implementation LWViewController 17 | 18 | - (void)viewDidLoad 19 | { 20 | [super viewDidLoad]; 21 | self.view.backgroundColor = [UIColor whiteColor]; 22 | UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(show)]; 23 | [self.view addGestureRecognizer:recognizer]; 24 | } 25 | 26 | - (void)didReceiveMemoryWarning 27 | { 28 | [super didReceiveMemoryWarning]; 29 | // Dispose of any resources that can be recreated. 30 | } 31 | 32 | -(void)show{ 33 | [[LWDatePickerDialog initWithDate:[NSDate date] Delegate:self] show]; 34 | } 35 | 36 | -(void)onDateSet:(LWDatePickerDialog *)dialog StartDate:(NSDate *)start EndDate:(NSDate *)end{ 37 | NSLog(@"onDateSet"); 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /Example/LWCalendar/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Example/LWCalendar/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Example/LWCalendar/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // LWCalendar 4 | // 5 | // Created by 1071932819@qq.com on 01/08/2017. 6 | // Copyright (c) 2017 1071932819@qq.com. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | #import "LWAppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) 13 | { 14 | @autoreleasepool { 15 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([LWAppDelegate class])); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Example/Podfile: -------------------------------------------------------------------------------- 1 | use_frameworks! 2 | 3 | target 'LWCalendar_Example' do 4 | pod 'LWCalendar', :path => '../' 5 | 6 | target 'LWCalendar_Tests' do 7 | inherit! :search_paths 8 | 9 | 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /Example/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - LWCalendar (1.0.0) 3 | 4 | DEPENDENCIES: 5 | - LWCalendar (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | LWCalendar: 9 | :path: "../" 10 | 11 | SPEC CHECKSUMS: 12 | LWCalendar: 788e1e671e4357847fea2b42bf2e28230c510d99 13 | 14 | PODFILE CHECKSUM: 06329ed04c71f394f1a4e2218c3fc43aa8665ed6 15 | 16 | COCOAPODS: 1.0.1 17 | -------------------------------------------------------------------------------- /Example/Pods/Local Podspecs/LWCalendar.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "LWCalendar", 3 | "version": "1.0.0", 4 | "summary": "Material Design Style Calendar for IOS.", 5 | "description": "This is a date picker with material design style. I have searched around for such a project and I get nothing.\nPeople seem to like useing the date picker offered by IOS system. So I start this project for someone else sufferring from date picker.\n\nHope you enjoy.\n\nIf you want to contribut to this project,please email \"1071932819@qq.com\".", 6 | "homepage": "https://github.com/luwei2012/LWCalender", 7 | "screenshots": "luwei2012.github.io/images/IOS/CustomView/ZYCalender_Record.gif", 8 | "license": { 9 | "type": "GNU", 10 | "file": "LICENSE" 11 | }, 12 | "authors": { 13 | "1071932819@qq.com": "luwei2012" 14 | }, 15 | "source": { 16 | "git": "https://github.com/luwei2012/LWCalender.git", 17 | "tag": "1.0.0" 18 | }, 19 | "social_media_url": "http://luwei2012.github.io", 20 | "platforms": { 21 | "ios": "7.0" 22 | }, 23 | "source_files": "LWCalendar/**/*.{h,m}", 24 | "resources": "LWCalendar/LWCalendar.bundle", 25 | "requires_arc": true 26 | } 27 | -------------------------------------------------------------------------------- /Example/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - LWCalendar (1.0.0) 3 | 4 | DEPENDENCIES: 5 | - LWCalendar (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | LWCalendar: 9 | :path: "../" 10 | 11 | SPEC CHECKSUMS: 12 | LWCalendar: 788e1e671e4357847fea2b42bf2e28230c510d99 13 | 14 | PODFILE CHECKSUM: 06329ed04c71f394f1a4e2218c3fc43aa8665ed6 15 | 16 | COCOAPODS: 1.0.1 17 | -------------------------------------------------------------------------------- /Example/Pods/Pods.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/LWCalendar/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.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/LWCalendar/LWCalendar-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_LWCalendar : NSObject 3 | @end 4 | @implementation PodsDummy_LWCalendar 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/LWCalendar/LWCalendar-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/LWCalendar/LWCalendar-umbrella.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "LWCalendarHeader.h" 4 | #import "LWCalendarManager.h" 5 | #import "LWCalendarView.h" 6 | #import "LWDateHelper.h" 7 | #import "LWDateIndicator.h" 8 | #import "LWDatePickerBuilder.h" 9 | #import "LWDatePickerDialog.h" 10 | #import "LWDatePickerView.h" 11 | #import "LWDayView.h" 12 | #import "LWMonthView.h" 13 | #import "LWWeekIndicator.h" 14 | #import "LWWeekView.h" 15 | #import "NSBundle+LWCalendar.h" 16 | 17 | FOUNDATION_EXPORT double LWCalendarVersionNumber; 18 | FOUNDATION_EXPORT const unsigned char LWCalendarVersionString[]; 19 | 20 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/LWCalendar/LWCalendar.modulemap: -------------------------------------------------------------------------------- 1 | framework module LWCalendar { 2 | umbrella header "LWCalendar-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/LWCalendar/LWCalendar.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/LWCalendar 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" 4 | PODS_BUILD_DIR = $BUILD_DIR 5 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 6 | PODS_ROOT = ${SRCROOT} 7 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 8 | SKIP_INSTALL = YES 9 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-LWCalendar_Example/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.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-LWCalendar_Example/Pods-LWCalendar_Example-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## LWCalendar 5 | 6 | GNU GENERAL PUBLIC LICENSE 7 | Version 2, June 1991 8 | 9 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 10 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 11 | Everyone is permitted to copy and distribute verbatim copies 12 | of this license document, but changing it is not allowed. 13 | 14 | Preamble 15 | 16 | The licenses for most software are designed to take away your 17 | freedom to share and change it. By contrast, the GNU General Public 18 | License is intended to guarantee your freedom to share and change free 19 | software--to make sure the software is free for all its users. This 20 | General Public License applies to most of the Free Software 21 | Foundation's software and to any other program whose authors commit to 22 | using it. (Some other Free Software Foundation software is covered by 23 | the GNU Lesser General Public License instead.) You can apply it to 24 | your programs, too. 25 | 26 | When we speak of free software, we are referring to freedom, not 27 | price. Our General Public Licenses are designed to make sure that you 28 | have the freedom to distribute copies of free software (and charge for 29 | this service if you wish), that you receive source code or can get it 30 | if you want it, that you can change the software or use pieces of it 31 | in new free programs; and that you know you can do these things. 32 | 33 | To protect your rights, we need to make restrictions that forbid 34 | anyone to deny you these rights or to ask you to surrender the rights. 35 | These restrictions translate to certain responsibilities for you if you 36 | distribute copies of the software, or if you modify it. 37 | 38 | For example, if you distribute copies of such a program, whether 39 | gratis or for a fee, you must give the recipients all the rights that 40 | you have. You must make sure that they, too, receive or can get the 41 | source code. And you must show them these terms so they know their 42 | rights. 43 | 44 | We protect your rights with two steps: (1) copyright the software, and 45 | (2) offer you this license which gives you legal permission to copy, 46 | distribute and/or modify the software. 47 | 48 | Also, for each author's protection and ours, we want to make certain 49 | that everyone understands that there is no warranty for this free 50 | software. If the software is modified by someone else and passed on, we 51 | want its recipients to know that what they have is not the original, so 52 | that any problems introduced by others will not reflect on the original 53 | authors' reputations. 54 | 55 | Finally, any free program is threatened constantly by software 56 | patents. We wish to avoid the danger that redistributors of a free 57 | program will individually obtain patent licenses, in effect making the 58 | program proprietary. To prevent this, we have made it clear that any 59 | patent must be licensed for everyone's free use or not licensed at all. 60 | 61 | The precise terms and conditions for copying, distribution and 62 | modification follow. 63 | 64 | GNU GENERAL PUBLIC LICENSE 65 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 66 | 67 | 0. This License applies to any program or other work which contains 68 | a notice placed by the copyright holder saying it may be distributed 69 | under the terms of this General Public License. The "Program", below, 70 | refers to any such program or work, and a "work based on the Program" 71 | means either the Program or any derivative work under copyright law: 72 | that is to say, a work containing the Program or a portion of it, 73 | either verbatim or with modifications and/or translated into another 74 | language. (Hereinafter, translation is included without limitation in 75 | the term "modification".) Each licensee is addressed as "you". 76 | 77 | Activities other than copying, distribution and modification are not 78 | covered by this License; they are outside its scope. The act of 79 | running the Program is not restricted, and the output from the Program 80 | is covered only if its contents constitute a work based on the 81 | Program (independent of having been made by running the Program). 82 | Whether that is true depends on what the Program does. 83 | 84 | 1. You may copy and distribute verbatim copies of the Program's 85 | source code as you receive it, in any medium, provided that you 86 | conspicuously and appropriately publish on each copy an appropriate 87 | copyright notice and disclaimer of warranty; keep intact all the 88 | notices that refer to this License and to the absence of any warranty; 89 | and give any other recipients of the Program a copy of this License 90 | along with the Program. 91 | 92 | You may charge a fee for the physical act of transferring a copy, and 93 | you may at your option offer warranty protection in exchange for a fee. 94 | 95 | 2. You may modify your copy or copies of the Program or any portion 96 | of it, thus forming a work based on the Program, and copy and 97 | distribute such modifications or work under the terms of Section 1 98 | above, provided that you also meet all of these conditions: 99 | 100 | a) You must cause the modified files to carry prominent notices 101 | stating that you changed the files and the date of any change. 102 | 103 | b) You must cause any work that you distribute or publish, that in 104 | whole or in part contains or is derived from the Program or any 105 | part thereof, to be licensed as a whole at no charge to all third 106 | parties under the terms of this License. 107 | 108 | c) If the modified program normally reads commands interactively 109 | when run, you must cause it, when started running for such 110 | interactive use in the most ordinary way, to print or display an 111 | announcement including an appropriate copyright notice and a 112 | notice that there is no warranty (or else, saying that you provide 113 | a warranty) and that users may redistribute the program under 114 | these conditions, and telling the user how to view a copy of this 115 | License. (Exception: if the Program itself is interactive but 116 | does not normally print such an announcement, your work based on 117 | the Program is not required to print an announcement.) 118 | 119 | These requirements apply to the modified work as a whole. If 120 | identifiable sections of that work are not derived from the Program, 121 | and can be reasonably considered independent and separate works in 122 | themselves, then this License, and its terms, do not apply to those 123 | sections when you distribute them as separate works. But when you 124 | distribute the same sections as part of a whole which is a work based 125 | on the Program, the distribution of the whole must be on the terms of 126 | this License, whose permissions for other licensees extend to the 127 | entire whole, and thus to each and every part regardless of who wrote it. 128 | 129 | Thus, it is not the intent of this section to claim rights or contest 130 | your rights to work written entirely by you; rather, the intent is to 131 | exercise the right to control the distribution of derivative or 132 | collective works based on the Program. 133 | 134 | In addition, mere aggregation of another work not based on the Program 135 | with the Program (or with a work based on the Program) on a volume of 136 | a storage or distribution medium does not bring the other work under 137 | the scope of this License. 138 | 139 | 3. You may copy and distribute the Program (or a work based on it, 140 | under Section 2) in object code or executable form under the terms of 141 | Sections 1 and 2 above provided that you also do one of the following: 142 | 143 | a) Accompany it with the complete corresponding machine-readable 144 | source code, which must be distributed under the terms of Sections 145 | 1 and 2 above on a medium customarily used for software interchange; or, 146 | 147 | b) Accompany it with a written offer, valid for at least three 148 | years, to give any third party, for a charge no more than your 149 | cost of physically performing source distribution, a complete 150 | machine-readable copy of the corresponding source code, to be 151 | distributed under the terms of Sections 1 and 2 above on a medium 152 | customarily used for software interchange; or, 153 | 154 | c) Accompany it with the information you received as to the offer 155 | to distribute corresponding source code. (This alternative is 156 | allowed only for noncommercial distribution and only if you 157 | received the program in object code or executable form with such 158 | an offer, in accord with Subsection b above.) 159 | 160 | The source code for a work means the preferred form of the work for 161 | making modifications to it. For an executable work, complete source 162 | code means all the source code for all modules it contains, plus any 163 | associated interface definition files, plus the scripts used to 164 | control compilation and installation of the executable. However, as a 165 | special exception, the source code distributed need not include 166 | anything that is normally distributed (in either source or binary 167 | form) with the major components (compiler, kernel, and so on) of the 168 | operating system on which the executable runs, unless that component 169 | itself accompanies the executable. 170 | 171 | If distribution of executable or object code is made by offering 172 | access to copy from a designated place, then offering equivalent 173 | access to copy the source code from the same place counts as 174 | distribution of the source code, even though third parties are not 175 | compelled to copy the source along with the object code. 176 | 177 | 4. You may not copy, modify, sublicense, or distribute the Program 178 | except as expressly provided under this License. Any attempt 179 | otherwise to copy, modify, sublicense or distribute the Program is 180 | void, and will automatically terminate your rights under this License. 181 | However, parties who have received copies, or rights, from you under 182 | this License will not have their licenses terminated so long as such 183 | parties remain in full compliance. 184 | 185 | 5. You are not required to accept this License, since you have not 186 | signed it. However, nothing else grants you permission to modify or 187 | distribute the Program or its derivative works. These actions are 188 | prohibited by law if you do not accept this License. Therefore, by 189 | modifying or distributing the Program (or any work based on the 190 | Program), you indicate your acceptance of this License to do so, and 191 | all its terms and conditions for copying, distributing or modifying 192 | the Program or works based on it. 193 | 194 | 6. Each time you redistribute the Program (or any work based on the 195 | Program), the recipient automatically receives a license from the 196 | original licensor to copy, distribute or modify the Program subject to 197 | these terms and conditions. You may not impose any further 198 | restrictions on the recipients' exercise of the rights granted herein. 199 | You are not responsible for enforcing compliance by third parties to 200 | this License. 201 | 202 | 7. If, as a consequence of a court judgment or allegation of patent 203 | infringement or for any other reason (not limited to patent issues), 204 | conditions are imposed on you (whether by court order, agreement or 205 | otherwise) that contradict the conditions of this License, they do not 206 | excuse you from the conditions of this License. If you cannot 207 | distribute so as to satisfy simultaneously your obligations under this 208 | License and any other pertinent obligations, then as a consequence you 209 | may not distribute the Program at all. For example, if a patent 210 | license would not permit royalty-free redistribution of the Program by 211 | all those who receive copies directly or indirectly through you, then 212 | the only way you could satisfy both it and this License would be to 213 | refrain entirely from distribution of the Program. 214 | 215 | If any portion of this section is held invalid or unenforceable under 216 | any particular circumstance, the balance of the section is intended to 217 | apply and the section as a whole is intended to apply in other 218 | circumstances. 219 | 220 | It is not the purpose of this section to induce you to infringe any 221 | patents or other property right claims or to contest validity of any 222 | such claims; this section has the sole purpose of protecting the 223 | integrity of the free software distribution system, which is 224 | implemented by public license practices. Many people have made 225 | generous contributions to the wide range of software distributed 226 | through that system in reliance on consistent application of that 227 | system; it is up to the author/donor to decide if he or she is willing 228 | to distribute software through any other system and a licensee cannot 229 | impose that choice. 230 | 231 | This section is intended to make thoroughly clear what is believed to 232 | be a consequence of the rest of this License. 233 | 234 | 8. If the distribution and/or use of the Program is restricted in 235 | certain countries either by patents or by copyrighted interfaces, the 236 | original copyright holder who places the Program under this License 237 | may add an explicit geographical distribution limitation excluding 238 | those countries, so that distribution is permitted only in or among 239 | countries not thus excluded. In such case, this License incorporates 240 | the limitation as if written in the body of this License. 241 | 242 | 9. The Free Software Foundation may publish revised and/or new versions 243 | of the General Public License from time to time. Such new versions will 244 | be similar in spirit to the present version, but may differ in detail to 245 | address new problems or concerns. 246 | 247 | Each version is given a distinguishing version number. If the Program 248 | specifies a version number of this License which applies to it and "any 249 | later version", you have the option of following the terms and conditions 250 | either of that version or of any later version published by the Free 251 | Software Foundation. If the Program does not specify a version number of 252 | this License, you may choose any version ever published by the Free Software 253 | Foundation. 254 | 255 | 10. If you wish to incorporate parts of the Program into other free 256 | programs whose distribution conditions are different, write to the author 257 | to ask for permission. For software which is copyrighted by the Free 258 | Software Foundation, write to the Free Software Foundation; we sometimes 259 | make exceptions for this. Our decision will be guided by the two goals 260 | of preserving the free status of all derivatives of our free software and 261 | of promoting the sharing and reuse of software generally. 262 | 263 | NO WARRANTY 264 | 265 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 266 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 267 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 268 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 269 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 270 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 271 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 272 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 273 | REPAIR OR CORRECTION. 274 | 275 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 276 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 277 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 278 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 279 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 280 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 281 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 282 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 283 | POSSIBILITY OF SUCH DAMAGES. 284 | 285 | END OF TERMS AND CONDITIONS 286 | 287 | How to Apply These Terms to Your New Programs 288 | 289 | If you develop a new program, and you want it to be of the greatest 290 | possible use to the public, the best way to achieve this is to make it 291 | free software which everyone can redistribute and change under these terms. 292 | 293 | To do so, attach the following notices to the program. It is safest 294 | to attach them to the start of each source file to most effectively 295 | convey the exclusion of warranty; and each file should have at least 296 | the "copyright" line and a pointer to where the full notice is found. 297 | 298 | {description} 299 | Copyright (C) {year} {fullname} 300 | 301 | This program is free software; you can redistribute it and/or modify 302 | it under the terms of the GNU General Public License as published by 303 | the Free Software Foundation; either version 2 of the License, or 304 | (at your option) any later version. 305 | 306 | This program is distributed in the hope that it will be useful, 307 | but WITHOUT ANY WARRANTY; without even the implied warranty of 308 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 309 | GNU General Public License for more details. 310 | 311 | You should have received a copy of the GNU General Public License along 312 | with this program; if not, write to the Free Software Foundation, Inc., 313 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 314 | 315 | Also add information on how to contact you by electronic and paper mail. 316 | 317 | If the program is interactive, make it output a short notice like this 318 | when it starts in an interactive mode: 319 | 320 | Gnomovision version 69, Copyright (C) year name of author 321 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 322 | This is free software, and you are welcome to redistribute it 323 | under certain conditions; type `show c' for details. 324 | 325 | The hypothetical commands `show w' and `show c' should show the appropriate 326 | parts of the General Public License. Of course, the commands you use may 327 | be called something other than `show w' and `show c'; they could even be 328 | mouse-clicks or menu items--whatever suits your program. 329 | 330 | You should also get your employer (if you work as a programmer) or your 331 | school, if any, to sign a "copyright disclaimer" for the program, if 332 | necessary. Here is a sample; alter the names: 333 | 334 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 335 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 336 | 337 | {signature of Ty Coon}, 1 April 1989 338 | Ty Coon, President of Vice 339 | 340 | This General Public License does not permit incorporating your program into 341 | proprietary programs. If your program is a subroutine library, you may 342 | consider it more useful to permit linking proprietary applications with the 343 | library. If this is what you want to do, use the GNU Lesser General 344 | Public License instead of this License. 345 | 346 | 347 | Generated by CocoaPods - https://cocoapods.org 348 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-LWCalendar_Example/Pods-LWCalendar_Example-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_LWCalendar_Example : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_LWCalendar_Example 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-LWCalendar_Example/Pods-LWCalendar_Example-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 6 | 7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 8 | 9 | install_framework() 10 | { 11 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 12 | local source="${BUILT_PRODUCTS_DIR}/$1" 13 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 14 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 15 | elif [ -r "$1" ]; then 16 | local source="$1" 17 | fi 18 | 19 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 20 | 21 | if [ -L "${source}" ]; then 22 | echo "Symlinked..." 23 | source="$(readlink "${source}")" 24 | fi 25 | 26 | # use filter instead of exclude so missing patterns dont' throw errors 27 | echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 28 | rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 29 | 30 | local basename 31 | basename="$(basename -s .framework "$1")" 32 | binary="${destination}/${basename}.framework/${basename}" 33 | if ! [ -r "$binary" ]; then 34 | binary="${destination}/${basename}" 35 | fi 36 | 37 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 38 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 39 | strip_invalid_archs "$binary" 40 | fi 41 | 42 | # Resign the code if required by the build settings to avoid unstable apps 43 | code_sign_if_enabled "${destination}/$(basename "$1")" 44 | 45 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 46 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 47 | local swift_runtime_libs 48 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 49 | for lib in $swift_runtime_libs; do 50 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 51 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 52 | code_sign_if_enabled "${destination}/${lib}" 53 | done 54 | fi 55 | } 56 | 57 | # Signs a framework with the provided identity 58 | code_sign_if_enabled() { 59 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 60 | # Use the current code_sign_identitiy 61 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 62 | echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements \"$1\"" 63 | /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1" 64 | fi 65 | } 66 | 67 | # Strip invalid architectures 68 | strip_invalid_archs() { 69 | binary="$1" 70 | # Get architectures for current file 71 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" 72 | stripped="" 73 | for arch in $archs; do 74 | if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then 75 | # Strip non-valid architectures in-place 76 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 77 | stripped="$stripped $arch" 78 | fi 79 | done 80 | if [[ "$stripped" ]]; then 81 | echo "Stripped $binary of architectures:$stripped" 82 | fi 83 | } 84 | 85 | 86 | if [[ "$CONFIGURATION" == "Debug" ]]; then 87 | install_framework "$BUILT_PRODUCTS_DIR/LWCalendar/LWCalendar.framework" 88 | fi 89 | if [[ "$CONFIGURATION" == "Release" ]]; then 90 | install_framework "$BUILT_PRODUCTS_DIR/LWCalendar/LWCalendar.framework" 91 | fi 92 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-LWCalendar_Example/Pods-LWCalendar_Example-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | case "${TARGETED_DEVICE_FAMILY}" in 12 | 1,2) 13 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 14 | ;; 15 | 1) 16 | TARGET_DEVICE_ARGS="--target-device iphone" 17 | ;; 18 | 2) 19 | TARGET_DEVICE_ARGS="--target-device ipad" 20 | ;; 21 | *) 22 | TARGET_DEVICE_ARGS="--target-device mac" 23 | ;; 24 | esac 25 | 26 | realpath() { 27 | DIRECTORY="$(cd "${1%/*}" && pwd)" 28 | FILENAME="${1##*/}" 29 | echo "$DIRECTORY/$FILENAME" 30 | } 31 | 32 | install_resource() 33 | { 34 | if [[ "$1" = /* ]] ; then 35 | RESOURCE_PATH="$1" 36 | else 37 | RESOURCE_PATH="${PODS_ROOT}/$1" 38 | fi 39 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 40 | cat << EOM 41 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 42 | EOM 43 | exit 1 44 | fi 45 | case $RESOURCE_PATH in 46 | *.storyboard) 47 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" 48 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 49 | ;; 50 | *.xib) 51 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" 52 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 53 | ;; 54 | *.framework) 55 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 56 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 57 | echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 58 | rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 59 | ;; 60 | *.xcdatamodel) 61 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" 62 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 63 | ;; 64 | *.xcdatamodeld) 65 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" 66 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 67 | ;; 68 | *.xcmappingmodel) 69 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" 70 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 71 | ;; 72 | *.xcassets) 73 | ABSOLUTE_XCASSET_FILE=$(realpath "$RESOURCE_PATH") 74 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 75 | ;; 76 | *) 77 | echo "$RESOURCE_PATH" 78 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 79 | ;; 80 | esac 81 | } 82 | 83 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 84 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 85 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 86 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 87 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 88 | fi 89 | rm -f "$RESOURCES_TO_COPY" 90 | 91 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 92 | then 93 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 94 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 95 | while read line; do 96 | if [[ $line != "`realpath $PODS_ROOT`*" ]]; then 97 | XCASSET_FILES+=("$line") 98 | fi 99 | done <<<"$OTHER_XCASSETS" 100 | 101 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 102 | fi 103 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-LWCalendar_Example/Pods-LWCalendar_Example-umbrella.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | 4 | FOUNDATION_EXPORT double Pods_LWCalendar_ExampleVersionNumber; 5 | FOUNDATION_EXPORT const unsigned char Pods_LWCalendar_ExampleVersionString[]; 6 | 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-LWCalendar_Example/Pods-LWCalendar_Example.debug.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/LWCalendar" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 4 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/LWCalendar/LWCalendar.framework/Headers" 5 | OTHER_LDFLAGS = $(inherited) -framework "LWCalendar" 6 | PODS_BUILD_DIR = $BUILD_DIR 7 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-LWCalendar_Example/Pods-LWCalendar_Example.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_LWCalendar_Example { 2 | umbrella header "Pods-LWCalendar_Example-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-LWCalendar_Example/Pods-LWCalendar_Example.release.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/LWCalendar" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 4 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/LWCalendar/LWCalendar.framework/Headers" 5 | OTHER_LDFLAGS = $(inherited) -framework "LWCalendar" 6 | PODS_BUILD_DIR = $BUILD_DIR 7 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 8 | PODS_ROOT = ${SRCROOT}/Pods 9 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-LWCalendar_Tests/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.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-LWCalendar_Tests/Pods-LWCalendar_Tests-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | Generated by CocoaPods - https://cocoapods.org 4 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-LWCalendar_Tests/Pods-LWCalendar_Tests-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Generated by CocoaPods - https://cocoapods.org 18 | Title 19 | 20 | Type 21 | PSGroupSpecifier 22 | 23 | 24 | StringsTable 25 | Acknowledgements 26 | Title 27 | Acknowledgements 28 | 29 | 30 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-LWCalendar_Tests/Pods-LWCalendar_Tests-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_LWCalendar_Tests : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_LWCalendar_Tests 5 | @end 6 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-LWCalendar_Tests/Pods-LWCalendar_Tests-frameworks.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 5 | mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 6 | 7 | SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" 8 | 9 | install_framework() 10 | { 11 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 12 | local source="${BUILT_PRODUCTS_DIR}/$1" 13 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 14 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 15 | elif [ -r "$1" ]; then 16 | local source="$1" 17 | fi 18 | 19 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 20 | 21 | if [ -L "${source}" ]; then 22 | echo "Symlinked..." 23 | source="$(readlink "${source}")" 24 | fi 25 | 26 | # use filter instead of exclude so missing patterns dont' throw errors 27 | echo "rsync -av --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 28 | rsync -av --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 29 | 30 | local basename 31 | basename="$(basename -s .framework "$1")" 32 | binary="${destination}/${basename}.framework/${basename}" 33 | if ! [ -r "$binary" ]; then 34 | binary="${destination}/${basename}" 35 | fi 36 | 37 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 38 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 39 | strip_invalid_archs "$binary" 40 | fi 41 | 42 | # Resign the code if required by the build settings to avoid unstable apps 43 | code_sign_if_enabled "${destination}/$(basename "$1")" 44 | 45 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 46 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 47 | local swift_runtime_libs 48 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 49 | for lib in $swift_runtime_libs; do 50 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 51 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 52 | code_sign_if_enabled "${destination}/${lib}" 53 | done 54 | fi 55 | } 56 | 57 | # Signs a framework with the provided identity 58 | code_sign_if_enabled() { 59 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 60 | # Use the current code_sign_identitiy 61 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 62 | echo "/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements \"$1\"" 63 | /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements "$1" 64 | fi 65 | } 66 | 67 | # Strip invalid architectures 68 | strip_invalid_archs() { 69 | binary="$1" 70 | # Get architectures for current file 71 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" 72 | stripped="" 73 | for arch in $archs; do 74 | if ! [[ "${VALID_ARCHS}" == *"$arch"* ]]; then 75 | # Strip non-valid architectures in-place 76 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 77 | stripped="$stripped $arch" 78 | fi 79 | done 80 | if [[ "$stripped" ]]; then 81 | echo "Stripped $binary of architectures:$stripped" 82 | fi 83 | } 84 | 85 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-LWCalendar_Tests/Pods-LWCalendar_Tests-resources.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 5 | 6 | RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt 7 | > "$RESOURCES_TO_COPY" 8 | 9 | XCASSET_FILES=() 10 | 11 | case "${TARGETED_DEVICE_FAMILY}" in 12 | 1,2) 13 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 14 | ;; 15 | 1) 16 | TARGET_DEVICE_ARGS="--target-device iphone" 17 | ;; 18 | 2) 19 | TARGET_DEVICE_ARGS="--target-device ipad" 20 | ;; 21 | *) 22 | TARGET_DEVICE_ARGS="--target-device mac" 23 | ;; 24 | esac 25 | 26 | realpath() { 27 | DIRECTORY="$(cd "${1%/*}" && pwd)" 28 | FILENAME="${1##*/}" 29 | echo "$DIRECTORY/$FILENAME" 30 | } 31 | 32 | install_resource() 33 | { 34 | if [[ "$1" = /* ]] ; then 35 | RESOURCE_PATH="$1" 36 | else 37 | RESOURCE_PATH="${PODS_ROOT}/$1" 38 | fi 39 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 40 | cat << EOM 41 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 42 | EOM 43 | exit 1 44 | fi 45 | case $RESOURCE_PATH in 46 | *.storyboard) 47 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" 48 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 49 | ;; 50 | *.xib) 51 | echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" 52 | ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 53 | ;; 54 | *.framework) 55 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 56 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 57 | echo "rsync -av $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 58 | rsync -av "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 59 | ;; 60 | *.xcdatamodel) 61 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" 62 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 63 | ;; 64 | *.xcdatamodeld) 65 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" 66 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 67 | ;; 68 | *.xcmappingmodel) 69 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" 70 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 71 | ;; 72 | *.xcassets) 73 | ABSOLUTE_XCASSET_FILE=$(realpath "$RESOURCE_PATH") 74 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 75 | ;; 76 | *) 77 | echo "$RESOURCE_PATH" 78 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 79 | ;; 80 | esac 81 | } 82 | 83 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 84 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 85 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 86 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 87 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 88 | fi 89 | rm -f "$RESOURCES_TO_COPY" 90 | 91 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 92 | then 93 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 94 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 95 | while read line; do 96 | if [[ $line != "`realpath $PODS_ROOT`*" ]]; then 97 | XCASSET_FILES+=("$line") 98 | fi 99 | done <<<"$OTHER_XCASSETS" 100 | 101 | printf "%s\0" "${XCASSET_FILES[@]}" | xargs -0 xcrun actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${!DEPLOYMENT_TARGET_SETTING_NAME}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 102 | fi 103 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-LWCalendar_Tests/Pods-LWCalendar_Tests-umbrella.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | 4 | FOUNDATION_EXPORT double Pods_LWCalendar_TestsVersionNumber; 5 | FOUNDATION_EXPORT const unsigned char Pods_LWCalendar_TestsVersionString[]; 6 | 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-LWCalendar_Tests/Pods-LWCalendar_Tests.debug.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/LWCalendar" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 4 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/LWCalendar/LWCalendar.framework/Headers" 5 | PODS_BUILD_DIR = $BUILD_DIR 6 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT}/Pods 8 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-LWCalendar_Tests/Pods-LWCalendar_Tests.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_LWCalendar_Tests { 2 | umbrella header "Pods-LWCalendar_Tests-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Example/Pods/Target Support Files/Pods-LWCalendar_Tests/Pods-LWCalendar_Tests.release.xcconfig: -------------------------------------------------------------------------------- 1 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/LWCalendar" 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 4 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/LWCalendar/LWCalendar.framework/Headers" 5 | PODS_BUILD_DIR = $BUILD_DIR 6 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT}/Pods 8 | -------------------------------------------------------------------------------- /Example/Tests/Tests-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 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Example/Tests/Tests-Prefix.pch: -------------------------------------------------------------------------------- 1 | // The contents of this file are implicitly included at the beginning of every test case source file. 2 | 3 | #ifdef __OBJC__ 4 | 5 | 6 | 7 | #endif 8 | -------------------------------------------------------------------------------- /Example/Tests/Tests.m: -------------------------------------------------------------------------------- 1 | // 2 | // LWCalendarTests.m 3 | // LWCalendarTests 4 | // 5 | // Created by 1071932819@qq.com on 01/08/2017. 6 | // Copyright (c) 2017 1071932819@qq.com. All rights reserved. 7 | // 8 | 9 | @import XCTest; 10 | 11 | @interface Tests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation Tests 16 | 17 | - (void)setUp 18 | { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown 24 | { 25 | // Put teardown code here. This method is called after the invocation of each test method in the class. 26 | [super tearDown]; 27 | } 28 | 29 | - (void)testExample 30 | { 31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 32 | } 33 | 34 | @end 35 | 36 | -------------------------------------------------------------------------------- /Example/Tests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | {description} 294 | Copyright (C) {year} {fullname} 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | {signature of Ty Coon}, 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | 341 | -------------------------------------------------------------------------------- /LWCalendar.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod lib lint LWCalendar.podspec' to ensure this is a 3 | # valid spec before submitting. 4 | # 5 | # Any lines starting with a # are optional, but their use is encouraged 6 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | s.name = 'LWCalendar' 11 | s.version = '1.0.1' 12 | s.summary = 'Material Design Style Calendar for IOS.' 13 | 14 | # This description is used to generate tags and improve search results. 15 | # * Think: What does it do? Why did you write it? What is the focus? 16 | # * Try to keep it short, snappy and to the point. 17 | # * Write the description between the DESC delimiters below. 18 | # * Finally, don't worry about the indent, CocoaPods strips it! 19 | 20 | s.description = <<-DESC 21 | This is a date picker with material design style. I have searched around for such a project and I get nothing. 22 | People seem to like useing the date picker offered by IOS system. So I start this project for someone else sufferring from date picker. 23 | 24 | Hope you enjoy. 25 | 26 | If you want to contribut to this project,please email "1071932819@qq.com". 27 | DESC 28 | 29 | s.homepage = 'https://github.com/luwei2012/LWCalendar' 30 | s.screenshots = "https://luwei2012.github.io/images/IOS/CustomView/ZYCalender_Record.gif" 31 | s.license = { :type => 'GNU', :file => 'LICENSE' } 32 | s.author = { '1071932819@qq.com' => 'luwei2012' } 33 | s.source = { :git => 'https://github.com/luwei2012/LWCalendar.git', :tag => s.version.to_s } 34 | s.social_media_url = "http://luwei2012.github.io" 35 | s.ios.deployment_target = '7.0' 36 | s.source_files = 'LWCalendar/**/*.{h,m}' 37 | s.resource = 'LWCalendar/LWCalendar.bundle' 38 | s.documentation_url = 'https://github.com/luwei2012/LWCalendar/wiki' 39 | s.requires_arc = true 40 | end 41 | -------------------------------------------------------------------------------- /LWCalendar/LWCalendar.bundle/circle@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luwei2012/LWCalendar/89b127965b144cafa474d8425bd08af9bbc0c185/LWCalendar/LWCalendar.bundle/circle@2x.png -------------------------------------------------------------------------------- /LWCalendar/LWCalendar.bundle/end_filter@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luwei2012/LWCalendar/89b127965b144cafa474d8425bd08af9bbc0c185/LWCalendar/LWCalendar.bundle/end_filter@2x.png -------------------------------------------------------------------------------- /LWCalendar/LWCalendar.bundle/start_filter@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/luwei2012/LWCalendar/89b127965b144cafa474d8425bd08af9bbc0c185/LWCalendar/LWCalendar.bundle/start_filter@2x.png -------------------------------------------------------------------------------- /LWCalendar/LWCalendarHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // LWCalendarHeader.h 3 | // PriceCalender 4 | // 5 | // Created by luwei on 2017/1/4. 6 | // Copyright © 2017年 HarrisHan. All rights reserved. 7 | // 8 | 9 | #ifndef LWCalendarHeader_h 10 | #define LWCalendarHeader_h 11 | 12 | #import "LWDatePickerDialog.h" 13 | #import "LWDateHelper.h" 14 | #import "LWCalendarManager.h" 15 | #import "LWCalendarView.h" 16 | #import "LWDayView.h" 17 | #import "LWMonthView.h" 18 | #import "LWWeekView.h" 19 | #import "LWDatePickerView.h" 20 | #import "LWDateIndicator.h" 21 | #import "LWWeekIndicator.h" 22 | #import "LWDatePickerBuilder.h" 23 | #import "NSBundle+LWCalendar.h" 24 | 25 | //日期选择器的通知事件 26 | //选中某个日期后的本地通知 27 | #define LWDAYVIEW_CHANGE_STATE (@"LWChangeState") 28 | //手动设置开始、结束日期的本地通知 一般是在Dialog初始化时设置开始和结束时间 用于calendarView通知dayView更新自己的状态 calendarView和dayView隔了很多层,因此使用本地通知的方式 29 | #define LWDAYVIEW_UPDATE_STATE (@"LWUpdateState") 30 | //dayView点击事件,用纸calendarView更新From和To时间的显示需要更新 31 | #define LWDAYVIEW_DATE_CHANGED (@"LWDateChanged") 32 | 33 | 34 | //颜色工具宏 35 | #define LWHEXCOLOR(rgbValue) [UIColor \ 36 | colorWithRed:((float)((rgbValue & 0xFF0000) >> 16))/255.0 \ 37 | green:((float)((rgbValue & 0x00FF00) >> 8))/255.0 \ 38 | blue:((float)(rgbValue & 0x0000FF))/255.0 \ 39 | alpha:1.0] 40 | 41 | // 图片路径 42 | #define LWCalendarSrcName(file) [@"LWCalendar.bundle" stringByAppendingPathComponent:file] 43 | 44 | #endif /* LWCalendarHeader_h */ 45 | -------------------------------------------------------------------------------- /LWCalendar/LWCalendarManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // LWCalendarManager.h 3 | // Example 4 | // 5 | // Created by Daniel on 2016/10/30. 6 | // Copyright © 2016年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | 12 | typedef NS_ENUM(NSInteger, LWCalendarSelectionType) { 13 | LWCalendarSelectionTypeSingle = 0, // 单选 14 | LWCalendarSelectionTypeMultiple = 1, // 多选 15 | LWCalendarSelectionTypeRange = 2 // 范围选择 16 | }; 17 | 18 | @class LWDayView,LWDateHelper,LWDatePickerDialog; 19 | 20 | @interface LWCalendarManager : NSObject 21 | @property (nonatomic, strong) LWDateHelper *helper; 22 | @property (nonatomic, strong) NSDateFormatter *titleDateFormatter; 23 | @property (nonatomic, strong) NSDateFormatter *dayDateFormatter; 24 | @property (nonatomic, strong) NSDateFormatter *dateFormatter; 25 | 26 | // 多选模式中保存选中的时间 27 | @property (nonatomic, strong)NSMutableArray *selectedDateArray; 28 | 29 | // 选择模式 默认单选 30 | @property (nonatomic, assign) LWCalendarSelectionType selectionType; 31 | 32 | // 之前的时间是否可以被点击选择 33 | @property (nonatomic, assign) BOOL canSelectPastDays; 34 | 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /LWCalendar/LWCalendarManager.m: -------------------------------------------------------------------------------- 1 | // 2 | // LWCalendarManager.m 3 | // Example 4 | // 5 | // Created by Daniel on 2016/10/30. 6 | // Copyright © 2016年 Daniel. All rights reserved. 7 | // 8 | 9 | #import "LWCalendarHeader.h" 10 | 11 | @implementation LWCalendarManager 12 | 13 | -(LWDateHelper *)helper { 14 | if (!_helper) { 15 | _helper = [LWDateHelper new]; 16 | } 17 | return _helper; 18 | } 19 | 20 | - (NSMutableArray *)selectedDateArray { 21 | if (!_selectedDateArray) { 22 | _selectedDateArray = @[].mutableCopy; 23 | } 24 | return _selectedDateArray; 25 | } 26 | 27 | - (NSDateFormatter *)titleDateFormatter { 28 | if (!_titleDateFormatter) { 29 | _titleDateFormatter = [self.helper createDateFormatter]; 30 | _titleDateFormatter.dateFormat = @"yyyy年MM月"; 31 | } 32 | return _titleDateFormatter; 33 | } 34 | 35 | - (NSDateFormatter *)dayDateFormatter { 36 | if (!_dayDateFormatter) { 37 | _dayDateFormatter = [self.helper createDateFormatter]; 38 | _dayDateFormatter.dateFormat = @"dd"; 39 | } 40 | return _dayDateFormatter; 41 | } 42 | 43 | - (NSDateFormatter *)dateFormatter { 44 | if (!_dateFormatter) { 45 | _dateFormatter = [self.helper createDateFormatter]; 46 | _dateFormatter.dateFormat = @"yyyy-MM-dd"; 47 | } 48 | return _dateFormatter; 49 | } 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /LWCalendar/LWCalendarView.h: -------------------------------------------------------------------------------- 1 | // 2 | // LWCalendarView.h 3 | // Example 4 | // 5 | // Created by Daniel on 16/10/28. 6 | // Copyright © 2016年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class LWDatePickerView, LWDayView, LWDatePickerBuilder; 12 | 13 | @interface LWCalendarView : UIScrollView 14 | @property(nonatomic, strong) NSDate *currentDate; 15 | @property(nonatomic, strong) NSDate *startDate; 16 | @property(nonatomic, strong) NSDate *endDate; 17 | 18 | // 选中的按钮(开始和结束) 19 | @property (nonatomic, strong) LWDayView *selectedStartDay; 20 | @property (nonatomic, strong) LWDayView *selectedEndDay; 21 | @property (nonatomic, weak) LWDatePickerView *dateViewDelegate; 22 | @property (nonatomic, weak) LWDatePickerBuilder *dialogBuilder; 23 | 24 | -(void)scrollToDate:(NSDate *)date; 25 | 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /LWCalendar/LWCalendarView.m: -------------------------------------------------------------------------------- 1 | // 2 | // LWCalendarView.m 3 | // Example 4 | // 5 | // Created by Daniel on 16/10/28. 6 | // Copyright © 2016年 Daniel. All rights reserved. 7 | // 8 | 9 | #import "LWCalendarHeader.h" 10 | 11 | @implementation LWCalendarView { 12 | CGSize lastSize; 13 | LWMonthView *monthView1; 14 | LWMonthView *monthView2; 15 | LWMonthView *monthView3; 16 | LWMonthView *monthView4; 17 | LWMonthView *monthView5; 18 | 19 | } 20 | 21 | @synthesize 22 | currentDate = _currentDate, 23 | startDate = _startDate, 24 | endDate = _endDate, 25 | selectedStartDay = _selectedStartDay, 26 | selectedEndDay = _selectedEndDay, 27 | dialogBuilder = _dialogBuilder; 28 | 29 | 30 | 31 | - (instancetype)initWithFrame:(CGRect)frame { 32 | if (self = [super initWithFrame:frame]) { 33 | self.showsHorizontalScrollIndicator = NO; 34 | self.showsVerticalScrollIndicator = NO; 35 | } 36 | return self; 37 | } 38 | 39 | - (void)layoutSubviews { 40 | // 修改大小 41 | [self resizeViewsIfWidthChanged]; 42 | // 滚动 43 | [self viewDidScroll]; 44 | } 45 | 46 | - (void)resizeViewsIfWidthChanged { 47 | CGSize size = self.frame.size; 48 | // 首次加载 49 | if (!lastSize.width) { 50 | [self repositionViews]; 51 | } 52 | 53 | // self的宽改变 54 | if(!lastSize.width || size.width != lastSize.width){ 55 | lastSize = size; 56 | monthView1.frame = CGRectMake(0, monthView1.frame.origin.y, size.width, monthView1.frame.size.height); 57 | monthView2.frame = CGRectMake(0, monthView2.frame.origin.y, size.width, monthView2.frame.size.height); 58 | monthView3.frame = CGRectMake(0, monthView3.frame.origin.y, size.width, monthView3.frame.size.height); 59 | monthView4.frame = CGRectMake(0, monthView4.frame.origin.y, size.width, monthView4.frame.size.height); 60 | monthView5.frame = CGRectMake(0, monthView5.frame.origin.y, size.width, monthView5.frame.size.height); 61 | self.contentSize = CGSizeMake(size.width, monthView1.frame.size.height + monthView2.frame.size.height + monthView3.frame.size.height + monthView4.frame.size.height + monthView5.frame.size.height); 62 | 63 | } 64 | } 65 | 66 | // 首次加载 67 | - (void)repositionViews { 68 | CGSize size = self.frame.size; 69 | 70 | if (!monthView1) { 71 | monthView1 = [[LWMonthView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 0)]; 72 | monthView2 = [[LWMonthView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 0)]; 73 | monthView3 = [[LWMonthView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 0)]; 74 | monthView4 = [[LWMonthView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 0)]; 75 | monthView5 = [[LWMonthView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 0)]; 76 | 77 | monthView1.tag = 1; 78 | monthView2.tag = 2; 79 | monthView3.tag = 3; 80 | monthView4.tag = 4; 81 | monthView5.tag = 5; 82 | 83 | monthView1.calendarDelegate = self; 84 | monthView2.calendarDelegate = self; 85 | monthView3.calendarDelegate = self; 86 | monthView4.calendarDelegate = self; 87 | monthView5.calendarDelegate = self; 88 | 89 | [self addSubview:monthView1]; 90 | [self addSubview:monthView2]; 91 | [self addSubview:monthView3]; 92 | [self addSubview:monthView4]; 93 | [self addSubview:monthView5]; 94 | self.dialogBuilder = self.dialogBuilder; 95 | self.currentDate = _currentDate; 96 | } 97 | 98 | self.contentSize = CGSizeMake(size.width, monthView1.frame.size.height + monthView2.frame.size.height + monthView3.frame.size.height + monthView4.frame.size.height + monthView5.frame.size.height); 99 | self.contentOffset = CGPointMake(0, monthView1.frame.size.height + monthView2.frame.size.height); 100 | [self resetMonthViewsFrame]; 101 | 102 | } 103 | 104 | // 滚动了 105 | - (void)viewDidScroll { 106 | if(self.contentSize.height <= 0){ 107 | return; 108 | } 109 | 110 | if(self.contentOffset.y < monthView1.frame.size.height + monthView2.frame.size.height/2.0){ 111 | // 加载上一页(如果是当前日期的上一个月, 不加载) 112 | [self loadPreviousPage]; 113 | } 114 | else if(self.contentOffset.y > monthView1.frame.size.height + monthView2.frame.size.height + monthView3.frame.size.height/2.0){ 115 | // 加载下一页 116 | [self loadNextPage]; 117 | } 118 | } 119 | 120 | - (void)loadPreviousPage { 121 | 122 | LWMonthView *tmpView = monthView5; 123 | 124 | monthView5 = monthView4; 125 | monthView4 = monthView3; 126 | monthView3 = monthView2; 127 | monthView2 = monthView1; 128 | 129 | monthView1 = tmpView; 130 | 131 | monthView1.date = [self.dateViewDelegate.dialogDelegate.manager.helper addToDate:monthView2.date months:-1]; 132 | 133 | [self resetMonthViewsFrame]; 134 | 135 | self.contentOffset = CGPointMake(0, self.contentOffset.y + monthView1.frame.size.height); 136 | } 137 | 138 | - (void)loadNextPage { 139 | 140 | CGFloat height1 = monthView1.frame.size.height; 141 | 142 | LWMonthView *tmpView = monthView1; 143 | 144 | monthView1 = monthView2; 145 | monthView2 = monthView3; 146 | monthView3 = monthView4; 147 | monthView4 = monthView5; 148 | 149 | monthView5 = tmpView; 150 | monthView5.date = [self.dateViewDelegate.dialogDelegate.manager.helper addToDate:monthView4.date months:1]; 151 | 152 | [self resetMonthViewsFrame]; 153 | 154 | self.contentOffset = CGPointMake(0, self.contentOffset.y - height1); 155 | } 156 | 157 | - (void)resetMonthViewsFrame { 158 | CGSize size = self.frame.size; 159 | 160 | monthView1.frame = CGRectMake(0, 0, size.width, monthView1.frame.size.height); 161 | 162 | monthView2.frame = CGRectMake(0, CGRectGetMaxY(monthView1.frame), size.width, monthView2.frame.size.height); 163 | 164 | monthView3.frame = CGRectMake(0, CGRectGetMaxY(monthView2.frame), size.width, monthView3.frame.size.height); 165 | 166 | monthView4.frame = CGRectMake(0, CGRectGetMaxY(monthView3.frame), size.width, monthView4.frame.size.height); 167 | 168 | monthView5.frame = CGRectMake(0, CGRectGetMaxY(monthView4.frame), size.width, monthView5.frame.size.height); 169 | 170 | self.contentSize = CGSizeMake(size.width, 171 | monthView1.frame.size.height + monthView2.frame.size.height + monthView3.frame.size.height + monthView4.frame.size.height + monthView5.frame.size.height); 172 | } 173 | 174 | 175 | -(void)scrollToDate:(NSDate *)date{ 176 | LWDateHelper *helper = self.dateViewDelegate.dialogDelegate.manager.helper; 177 | int distance = [helper date:date distanceFrom:monthView3.date]; 178 | monthView1.date = [self.dateViewDelegate.dialogDelegate.manager.helper addToDate:date months:-2]; 179 | monthView2.date = [self.dateViewDelegate.dialogDelegate.manager.helper addToDate:date months:-1]; 180 | monthView3.date = date; 181 | monthView4.date = [self.dateViewDelegate.dialogDelegate.manager.helper addToDate:date months:1]; 182 | monthView5.date = [self.dateViewDelegate.dialogDelegate.manager.helper addToDate:date months:2]; 183 | [self resetMonthViewsFrame]; 184 | if (distance > 0) { 185 | //应该向上滚动 186 | self.contentOffset = CGPointMake(0, monthView1.frame.size.height + monthView2.frame.size.height * 0.5); 187 | }else if(distance < 0){ 188 | //应该向下滚动 189 | self.contentOffset = CGPointMake(0, monthView1.frame.size.height + monthView2.frame.size.height + monthView3.frame.size.height/2.0); 190 | } 191 | [self setContentOffset:CGPointMake(0, monthView1.frame.size.height + monthView2.frame.size.height) animated:true]; 192 | } 193 | 194 | #pragma mark Get and Set 195 | //每次取值时首先同步一次startDate 196 | -(NSDate *)startDate{ 197 | if (_selectedStartDay) { 198 | _startDate = _selectedStartDay.date; 199 | } 200 | return _startDate; 201 | } 202 | 203 | //每次取值时首先同步一次endDate 204 | -(NSDate *)endDate{ 205 | if (_selectedEndDay) { 206 | _endDate = _selectedEndDay.date; 207 | } 208 | return _endDate; 209 | } 210 | 211 | -(void)setCurrentDate:(NSDate *)currentDate{ 212 | _currentDate = currentDate; 213 | monthView1.date = [self.dateViewDelegate.dialogDelegate.manager.helper addToDate:_currentDate months:-2]; 214 | monthView2.date = [self.dateViewDelegate.dialogDelegate.manager.helper addToDate:_currentDate months:-1]; 215 | monthView3.date = _currentDate; 216 | monthView4.date = [self.dateViewDelegate.dialogDelegate.manager.helper addToDate:_currentDate months:1]; 217 | monthView5.date = [self.dateViewDelegate.dialogDelegate.manager.helper addToDate:_currentDate months:2]; 218 | } 219 | 220 | -(void)setStartDate:(NSDate *)startDate{ 221 | _startDate = startDate; 222 | //首先需要清空选中的LWDayView 否则LWDayView在取startDate值时会将startDate覆盖回来 223 | if (_selectedStartDay) { 224 | _selectedStartDay.selected = false; 225 | _selectedStartDay = nil; 226 | } 227 | [[NSNotificationCenter defaultCenter] postNotificationName:LWDAYVIEW_UPDATE_STATE object:nil]; 228 | } 229 | 230 | -(void)setEndDate:(NSDate *)endDate{ 231 | _endDate = endDate; 232 | //首先需要清空选中的LWDayView 否则LWDayView在取endDate值时会将endDate覆盖回来 233 | if (_selectedEndDay) { 234 | _selectedEndDay.selected = false; 235 | _selectedEndDay = nil; 236 | } 237 | [[NSNotificationCenter defaultCenter] postNotificationName:LWDAYVIEW_UPDATE_STATE object:nil]; 238 | } 239 | 240 | -(void)setSelectedStartDay:(LWDayView *)selectedStartDay{ 241 | _selectedStartDay = selectedStartDay; 242 | if (_selectedStartDay) { 243 | _startDate = _selectedStartDay.date; 244 | }else{ 245 | _startDate = nil; 246 | } 247 | } 248 | 249 | -(void)setSelectedEndDay:(LWDayView *)selectedEndDay{ 250 | _selectedEndDay = selectedEndDay; 251 | if (_selectedEndDay) { 252 | _endDate = _selectedEndDay.date; 253 | }else{ 254 | _endDate = nil; 255 | } 256 | } 257 | 258 | -(void)setDialogBuilder:(LWDatePickerBuilder *)dialogBuilder{ 259 | if (dialogBuilder && _dialogBuilder != dialogBuilder) { 260 | _dialogBuilder = dialogBuilder; 261 | [self updateWithBuilder:dialogBuilder]; 262 | } 263 | } 264 | 265 | -(LWDatePickerBuilder *)dialogBuilder{ 266 | if(_dialogBuilder == nil){ 267 | if (self.dateViewDelegate) { 268 | _dialogBuilder = self.dateViewDelegate.dialogBuilder; 269 | }else{ 270 | _dialogBuilder = [LWDatePickerBuilder defaultBuilder]; 271 | } 272 | } 273 | return _dialogBuilder; 274 | } 275 | 276 | #pragma mark 根据Build参数更新UI或者约束 277 | -(void)updateWithBuilder:(LWDatePickerBuilder *)builder{ 278 | //更新month样式 279 | if (monthView1) { 280 | monthView1.dialogBuilder = builder; 281 | monthView2.dialogBuilder = builder; 282 | monthView3.dialogBuilder = builder; 283 | monthView4.dialogBuilder = builder; 284 | monthView5.dialogBuilder = builder; 285 | } 286 | } 287 | 288 | 289 | @end 290 | -------------------------------------------------------------------------------- /LWCalendar/LWDateHelper.h: -------------------------------------------------------------------------------- 1 | // 2 | // JTDateHelper.h 3 | // JTCalendar 4 | // 5 | // Created by Jonathan Tribouharet 6 | // 7 | 8 | #import 9 | 10 | @interface LWDateHelper : NSObject 11 | 12 | - (NSCalendar *)calendar; 13 | - (NSDateFormatter *)createDateFormatter; 14 | 15 | // 在某日期上加几月/天/日 16 | - (NSDate *)addToDate:(NSDate *)date months:(NSInteger)months; 17 | - (NSDate *)addToDate:(NSDate *)date weeks:(NSInteger)weeks; 18 | - (NSDate *)addToDate:(NSDate *)date days:(NSInteger)days; 19 | 20 | // Must be less or equal to 6 21 | - (NSUInteger)numberOfWeeks:(NSDate *)date; 22 | 23 | // 第一天 24 | - (NSDate *)firstDayOfMonth:(NSDate *)date; 25 | - (NSDate *)firstWeekDayOfMonth:(NSDate *)date; 26 | - (NSDate *)firstWeekDayOfWeek:(NSDate *)date; 27 | 28 | - (NSDate *)lastDayOfMonth:(NSDate *)date; 29 | 30 | // 判断是否是同一个月/周/天 31 | - (BOOL)date:(NSDate *)dateA isTheSameMonthThan:(NSDate *)dateB; 32 | - (BOOL)date:(NSDate *)dateA isTheSameWeekThan:(NSDate *)dateB; 33 | - (BOOL)date:(NSDate *)dateA isTheSameDayThan:(NSDate *)dateB; 34 | 35 | // 判断是否在某个日期之前/之后 36 | - (BOOL)date:(NSDate *)dateA isEqualOrBefore:(NSDate *)dateB; 37 | - (BOOL)date:(NSDate *)dateA isEqualOrAfter:(NSDate *)dateB; 38 | 39 | // 判断是否在某个日期之前/之后 40 | - (BOOL)date:(NSDate *)dateA isBefore:(NSDate *)dateB; 41 | - (BOOL)date:(NSDate *)dateA isAfter:(NSDate *)dateB; 42 | 43 | // 判断是否在某个时间段之内 44 | - (BOOL)date:(NSDate *)date isEqualOrAfter:(NSDate *)startDate andEqualOrBefore:(NSDate *)endDate; 45 | - (BOOL)date:(NSDate *)date isAfter:(NSDate *)startDate andBefore:(NSDate *)endDate; 46 | 47 | - (int)date:(NSDate *)date distanceFrom:(NSDate *)destDate; 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /LWCalendar/LWDateHelper.m: -------------------------------------------------------------------------------- 1 | // 2 | // JTDateHelper.m 3 | // JTCalendar 4 | // 5 | // Created by Jonathan Tribouharet 6 | // 7 | 8 | #import "LWDateHelper.h" 9 | 10 | @interface LWDateHelper (){ 11 | NSCalendar *_calendar; 12 | } 13 | 14 | @end 15 | 16 | @implementation LWDateHelper 17 | 18 | - (NSCalendar *)calendar 19 | { 20 | if(!_calendar){ 21 | #ifdef __IPHONE_8_0 22 | _calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; 23 | #else 24 | _calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; 25 | #endif 26 | _calendar.timeZone = [NSTimeZone localTimeZone]; 27 | _calendar.locale = [NSLocale currentLocale]; 28 | } 29 | 30 | return _calendar; 31 | } 32 | 33 | - (NSDateFormatter *)createDateFormatter 34 | { 35 | NSDateFormatter *dateFormatter = [NSDateFormatter new]; 36 | 37 | dateFormatter.timeZone = self.calendar.timeZone; 38 | dateFormatter.locale = self.calendar.locale; 39 | 40 | return dateFormatter; 41 | } 42 | 43 | #pragma mark - Operations 44 | 45 | - (NSDate *)addToDate:(NSDate *)date months:(NSInteger)months 46 | { 47 | NSDateComponents *components = [NSDateComponents new]; 48 | components.month = months; 49 | return [self.calendar dateByAddingComponents:components toDate:date options:0]; 50 | } 51 | 52 | - (NSDate *)addToDate:(NSDate *)date weeks:(NSInteger)weeks 53 | { 54 | NSDateComponents *components = [NSDateComponents new]; 55 | components.day = 7 * weeks; 56 | return [self.calendar dateByAddingComponents:components toDate:date options:0]; 57 | } 58 | 59 | - (NSDate *)addToDate:(NSDate *)date days:(NSInteger)days 60 | { 61 | NSDateComponents *components = [NSDateComponents new]; 62 | components.day = days; 63 | return [self.calendar dateByAddingComponents:components toDate:date options:0]; 64 | } 65 | 66 | #pragma mark - Helpers 67 | 68 | - (NSUInteger)numberOfWeeks:(NSDate *)date 69 | { 70 | NSDate *firstDay = [self firstDayOfMonth:date]; 71 | NSDate *lastDay = [self lastDayOfMonth:date]; 72 | 73 | NSDateComponents *componentsA = [self.calendar components:NSCalendarUnitWeekOfYear fromDate:firstDay]; 74 | NSDateComponents *componentsB = [self.calendar components:NSCalendarUnitWeekOfYear fromDate:lastDay]; 75 | 76 | // weekOfYear may return 53 for the first week of the year 77 | return (componentsB.weekOfYear - componentsA.weekOfYear + 52 + 1) % 52; 78 | } 79 | 80 | - (NSDate *)firstDayOfMonth:(NSDate *)date 81 | { 82 | NSDateComponents *componentsCurrentDate = [self.calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitWeekday|NSCalendarUnitWeekOfMonth fromDate:date]; 83 | 84 | NSDateComponents *componentsNewDate = [NSDateComponents new]; 85 | 86 | componentsNewDate.year = componentsCurrentDate.year; 87 | componentsNewDate.month = componentsCurrentDate.month; 88 | componentsNewDate.weekOfMonth = 1; 89 | componentsNewDate.day = 1; 90 | 91 | return [self.calendar dateFromComponents:componentsNewDate]; 92 | } 93 | 94 | - (NSDate *)lastDayOfMonth:(NSDate *)date 95 | { 96 | NSDateComponents *componentsCurrentDate = [self.calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitWeekday|NSCalendarUnitWeekOfMonth fromDate:date]; 97 | 98 | NSDateComponents *componentsNewDate = [NSDateComponents new]; 99 | 100 | componentsNewDate.year = componentsCurrentDate.year; 101 | componentsNewDate.month = componentsCurrentDate.month + 1; 102 | componentsNewDate.day = 0; 103 | 104 | return [self.calendar dateFromComponents:componentsNewDate]; 105 | } 106 | 107 | - (NSDate *)firstWeekDayOfMonth:(NSDate *)date 108 | { 109 | NSDate *firstDayOfMonth = [self firstDayOfMonth:date]; 110 | return [self firstWeekDayOfWeek:firstDayOfMonth]; 111 | } 112 | 113 | - (NSDate *)firstWeekDayOfWeek:(NSDate *)date 114 | { 115 | NSDateComponents *componentsCurrentDate = [self.calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitWeekday|NSCalendarUnitWeekOfMonth fromDate:date]; 116 | 117 | NSDateComponents *componentsNewDate = [NSDateComponents new]; 118 | 119 | componentsNewDate.year = componentsCurrentDate.year; 120 | componentsNewDate.month = componentsCurrentDate.month; 121 | componentsNewDate.weekOfMonth = componentsCurrentDate.weekOfMonth; 122 | componentsNewDate.weekday = self.calendar.firstWeekday; 123 | 124 | return [self.calendar dateFromComponents:componentsNewDate]; 125 | } 126 | 127 | #pragma mark - Comparaison 128 | 129 | - (BOOL)date:(NSDate *)dateA isTheSameMonthThan:(NSDate *)dateB 130 | { 131 | if (!dateA || !dateB) { 132 | return false; 133 | } 134 | NSDateComponents *componentsA = [self.calendar components:NSCalendarUnitYear|NSCalendarUnitMonth fromDate:dateA]; 135 | NSDateComponents *componentsB = [self.calendar components:NSCalendarUnitYear|NSCalendarUnitMonth fromDate:dateB]; 136 | 137 | return componentsA.year == componentsB.year && componentsA.month == componentsB.month; 138 | } 139 | 140 | - (BOOL)date:(NSDate *)dateA isTheSameWeekThan:(NSDate *)dateB 141 | { 142 | if (!dateA || !dateB) { 143 | return false; 144 | } 145 | NSDateComponents *componentsA = [self.calendar components:NSCalendarUnitYear|NSCalendarUnitWeekOfYear fromDate:dateA]; 146 | NSDateComponents *componentsB = [self.calendar components:NSCalendarUnitYear|NSCalendarUnitWeekOfYear fromDate:dateB]; 147 | 148 | return componentsA.year == componentsB.year && componentsA.weekOfYear == componentsB.weekOfYear; 149 | } 150 | 151 | - (BOOL)date:(NSDate *)dateA isTheSameDayThan:(NSDate *)dateB 152 | { 153 | if (!dateA || !dateB) { 154 | return false; 155 | } 156 | NSDateComponents *componentsA = [self.calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:dateA]; 157 | NSDateComponents *componentsB = [self.calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:dateB]; 158 | 159 | return componentsA.year == componentsB.year && componentsA.month == componentsB.month && componentsA.day == componentsB.day; 160 | } 161 | 162 | - (BOOL)date:(NSDate *)dateA isEqualOrBefore:(NSDate *)dateB 163 | { 164 | if([dateA compare:dateB] == NSOrderedAscending || [self date:dateA isTheSameDayThan:dateB]){ 165 | return YES; 166 | } 167 | 168 | return NO; 169 | } 170 | 171 | - (BOOL)date:(NSDate *)dateA isEqualOrAfter:(NSDate *)dateB 172 | { 173 | if([dateA compare:dateB] == NSOrderedDescending || [self date:dateA isTheSameDayThan:dateB]){ 174 | return YES; 175 | } 176 | 177 | return NO; 178 | } 179 | 180 | - (BOOL)date:(NSDate *)dateA isBefore:(NSDate *)dateB { 181 | if([dateA compare:dateB] == NSOrderedAscending){ 182 | return YES; 183 | } 184 | 185 | return NO; 186 | } 187 | 188 | - (BOOL)date:(NSDate *)dateA isAfter:(NSDate *)dateB { 189 | if([dateA compare:dateB] == NSOrderedDescending){ 190 | return YES; 191 | } 192 | 193 | return NO; 194 | } 195 | 196 | - (BOOL)date:(NSDate *)date isEqualOrAfter:(NSDate *)startDate andEqualOrBefore:(NSDate *)endDate 197 | { 198 | if([self date:date isEqualOrAfter:startDate] && [self date:date isEqualOrBefore:endDate]){ 199 | return YES; 200 | } 201 | 202 | return NO; 203 | } 204 | 205 | - (BOOL)date:(NSDate *)date isAfter:(NSDate *)startDate andBefore:(NSDate *)endDate { 206 | if([self date:date isAfter:startDate] && [self date:date isBefore:endDate]){ 207 | return YES; 208 | } 209 | 210 | return NO; 211 | } 212 | 213 | - (int)date:(NSDate *)date distanceFrom:(NSDate *)destDate{ 214 | NSDateComponents *componentsCurrentDate = [self.calendar components:NSCalendarUnitYear|NSCalendarUnitMonth fromDate:date]; 215 | int yearOfDate = (int) componentsCurrentDate.year; 216 | int monthOfDate = (int) componentsCurrentDate.month; 217 | componentsCurrentDate = [self.calendar components:NSCalendarUnitYear|NSCalendarUnitMonth fromDate:destDate]; 218 | int monthOfDestDate = (int) componentsCurrentDate.month; 219 | int yearOfDestDate = (int) componentsCurrentDate.year; 220 | return monthOfDate - monthOfDestDate + 12 * (yearOfDate - yearOfDestDate); 221 | } 222 | 223 | @end 224 | 225 | -------------------------------------------------------------------------------- /LWCalendar/LWDateIndicator.h: -------------------------------------------------------------------------------- 1 | // 2 | // DateIndicator.h 3 | // PriceCalender 4 | // 5 | // Created by luwei on 2017/1/4. 6 | // Copyright © 2017年 HarrisHan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class LWDatePickerView, LWDatePickerBuilder; 12 | 13 | @interface LWDateIndicator : UIView 14 | 15 | @property(nonatomic, strong) UILabel *titleLabel; 16 | @property(nonatomic, strong) UILabel *dateLabel; 17 | @property(nonatomic, strong) NSDate *date; 18 | @property(nonatomic, weak) LWDatePickerView *dateViewDelegate; 19 | @property(nonatomic, weak) LWDatePickerBuilder *dialogBuilder; 20 | 21 | +(instancetype)initWithTitle:(NSString *)title Date:(NSDate *)date Delegate:(LWDatePickerView *)delegate; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /LWCalendar/LWDateIndicator.m: -------------------------------------------------------------------------------- 1 | // 2 | // DateIndicator.m 3 | // PriceCalender 4 | // 5 | // Created by luwei on 2017/1/4. 6 | // Copyright © 2017年 HarrisHan. All rights reserved. 7 | // 8 | 9 | #import "LWCalendarHeader.h" 10 | 11 | @interface LWDateIndicator () 12 | @property (nonatomic, strong) NSMutableArray *titleLabelConstraints; 13 | @property (nonatomic, strong) NSMutableArray *dateLabelConstraints; 14 | @end 15 | 16 | @implementation LWDateIndicator 17 | @synthesize 18 | titleLabel = _titleLabel, 19 | dateLabel = _dateLabel, 20 | date = _date, 21 | dialogBuilder = _dialogBuilder; 22 | 23 | +(instancetype)initWithTitle:(NSString *)title Date:(NSDate *)date Delegate:(LWDatePickerView *)delegate{ 24 | LWDateIndicator *tmp = [[LWDateIndicator alloc] init]; 25 | if (tmp) { 26 | tmp.titleLabelConstraints = [NSMutableArray new]; 27 | tmp.dateLabelConstraints = [NSMutableArray new]; 28 | //初始化操作 29 | tmp.dateViewDelegate = delegate; 30 | tmp.titleLabel.text = title; 31 | tmp.date = date; 32 | [tmp updateWithBuilder:tmp.dialogBuilder]; 33 | } 34 | return tmp; 35 | } 36 | 37 | 38 | #pragma mark Get and Set 39 | -(UILabel *)titleLabel{ 40 | if (_titleLabel == nil) { 41 | _titleLabel = [[UILabel alloc] init]; 42 | _titleLabel.textAlignment = NSTextAlignmentCenter; 43 | _titleLabel.translatesAutoresizingMaskIntoConstraints = NO; 44 | [self addSubview:_titleLabel]; 45 | } 46 | return _titleLabel; 47 | } 48 | 49 | -(UILabel *)dateLabel{ 50 | if (_dateLabel == nil) { 51 | _dateLabel = [[UILabel alloc] init]; 52 | _dateLabel.textAlignment = NSTextAlignmentCenter; 53 | _dateLabel.translatesAutoresizingMaskIntoConstraints = NO; 54 | [self addSubview:_dateLabel]; 55 | 56 | 57 | } 58 | return _dateLabel; 59 | } 60 | 61 | -(void)setDate:(NSDate *)date{ 62 | //更新date 63 | _date = date; 64 | if (date) { 65 | // 某月 66 | NSString *dateStr = [self.dateViewDelegate.dialogDelegate.manager.dateFormatter stringFromDate:date]; 67 | self.dateLabel.text = dateStr; 68 | }else{ 69 | self.dateLabel.text = @""; 70 | } 71 | } 72 | 73 | -(void)setDialogBuilder:(LWDatePickerBuilder *)dialogBuilder{ 74 | if (dialogBuilder && _dialogBuilder != dialogBuilder) { 75 | _dialogBuilder = dialogBuilder; 76 | [self updateWithBuilder:dialogBuilder]; 77 | } 78 | } 79 | 80 | -(LWDatePickerBuilder *)dialogBuilder{ 81 | if(_dialogBuilder == nil){ 82 | if (self.dateViewDelegate) { 83 | _dialogBuilder = self.dateViewDelegate.dialogBuilder; 84 | }else{ 85 | _dialogBuilder = [LWDatePickerBuilder defaultBuilder]; 86 | } 87 | } 88 | return _dialogBuilder; 89 | } 90 | 91 | #pragma mark 根据Build参数更新UI或者约束 92 | -(void)updateWithBuilder:(LWDatePickerBuilder *)builder{ 93 | //title设置 94 | self.titleLabel.font = self.dialogBuilder.LWDateIndicatorTitleFont; 95 | self.titleLabel.textColor = self.dialogBuilder.LWDatePickerViewDefaultTextColor; 96 | self.titleLabel.backgroundColor = self.dialogBuilder.LWDatePickerViewDefaultColor; 97 | //date设置 98 | self.dateLabel.font = self.dialogBuilder.LWDateIndicatorDateFont; 99 | self.dateLabel.textColor= self.dialogBuilder.LWDatePickerViewSelectedTextColor; 100 | self.dateLabel.backgroundColor = self.dialogBuilder.LWDatePickerViewSelectedColor; 101 | //约束更新 102 | [self updateConstraintForTitleLabel]; 103 | [self updateConstraintForDateLabel]; 104 | } 105 | 106 | #pragma mark 约束相关 107 | -(void)updateConstraintForTitleLabel{ 108 | [self removeConstraints:self.titleLabelConstraints]; 109 | [self.titleLabelConstraints removeAllObjects]; 110 | //添加约束 111 | NSLayoutConstraint *viewLeft = [NSLayoutConstraint constraintWithItem:self.titleLabel attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0.0]; 112 | NSLayoutConstraint *viewRight = [NSLayoutConstraint constraintWithItem:self.titleLabel attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0]; 113 | NSLayoutConstraint *viewTop = [NSLayoutConstraint constraintWithItem:self.titleLabel attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0]; 114 | NSLayoutConstraint *viewHeight = [NSLayoutConstraint constraintWithItem:self.titleLabel attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:self.dialogBuilder.LWDateIndicatorTitleHeight]; 115 | [self addConstraint:viewLeft]; 116 | [self addConstraint:viewRight]; 117 | [self addConstraint:viewTop]; 118 | [self addConstraint:viewHeight]; 119 | [self.titleLabelConstraints addObject:viewLeft]; 120 | [self.titleLabelConstraints addObject:viewRight]; 121 | [self.titleLabelConstraints addObject:viewTop]; 122 | [self.titleLabelConstraints addObject:viewHeight]; 123 | } 124 | 125 | -(void)updateConstraintForDateLabel{ 126 | [self removeConstraints:self.dateLabelConstraints]; 127 | [self.dateLabelConstraints removeAllObjects]; 128 | //添加约束 129 | NSLayoutConstraint *viewLeft = [NSLayoutConstraint constraintWithItem:self.dateLabel attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0.0]; 130 | NSLayoutConstraint *viewRight = [NSLayoutConstraint constraintWithItem:self.dateLabel attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0]; 131 | NSLayoutConstraint *viewTop = [NSLayoutConstraint constraintWithItem:self.dateLabel attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.titleLabel attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0]; 132 | NSLayoutConstraint *viewBottom = [NSLayoutConstraint constraintWithItem:self.dateLabel attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0]; 133 | [self addConstraint:viewLeft]; 134 | [self addConstraint:viewRight]; 135 | [self addConstraint:viewTop]; 136 | [self addConstraint:viewBottom]; 137 | [self.dateLabelConstraints addObject:viewLeft]; 138 | [self.dateLabelConstraints addObject:viewRight]; 139 | [self.dateLabelConstraints addObject:viewTop]; 140 | [self.dateLabelConstraints addObject:viewBottom]; 141 | } 142 | 143 | @end 144 | -------------------------------------------------------------------------------- /LWCalendar/LWDatePickerBuilder.h: -------------------------------------------------------------------------------- 1 | // 2 | // LWDatePickerBuilder.h 3 | // Pods 4 | // 5 | // Created by luwei on 2017/1/9. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @interface LWDatePickerBuilder : NSObject 12 | 13 | //日期选择器容器的默认配置的圆角 14 | @property (nonatomic, assign) CGFloat LWDatePickerDialogCorner; 15 | //日期选择器容器水平方向边距 决定了选择器的宽度 16 | @property (nonatomic, assign) CGFloat LWDatePickerDialogMarginH; 17 | //日期选择器容器垂直方向边距 决定了选择器的高度 18 | @property (nonatomic, assign) CGFloat LWDatePickerDialogMarginV; 19 | //日期选择器容器显示和隐藏的动画时间 20 | @property (nonatomic, assign) CGFloat LWDatePickerDialogAnimateDutation; 21 | 22 | //选中状态的颜色 这里默认使用的是绿色 23 | @property (nonatomic, strong) UIColor *LWDatePickerViewSelectedColor; 24 | //选中状态的文字颜色 绿色的背景+白色的文字 25 | @property (nonatomic, strong) UIColor *LWDatePickerViewSelectedTextColor; 26 | //默认普通状态颜色 白色背景 27 | @property (nonatomic, strong) UIColor *LWDatePickerViewDefaultColor; 28 | //默认普通状态的文字是黑色 白色背景+黑色文字 29 | @property (nonatomic, strong) UIColor *LWDatePickerViewDefaultTextColor; 30 | //LWDatePickerView阴影的配置参数 31 | @property (nonatomic, assign) CGFloat LWDatePickerViewShadowRadius; 32 | @property (nonatomic, strong) UIColor *LWDatePickerViewShadowColor; 33 | @property (nonatomic, assign) CGSize LWDatePickerViewShadowOffset; 34 | @property (nonatomic, assign) CGFloat LWDatePickerViewShadowOpacity; 35 | 36 | //功能按钮水平方向的间距:主要是指cancel和confirm按钮之间的间距 37 | @property (nonatomic, assign) CGFloat LWDatePickerViewButtonMarginH; 38 | //功能按钮的高度:主要是指cancel和confirm按钮的高度 39 | @property (nonatomic, assign) CGFloat LWDatePickerViewButtonHeight; 40 | //功能按钮的宽度相对LWDatePickerView宽度的比例:主要是指cancel和confirm按钮的宽度 41 | @property (nonatomic, assign) CGFloat LWDatePickerViewButtonWidth; 42 | //功能按钮的字体大小:主要是指cancel和confirm按钮的字体 43 | @property (nonatomic, strong) UIFont *LWDatePickerViewButtonFont ; 44 | 45 | //指示器的title默认高度 整个指示器高度为title高度+日期提示label高度 日期提示label高度默认为title高度的1.5倍 46 | @property (nonatomic, assign) CGFloat LWDateIndicatorTitleHeight; 47 | //指示器上的title字体大小 48 | @property (nonatomic, strong) UIFont *LWDateIndicatorTitleFont; 49 | //指示器上的选中日期提示文字的字体大小 50 | @property (nonatomic, strong) UIFont *LWDateIndicatorDateFont; 51 | 52 | //LWCalendarView设置 53 | //月历距离父容器的左右留白 54 | @property (nonatomic, assign) CGFloat LWCalendarMarginH; 55 | //月历行间距 56 | @property (nonatomic, assign) CGFloat LWCalendarLineGap; 57 | //月历列间距 58 | @property (nonatomic, assign) CGFloat LWCalendarRowGap; 59 | //月历有一个标题 显示当前月历是2016年8月 标题字体大小 60 | @property (nonatomic, strong) UIFont *LWCalendarTitleFont; 61 | //月历标题高度 62 | @property (nonatomic, assign) CGFloat LWCalendarTitleHeight; 63 | 64 | //week指示器 字体颜色 65 | @property (nonatomic, strong) UIColor *LWWeekIndicatorTextColor; 66 | //week指示器 字体大小 67 | @property (nonatomic, strong) UIFont *LWWeekIndicatorTextFont; 68 | //week指示器 高度 69 | @property (nonatomic, assign) CGFloat LWWeekIndicatorHeight; 70 | 71 | //日期选择器中LWDayView的文字字体大小 72 | @property (nonatomic, strong) UIFont *LWDayViewFont; 73 | 74 | +(LWDatePickerBuilder *)defaultBuilder; 75 | 76 | @end 77 | -------------------------------------------------------------------------------- /LWCalendar/LWDatePickerBuilder.m: -------------------------------------------------------------------------------- 1 | // 2 | // LWDatePickerBuilder.m 3 | // Pods 4 | // 5 | // Created by luwei on 2017/1/9. 6 | // 7 | // 8 | 9 | #import "LWCalendarHeader.h" 10 | 11 | #define UNINITIALIZED_FLOAT (-MAXFLOAT) 12 | #define UNINITIALIZED_CGSIZE (CGSizeMake(UNINITIALIZED_FLOAT,UNINITIALIZED_FLOAT)) 13 | 14 | //日期选择器容器的默认配置的圆角 --LWDatePickerDialog 15 | #define LWDATEPICKERDIALOG_CORNER (4) 16 | //日期选择器容器水平方向边距 决定了选择器的宽度 17 | #define LWDATEPICKERDIALOG_MARGIN_H (60) 18 | //日期选择器容器垂直方向边距 决定了选择器的高度 19 | #define LWDATEPICKERDIALOG_MARGIN_V (60) 20 | //日期选择器容器显示和隐藏的动画时间 21 | #define ANIMATE_DUTATION (0.5) 22 | 23 | 24 | //日期选择器 月历View的默认配置 --LWDatePickerView 25 | //选中状态的颜色 这里默认使用的是绿色 26 | #define LWDATEPICKERVIEW_SELECTED_COLOR LWHEXCOLOR(0x128963) 27 | //选中状态的文字颜色 绿色的背景+白色的文字 28 | #define LWDATEPICKERVIEW_SELECTED_TEXT_COLOR [UIColor whiteColor] 29 | //默认普通状态的颜色 这里默认使用的是白色 30 | #define LWDATEPICKERVIEW_DEFAULT_COLOR [UIColor whiteColor] 31 | //默认普通状态的文字是黑色 白色背景+黑色文字 32 | #define LWDATEPICKERVIEW_DEFAULT_TEXT_COLOR [UIColor blackColor] 33 | //LWDatePickerView阴影的配置参数 34 | #define LWDATEPICKERVIEW_SHADOW_RADIUS (8.0) 35 | #define LWDATEPICKERVIEW_SHADOW_COLOR ([UIColor blackColor]) 36 | #define LWDATEPICKERVIEW_SHADOW_OFFSET (CGSizeMake(2, 2)) 37 | #define LWDATEPICKERVIEW_SHADOW_OPACITY (0.6) 38 | 39 | //LWCalendarView设置 40 | //月历距离父容器的左右留白 41 | #define LWCALENDARVIEW_MARGIN_H (10.0) 42 | //月历行间距 43 | #define LWCALENDARVIEW_LINE_GAP (4.0) 44 | //月历列间距 45 | #define LWCALENDARVIEW_ROW_GAP (4.0) 46 | //月历有一个标题 显示当前月历是2016年8月 标题字体大小 47 | #define LWCALENDARVIEW_TITLE_FONT_SIZE (15) 48 | //月历标题高度 49 | #define LWCALENDARVIEW_TITLE_HEIGHT (40.0) 50 | 51 | //功能按钮水平方向的间距:主要是指cancel和confirm按钮之间的间距 52 | #define LWDATEPICKERVIEW_BUTTON_MARGIN_H (5) 53 | //功能按钮的高度:主要是指cancel和confirm按钮的高度 54 | #define LWDATEPICKERVIEW_BUTTON_HEIGHT (48) 55 | //功能按钮的宽度相对LWDatePickerView宽度的比例:主要是指cancel和confirm按钮的宽度 56 | #define LWDATEPICKERVIEW_BUTTON_WIDTH (0.25) 57 | //功能按钮的字体大小:主要是指cancel和confirm按钮的字体大小 58 | #define LWDATEPICKERVIEW_BUTTON_FONT_SIZE (16) 59 | 60 | //From/To指示器的默认配置 --LWDateIndicator 61 | //From/To指示器的title默认高度 整个指示器高度为title高度+日期提示label高度 日期提示label高度默认为title高度的1.5倍 62 | #define LWDATEINICATOR_TITLE_HEIGHT (48) 63 | //From/To指示器上的title字体大小 64 | #define LWDATEINICATOR_TITLE_FONT_SIZE (16) 65 | //From/To指示器上的选中日期提示文字的字体大小 66 | #define LWDATEINICATOR_DATE_FONT_SIZE (16) 67 | 68 | //week指示器 字体颜色 69 | #define LWWEEKINICATOR_TEXT_COLOR LWHEXCOLOR(0x666666) 70 | //week指示器 字体大小 71 | #define LWWEEKINICATOR_FONT_SIZE (12) 72 | //week指示器 高度 73 | #define LWWEEKINICATOR_HEIGHT (20.0) 74 | 75 | //日期选择器中LWDayView的文字字体大小 76 | #define LWDAYVIEW_FONT_SIZE (12) 77 | 78 | 79 | static LWDatePickerBuilder *defaultInstance; 80 | 81 | @implementation LWDatePickerBuilder 82 | 83 | @synthesize 84 | LWDatePickerDialogCorner = _LWDatePickerDialogCorner, 85 | LWDatePickerDialogMarginH = _LWDatePickerDialogMarginH, 86 | LWDatePickerDialogMarginV = _LWDatePickerDialogMarginV, 87 | LWDatePickerDialogAnimateDutation = _LWDatePickerDialogAnimateDutation, 88 | 89 | LWDatePickerViewSelectedColor = _LWDatePickerViewSelectedColor, 90 | LWDatePickerViewSelectedTextColor = _LWDatePickerViewSelectedTextColor, 91 | LWDatePickerViewDefaultColor = _LWDatePickerViewDefaultColor, 92 | LWDatePickerViewDefaultTextColor = _LWDatePickerViewDefaultTextColor, 93 | LWDatePickerViewShadowColor = _LWDatePickerViewShadowColor, 94 | LWDatePickerViewShadowRadius = _LWDatePickerViewShadowRadius, 95 | LWDatePickerViewShadowOffset = _LWDatePickerViewShadowOffset, 96 | LWDatePickerViewShadowOpacity = _LWDatePickerViewShadowOpacity, 97 | 98 | LWDatePickerViewButtonMarginH = _LWDatePickerViewButtonMarginH, 99 | LWDatePickerViewButtonHeight = _LWDatePickerViewButtonHeight, 100 | LWDatePickerViewButtonWidth = _LWDatePickerViewButtonWidth, 101 | LWDatePickerViewButtonFont = _LWDatePickerViewButtonFont, 102 | 103 | LWCalendarLineGap = _LWCalendarLineGap, 104 | LWCalendarMarginH = _LWCalendarMarginH, 105 | LWCalendarRowGap = _LWCalendarRowGap, 106 | LWCalendarTitleFont = _LWCalendarTitleFont, 107 | LWCalendarTitleHeight = _LWCalendarTitleHeight, 108 | 109 | LWDateIndicatorTitleHeight = _LWDateIndicatorTitleHeight, 110 | LWDateIndicatorDateFont = _LWDateIndicatorDateFont, 111 | LWDateIndicatorTitleFont = _LWDateIndicatorTitleFont, 112 | 113 | LWWeekIndicatorTextColor = _LWWeekIndicatorTextColor, 114 | LWWeekIndicatorTextFont = _LWWeekIndicatorTextFont, 115 | LWWeekIndicatorHeight = _LWWeekIndicatorHeight, 116 | 117 | LWDayViewFont = _LWDayViewFont; 118 | 119 | -(instancetype)init{ 120 | if (self = [super init]) { 121 | self.LWDatePickerDialogCorner = UNINITIALIZED_FLOAT; 122 | self.LWDatePickerDialogMarginH = UNINITIALIZED_FLOAT; 123 | self.LWDatePickerDialogMarginV = UNINITIALIZED_FLOAT; 124 | self.LWDatePickerDialogAnimateDutation = UNINITIALIZED_FLOAT; 125 | self.LWDatePickerViewShadowRadius = UNINITIALIZED_FLOAT; 126 | self.LWDatePickerViewShadowOffset = UNINITIALIZED_CGSIZE; 127 | self.LWDatePickerViewShadowOpacity = UNINITIALIZED_FLOAT; 128 | 129 | self.LWDatePickerViewButtonMarginH = UNINITIALIZED_FLOAT; 130 | self.LWDatePickerViewButtonHeight = UNINITIALIZED_FLOAT; 131 | self.LWDatePickerViewButtonWidth = UNINITIALIZED_FLOAT; 132 | 133 | self.LWCalendarLineGap = UNINITIALIZED_FLOAT; 134 | self.LWCalendarRowGap = UNINITIALIZED_FLOAT; 135 | self.LWCalendarMarginH = UNINITIALIZED_FLOAT; 136 | self.LWCalendarTitleHeight = UNINITIALIZED_FLOAT; 137 | 138 | self.LWWeekIndicatorHeight = UNINITIALIZED_FLOAT; 139 | 140 | self.LWDateIndicatorTitleHeight = UNINITIALIZED_FLOAT; 141 | } 142 | return self; 143 | } 144 | 145 | +(LWDatePickerBuilder *)defaultBuilder{ 146 | static dispatch_once_t onceToken; 147 | dispatch_once(&onceToken, ^{ 148 | if (!defaultInstance) { 149 | defaultInstance = [[self alloc] init]; 150 | defaultInstance.LWDatePickerDialogCorner = LWDATEPICKERDIALOG_CORNER; 151 | defaultInstance.LWDatePickerDialogMarginH = LWDATEPICKERDIALOG_MARGIN_H; 152 | defaultInstance.LWDatePickerDialogMarginV = LWDATEPICKERDIALOG_MARGIN_V; 153 | defaultInstance.LWDatePickerDialogAnimateDutation = ANIMATE_DUTATION; 154 | 155 | defaultInstance.LWDatePickerViewSelectedColor = LWDATEPICKERVIEW_SELECTED_COLOR; 156 | defaultInstance.LWDatePickerViewSelectedTextColor = LWDATEPICKERVIEW_SELECTED_TEXT_COLOR; 157 | defaultInstance.LWDatePickerViewDefaultColor = LWDATEPICKERVIEW_DEFAULT_COLOR; 158 | defaultInstance.LWDatePickerViewDefaultTextColor = LWDATEPICKERVIEW_DEFAULT_TEXT_COLOR; 159 | defaultInstance.LWDatePickerViewShadowColor = LWDATEPICKERVIEW_SHADOW_COLOR; 160 | defaultInstance.LWDatePickerViewShadowRadius = LWDATEPICKERVIEW_SHADOW_RADIUS; 161 | defaultInstance.LWDatePickerViewShadowOffset = LWDATEPICKERVIEW_SHADOW_OFFSET; 162 | defaultInstance.LWDatePickerViewShadowOpacity = LWDATEPICKERVIEW_SHADOW_OPACITY; 163 | 164 | defaultInstance.LWDatePickerViewButtonMarginH = LWDATEPICKERVIEW_BUTTON_MARGIN_H; 165 | defaultInstance.LWDatePickerViewButtonHeight = LWDATEPICKERVIEW_BUTTON_HEIGHT; 166 | defaultInstance.LWDatePickerViewButtonWidth = LWDATEPICKERVIEW_BUTTON_WIDTH; 167 | defaultInstance.LWDatePickerViewButtonFont = [UIFont boldSystemFontOfSize:LWDATEPICKERVIEW_BUTTON_FONT_SIZE]; 168 | 169 | defaultInstance.LWCalendarTitleHeight = LWCALENDARVIEW_TITLE_HEIGHT; 170 | defaultInstance.LWCalendarTitleFont = [UIFont systemFontOfSize:LWCALENDARVIEW_TITLE_FONT_SIZE]; 171 | defaultInstance.LWCalendarMarginH = LWCALENDARVIEW_MARGIN_H; 172 | defaultInstance.LWCalendarLineGap = LWCALENDARVIEW_LINE_GAP; 173 | defaultInstance.LWCalendarRowGap = LWCALENDARVIEW_ROW_GAP; 174 | 175 | defaultInstance.LWDateIndicatorTitleHeight = LWDATEINICATOR_TITLE_HEIGHT; 176 | defaultInstance.LWDateIndicatorDateFont = [UIFont boldSystemFontOfSize:LWDATEINICATOR_TITLE_FONT_SIZE]; 177 | defaultInstance.LWDateIndicatorTitleFont = [UIFont boldSystemFontOfSize:LWDATEINICATOR_DATE_FONT_SIZE]; 178 | 179 | defaultInstance.LWWeekIndicatorTextColor = LWWEEKINICATOR_TEXT_COLOR; 180 | defaultInstance.LWWeekIndicatorTextFont = [UIFont systemFontOfSize:LWWEEKINICATOR_FONT_SIZE]; 181 | defaultInstance.LWWeekIndicatorHeight = LWWEEKINICATOR_HEIGHT; 182 | 183 | defaultInstance.LWDayViewFont = [UIFont systemFontOfSize:LWDAYVIEW_FONT_SIZE]; 184 | } 185 | }); 186 | //初始化代码 187 | return defaultInstance; 188 | } 189 | 190 | -(CGFloat)LWDatePickerDialogCorner{ 191 | if (_LWDatePickerDialogCorner == UNINITIALIZED_FLOAT) { 192 | _LWDatePickerDialogCorner = [LWDatePickerBuilder defaultBuilder].LWDatePickerDialogCorner; 193 | } 194 | return _LWDatePickerDialogCorner; 195 | } 196 | 197 | -(CGFloat)LWDatePickerDialogMarginH{ 198 | if (_LWDatePickerDialogMarginH == UNINITIALIZED_FLOAT) { 199 | _LWDatePickerDialogMarginH = [LWDatePickerBuilder defaultBuilder].LWDatePickerDialogMarginH; 200 | } 201 | return _LWDatePickerDialogMarginH; 202 | } 203 | 204 | -(CGFloat)LWDatePickerDialogMarginV{ 205 | if (_LWDatePickerDialogMarginV == UNINITIALIZED_FLOAT) { 206 | _LWDatePickerDialogMarginV = [LWDatePickerBuilder defaultBuilder].LWDatePickerDialogMarginV; 207 | } 208 | return _LWDatePickerDialogMarginV; 209 | } 210 | 211 | -(CGFloat)LWDatePickerDialogAnimateDutation{ 212 | if (_LWDatePickerDialogAnimateDutation == UNINITIALIZED_FLOAT) { 213 | _LWDatePickerDialogAnimateDutation = [LWDatePickerBuilder defaultBuilder].LWDatePickerDialogAnimateDutation; 214 | } 215 | return _LWDatePickerDialogAnimateDutation; 216 | } 217 | 218 | -(CGFloat)LWDatePickerViewShadowRadius{ 219 | if (_LWDatePickerViewShadowRadius == UNINITIALIZED_FLOAT) { 220 | _LWDatePickerViewShadowRadius = [LWDatePickerBuilder defaultBuilder].LWDatePickerViewShadowRadius; 221 | } 222 | return _LWDatePickerViewShadowRadius; 223 | } 224 | 225 | -(CGFloat)LWDatePickerViewShadowOpacity{ 226 | if (_LWDatePickerViewShadowOpacity == UNINITIALIZED_FLOAT) { 227 | _LWDatePickerViewShadowOpacity = [LWDatePickerBuilder defaultBuilder].LWDatePickerViewShadowOpacity; 228 | } 229 | return _LWDatePickerViewShadowOpacity; 230 | } 231 | 232 | -(CGFloat)LWDatePickerViewButtonMarginH{ 233 | if (_LWDatePickerViewButtonMarginH == UNINITIALIZED_FLOAT) { 234 | _LWDatePickerViewButtonMarginH = [LWDatePickerBuilder defaultBuilder].LWDatePickerViewButtonMarginH; 235 | } 236 | return _LWDatePickerViewButtonMarginH; 237 | } 238 | 239 | -(CGFloat)LWDatePickerViewButtonHeight{ 240 | if (_LWDatePickerViewButtonHeight == UNINITIALIZED_FLOAT) { 241 | _LWDatePickerViewButtonHeight = [LWDatePickerBuilder defaultBuilder].LWDatePickerViewButtonHeight; 242 | } 243 | return _LWDatePickerViewButtonHeight; 244 | } 245 | 246 | -(CGFloat)LWDatePickerViewButtonWidth{ 247 | if (_LWDatePickerViewButtonWidth == UNINITIALIZED_FLOAT) { 248 | _LWDatePickerViewButtonWidth = [LWDatePickerBuilder defaultBuilder].LWDatePickerViewButtonWidth; 249 | } 250 | return _LWDatePickerViewButtonWidth; 251 | } 252 | 253 | -(CGFloat)LWDateIndicatorTitleHeight{ 254 | if (_LWDateIndicatorTitleHeight == UNINITIALIZED_FLOAT) { 255 | _LWDateIndicatorTitleHeight = [LWDatePickerBuilder defaultBuilder].LWDateIndicatorTitleHeight; 256 | } 257 | return _LWDateIndicatorTitleHeight; 258 | } 259 | 260 | -(CGFloat)LWCalendarLineGap{ 261 | if (_LWCalendarLineGap == UNINITIALIZED_FLOAT) { 262 | _LWCalendarLineGap = [LWDatePickerBuilder defaultBuilder].LWCalendarLineGap; 263 | } 264 | return _LWCalendarLineGap; 265 | } 266 | 267 | 268 | -(CGFloat)LWCalendarMarginH{ 269 | if (_LWCalendarMarginH == UNINITIALIZED_FLOAT) { 270 | _LWCalendarMarginH = [LWDatePickerBuilder defaultBuilder].LWCalendarMarginH; 271 | } 272 | return _LWCalendarMarginH; 273 | } 274 | 275 | 276 | -(CGFloat)LWCalendarRowGap{ 277 | if (_LWCalendarRowGap == UNINITIALIZED_FLOAT) { 278 | _LWCalendarRowGap = [LWDatePickerBuilder defaultBuilder].LWCalendarRowGap; 279 | } 280 | return _LWCalendarRowGap; 281 | } 282 | 283 | 284 | -(CGFloat)LWCalendarTitleHeight{ 285 | if (_LWCalendarTitleHeight == UNINITIALIZED_FLOAT) { 286 | _LWCalendarTitleHeight = [LWDatePickerBuilder defaultBuilder].LWCalendarTitleHeight; 287 | } 288 | return _LWCalendarTitleHeight; 289 | } 290 | 291 | 292 | -(CGFloat)LWWeekIndicatorHeight{ 293 | if (_LWWeekIndicatorHeight == UNINITIALIZED_FLOAT) { 294 | _LWWeekIndicatorHeight = [LWDatePickerBuilder defaultBuilder].LWWeekIndicatorHeight; 295 | } 296 | return _LWWeekIndicatorHeight; 297 | } 298 | 299 | 300 | -(UIColor *)LWDatePickerViewSelectedColor{ 301 | if (_LWDatePickerViewSelectedColor == nil) { 302 | _LWDatePickerViewSelectedColor = [LWDatePickerBuilder defaultBuilder].LWDatePickerViewSelectedColor; 303 | } 304 | return _LWDatePickerViewSelectedColor; 305 | } 306 | 307 | -(UIColor *)LWDatePickerViewSelectedTextColor{ 308 | if (_LWDatePickerViewSelectedTextColor == nil) { 309 | _LWDatePickerViewSelectedTextColor = [LWDatePickerBuilder defaultBuilder].LWDatePickerViewSelectedTextColor; 310 | } 311 | return _LWDatePickerViewSelectedTextColor; 312 | } 313 | 314 | -(UIColor *)LWDatePickerViewDefaultColor{ 315 | if (_LWDatePickerViewDefaultColor == nil) { 316 | _LWDatePickerViewDefaultColor = [LWDatePickerBuilder defaultBuilder].LWDatePickerViewDefaultColor; 317 | } 318 | return _LWDatePickerViewDefaultColor; 319 | } 320 | 321 | -(UIColor *)LWDatePickerViewDefaultTextColor{ 322 | if (_LWDatePickerViewDefaultTextColor == nil) { 323 | _LWDatePickerViewDefaultTextColor = [LWDatePickerBuilder defaultBuilder].LWDatePickerViewDefaultTextColor; 324 | } 325 | return _LWDatePickerViewDefaultTextColor; 326 | } 327 | 328 | -(UIColor *)LWWeekIndicatorTextColor{ 329 | if (_LWWeekIndicatorTextColor == nil) { 330 | _LWWeekIndicatorTextColor = [LWDatePickerBuilder defaultBuilder].LWWeekIndicatorTextColor; 331 | } 332 | return _LWWeekIndicatorTextColor; 333 | } 334 | 335 | -(UIColor *)LWDatePickerViewShadowColor{ 336 | if (_LWDatePickerViewShadowColor == nil) { 337 | _LWDatePickerViewShadowColor = [LWDatePickerBuilder defaultBuilder].LWDatePickerViewShadowColor; 338 | } 339 | return _LWDatePickerViewShadowColor; 340 | } 341 | 342 | -(UIFont *)LWDatePickerViewButtonFont{ 343 | if (_LWDatePickerViewButtonFont == nil) { 344 | _LWDatePickerViewButtonFont = [LWDatePickerBuilder defaultBuilder].LWDatePickerViewButtonFont; 345 | } 346 | return _LWDatePickerViewButtonFont; 347 | } 348 | 349 | -(UIFont *)LWDateIndicatorDateFont{ 350 | if (_LWDateIndicatorDateFont == nil) { 351 | _LWDateIndicatorDateFont = [LWDatePickerBuilder defaultBuilder].LWDateIndicatorDateFont; 352 | } 353 | return _LWDateIndicatorDateFont; 354 | } 355 | 356 | -(UIFont *)LWDateIndicatorTitleFont{ 357 | if (_LWDateIndicatorTitleFont == nil) { 358 | _LWDateIndicatorTitleFont = [LWDatePickerBuilder defaultBuilder].LWDateIndicatorTitleFont; 359 | } 360 | return _LWDateIndicatorTitleFont; 361 | } 362 | 363 | -(UIFont *)LWWeekIndicatorTextFont{ 364 | if (_LWWeekIndicatorTextFont == nil) { 365 | _LWWeekIndicatorTextFont = [LWDatePickerBuilder defaultBuilder].LWWeekIndicatorTextFont; 366 | } 367 | return _LWWeekIndicatorTextFont; 368 | } 369 | 370 | -(UIFont *)LWDayViewFont{ 371 | if (_LWDayViewFont == nil) { 372 | _LWDayViewFont = [LWDatePickerBuilder defaultBuilder].LWDayViewFont; 373 | } 374 | return _LWDayViewFont; 375 | } 376 | 377 | -(UIFont *)LWCalendarTitleFont{ 378 | if (_LWCalendarTitleFont == nil) { 379 | _LWCalendarTitleFont = [LWDatePickerBuilder defaultBuilder].LWCalendarTitleFont; 380 | } 381 | return _LWCalendarTitleFont; 382 | } 383 | 384 | -(CGSize)LWDatePickerViewShadowOffset{ 385 | if (_LWDatePickerViewShadowOffset.width == UNINITIALIZED_CGSIZE.width 386 | && _LWDatePickerViewShadowOffset.height == UNINITIALIZED_CGSIZE.height) { 387 | _LWDatePickerViewShadowOffset = [LWDatePickerBuilder defaultBuilder].LWDatePickerViewShadowOffset; 388 | } 389 | return _LWDatePickerViewShadowOffset; 390 | } 391 | 392 | @end 393 | -------------------------------------------------------------------------------- /LWCalendar/LWDatePickerDialog.h: -------------------------------------------------------------------------------- 1 | // 2 | // DatePickerDialog.h 3 | // PriceCalender 4 | // 5 | // Created by luwei on 2016/12/29. 6 | // Copyright © 2016年 HarrisHan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class LWDatePickerDialog,LWCalendarManager, LWDatePickerView, LWDatePickerBuilder; 12 | 13 | /** 14 | 日期选择器的回调 15 | */ 16 | @protocol LWDatePickerDelegate 17 | 18 | - (void)onDateSet:(LWDatePickerDialog*)dialog 19 | StartDate:(NSDate *)start 20 | EndDate:(NSDate *)end; 21 | 22 | @end 23 | 24 | @interface LWDatePickerDialog : UIViewController 25 | @property(nonatomic, strong) LWDatePickerBuilder *dialogBuilder; //日期选择器的样式配置 26 | @property(nonatomic, strong) LWDatePickerView *datePickerView; //日期选择器的容器 27 | @property(nonatomic, strong) LWCalendarManager *manager; //日期选择器的配置参数 28 | @property(nonatomic, strong) NSDate *currentDate; //今日日期 特殊显示 29 | @property(nonatomic, strong) NSDate *startDate; //选中的开始日期,默认为今日日期 30 | @property(nonatomic, strong) NSDate *endDate; //选中的结束日期,默认为开始日期 31 | @property(nonatomic, weak) id controllerDelegate; //日期选择器的回调 32 | 33 | //提供了三个创建函数 今日日期和回调是必填参数 但是都是可空的 今日日期为空时将会使用当前时间作为今日日期 34 | + (instancetype)initWithDate:(NSDate *)currentDate 35 | StartDate:(NSDate *)startDate 36 | EndDate:(NSDate *)endDate 37 | Delegate:(id)delegate 38 | Builder:(LWDatePickerBuilder *)builder; 39 | 40 | + (instancetype)initWithDate:(NSDate *)currentDate 41 | StartDate:(NSDate *)startDate 42 | Delegate:(id)delegate 43 | Builder:(LWDatePickerBuilder *)builder; 44 | 45 | + (instancetype)initWithDate:(NSDate *)currentDate 46 | Delegate:(id)delegate 47 | Builder:(LWDatePickerBuilder *)builder; 48 | 49 | + (instancetype)initWithDate:(NSDate *)currentDate 50 | Delegate:(id)delegate; 51 | 52 | //显示日期选择器 53 | - (void)show; 54 | //隐藏日期选择器 55 | - (void)hide; 56 | 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /LWCalendar/LWDatePickerDialog.m: -------------------------------------------------------------------------------- 1 | // 2 | // DatePickerDialog.m 3 | // PriceCalender 4 | // 5 | // Created by luwei on LWDATEPICKERDIALOG_MARGIN_V16/12/29. 6 | // Copyright © LWDATEPICKERDIALOG_MARGIN_V16年 HarrisHan. All rights reserved. 7 | // 8 | 9 | #import "LWCalendarHeader.h" 10 | 11 | @interface LWDatePickerDialog () 12 | 13 | @property(nonatomic, strong) NSMutableArray *datePickerViewConstraints; 14 | 15 | @end 16 | 17 | @implementation LWDatePickerDialog 18 | 19 | @synthesize 20 | datePickerView = _datePickerView, 21 | currentDate = _currentDate, 22 | startDate = _startDate, 23 | endDate = _endDate, 24 | manager = _manager, 25 | dialogBuilder = _dialogBuilder, 26 | datePickerViewConstraints = _datePickerViewConstraints; 27 | 28 | +(instancetype)initWithDate:(NSDate *)currentDate 29 | Delegate:(id)delegate{ 30 | return [LWDatePickerDialog initWithDate:currentDate StartDate:currentDate Delegate:delegate Builder:[LWDatePickerBuilder defaultBuilder]]; 31 | } 32 | 33 | +(instancetype)initWithDate:(NSDate *)currentDate 34 | Delegate:(id)delegate 35 | Builder:(LWDatePickerBuilder *)builder{ 36 | return [LWDatePickerDialog initWithDate:currentDate StartDate:currentDate Delegate:delegate Builder:builder]; 37 | } 38 | 39 | +(instancetype)initWithDate:(NSDate *)currentDate 40 | StartDate:(NSDate *)startDate 41 | Delegate:(id)delegate 42 | Builder:(LWDatePickerBuilder *)builder{ 43 | return [LWDatePickerDialog initWithDate:currentDate StartDate:startDate EndDate:startDate Delegate:delegate Builder:builder]; 44 | } 45 | 46 | +(instancetype)initWithDate:(NSDate *)currentDate 47 | StartDate:(NSDate *)startDate 48 | EndDate:(NSDate *)endDate 49 | Delegate:(id)delegate 50 | Builder:(LWDatePickerBuilder *)builder{ 51 | LWDatePickerDialog *tmp = [[LWDatePickerDialog alloc] init]; 52 | if (tmp) { 53 | //初始化代码 54 | tmp.dialogBuilder = builder; 55 | tmp.controllerDelegate = delegate; 56 | tmp.currentDate = currentDate; 57 | tmp.startDate = startDate; 58 | tmp.endDate = endDate; 59 | } 60 | return tmp; 61 | } 62 | 63 | -(void)viewDidLoad{ 64 | self.view.userInteractionEnabled = true; 65 | UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(hide)]; 66 | recognizer.delegate = self; 67 | [self.view addGestureRecognizer:recognizer]; 68 | } 69 | 70 | -(void)show{ 71 | id delegate = [UIApplication sharedApplication].delegate; 72 | if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0 ) { 73 | self.modalPresentationStyle = UIModalPresentationOverCurrentContext; 74 | [delegate.window.rootViewController presentViewController:self animated:NO completion:^{ 75 | [UIView animateWithDuration:self.dialogBuilder.LWDatePickerDialogAnimateDutation animations:^{ 76 | self.view.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5]; 77 | self.datePickerView.alpha = 1.0; 78 | }]; 79 | 80 | }]; 81 | }else{ 82 | self.view.window.rootViewController.modalPresentationStyle = UIModalPresentationCurrentContext; 83 | [delegate.window.rootViewController presentViewController:self animated:NO completion:^{ 84 | [UIView animateWithDuration:self.dialogBuilder.LWDatePickerDialogAnimateDutation animations:^{ 85 | self.view.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5]; 86 | self.datePickerView.alpha = 1.0; 87 | }]; 88 | }]; 89 | self.view.window.rootViewController.modalPresentationStyle = UIModalPresentationFullScreen; 90 | } 91 | } 92 | 93 | -(void)hide{ 94 | [UIView animateWithDuration:self.dialogBuilder.LWDatePickerDialogAnimateDutation animations:^{ 95 | self.view.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.0]; 96 | self.datePickerView.alpha = 0.0; 97 | } completion:^(BOOL finished) { 98 | [self dismissViewControllerAnimated:NO completion:nil]; 99 | }]; 100 | } 101 | 102 | 103 | 104 | #pragma mark Get And Set 105 | -(LWDatePickerView *)datePickerView{ 106 | if (_datePickerView == nil) { 107 | _datePickerView = [[LWDatePickerView alloc] init]; 108 | _datePickerView.dialogDelegate = self; 109 | _datePickerView.alpha = 0.0; 110 | _datePickerView.translatesAutoresizingMaskIntoConstraints = NO; 111 | [self.view addSubview:_datePickerView]; 112 | } 113 | return _datePickerView; 114 | } 115 | 116 | -(LWCalendarManager *)manager{ 117 | if (_manager == nil) { 118 | _manager = [[LWCalendarManager alloc] init]; 119 | _manager.canSelectPastDays = true; 120 | _manager.selectionType = LWCalendarSelectionTypeRange; 121 | } 122 | return _manager; 123 | } 124 | 125 | -(void)setCurrentDate:(NSDate *)currentDate{ 126 | if (currentDate == nil) { 127 | currentDate = [NSDate new]; 128 | } 129 | _currentDate = currentDate; 130 | self.datePickerView.currentDate = _currentDate; 131 | } 132 | 133 | -(void)setStartDate:(NSDate *)startDate{ 134 | if (startDate == nil) { 135 | startDate = [NSDate new]; 136 | } 137 | _startDate = startDate; 138 | self.datePickerView.startDate = _startDate; 139 | } 140 | 141 | -(void)setEndDate:(NSDate *)endDate{ 142 | if (endDate == nil) { 143 | endDate = [NSDate new]; 144 | } 145 | _endDate = endDate; 146 | self.datePickerView.endDate = _endDate; 147 | } 148 | 149 | -(NSDate *)currentDate{ 150 | if (_currentDate == nil) { 151 | _currentDate = [NSDate new]; 152 | } 153 | return _currentDate; 154 | } 155 | 156 | -(NSDate *)startDate{ 157 | _startDate = self.datePickerView.startDate; 158 | return _startDate; 159 | } 160 | 161 | -(NSDate *)endDate{ 162 | _endDate = self.datePickerView.endDate; 163 | return _endDate; 164 | } 165 | 166 | -(void)setDialogBuilder:(LWDatePickerBuilder *)dialogBuilder{ 167 | if (dialogBuilder == nil) { 168 | dialogBuilder = [LWDatePickerBuilder defaultBuilder]; 169 | } 170 | if (_dialogBuilder != dialogBuilder) { 171 | _dialogBuilder = dialogBuilder; 172 | [self updateWithBuilder:dialogBuilder]; 173 | } 174 | } 175 | 176 | -(LWDatePickerBuilder *)dialogBuilder{ 177 | if (_dialogBuilder == nil) { 178 | _dialogBuilder = [LWDatePickerBuilder defaultBuilder]; 179 | } 180 | return _dialogBuilder; 181 | } 182 | 183 | -(NSMutableArray *)datePickerViewConstraints{ 184 | if (_datePickerViewConstraints == nil) { 185 | _datePickerViewConstraints = [NSMutableArray new]; 186 | } 187 | return _datePickerViewConstraints; 188 | } 189 | 190 | #pragma mark UIGestureRecognizerDelegate 191 | -(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{ 192 | if ([touch.view isDescendantOfView:self.datePickerView]) { 193 | return NO; 194 | } 195 | return YES; 196 | } 197 | 198 | #pragma mark 处理屏幕旋转 199 | -(BOOL)shouldAutorotate{ 200 | //是否允许屏幕旋转 201 | return YES; 202 | } 203 | 204 | -(UIInterfaceOrientationMask)supportedInterfaceOrientations{ 205 | //viewController所支持的全部旋转方向 206 | return UIInterfaceOrientationMaskAll; 207 | } 208 | 209 | - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation{ 210 | //viewController初始显示的方向 211 | return UIInterfaceOrientationPortrait; 212 | } 213 | 214 | #pragma mark 根据Build参数更新UI或者约束 215 | -(void)updateWithBuilder:(LWDatePickerBuilder *)builder{ 216 | [self.view removeConstraints:self.datePickerViewConstraints]; 217 | [self.datePickerViewConstraints removeAllObjects]; 218 | 219 | //添加约束 220 | NSLayoutConstraint *viewLeft = [NSLayoutConstraint constraintWithItem:self.datePickerView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeLeft multiplier:1.0 constant:builder.LWDatePickerDialogMarginH]; 221 | NSLayoutConstraint *viewRight = [NSLayoutConstraint constraintWithItem:self.datePickerView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeRight multiplier:1.0 constant:-builder.LWDatePickerDialogMarginH]; 222 | NSLayoutConstraint *viewTop = [NSLayoutConstraint constraintWithItem:self.datePickerView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeTop multiplier:1.0 constant:builder.LWDatePickerDialogMarginV]; 223 | NSLayoutConstraint *viewBottom = [NSLayoutConstraint constraintWithItem:self.datePickerView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.view attribute:NSLayoutAttributeBottom multiplier:1.0 constant:-builder.LWDatePickerDialogMarginV]; 224 | [self.view addConstraint:viewLeft]; 225 | [self.view addConstraint:viewRight]; 226 | [self.view addConstraint:viewTop]; 227 | [self.view addConstraint:viewBottom]; 228 | [self.datePickerViewConstraints addObject:viewLeft]; 229 | [self.datePickerViewConstraints addObject:viewRight]; 230 | [self.datePickerViewConstraints addObject:viewTop]; 231 | [self.datePickerViewConstraints addObject:viewBottom]; 232 | 233 | self.datePickerView.dialogBuilder = builder; 234 | } 235 | 236 | @end 237 | -------------------------------------------------------------------------------- /LWCalendar/LWDatePickerView.h: -------------------------------------------------------------------------------- 1 | // 2 | // DatePickerView.h 3 | // PriceCalender 4 | // 5 | // Created by luwei on 2017/1/4. 6 | // Copyright © 2017年 HarrisHan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class LWDatePickerDialog, LWDateIndicator, LWCalendarView, LWDatePickerBuilder; 12 | 13 | @interface LWDatePickerView : UIView 14 | 15 | @property(nonatomic, weak) LWDatePickerDialog *dialogDelegate; 16 | @property(nonatomic, strong) LWCalendarView *calendarView;//月天选择器 17 | @property(nonatomic, strong) UIButton *cancelButton;//取消按钮 18 | @property(nonatomic, strong) UIButton *confirmButton; //确认按钮 19 | @property(nonatomic, strong) LWDateIndicator *fromIndicator;//开始时间的指示器 20 | @property(nonatomic, strong) LWDateIndicator *toIndicator;//结束时间的指示器 21 | 22 | @property(nonatomic, strong) NSDate *currentDate; 23 | @property(nonatomic, strong) NSDate *startDate; 24 | @property(nonatomic, strong) NSDate *endDate; 25 | @property(nonatomic, weak) LWDatePickerBuilder *dialogBuilder; 26 | 27 | @end 28 | -------------------------------------------------------------------------------- /LWCalendar/LWDayView.h: -------------------------------------------------------------------------------- 1 | // 2 | // LWDayView.h 3 | // Example 4 | // 5 | // Created by Daniel on 16/10/28. 6 | // Copyright © 2016年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class LWWeekView, LWDatePickerBuilder; 12 | 13 | @interface LWDayView : UIButton 14 | @property (nonatomic, strong) NSDate *date; 15 | @property (nonatomic, weak) LWWeekView *weekDelegate; 16 | @property (nonatomic, weak) LWDatePickerBuilder *dialogBuilder; 17 | @end 18 | -------------------------------------------------------------------------------- /LWCalendar/LWDayView.m: -------------------------------------------------------------------------------- 1 | // 2 | // LWDayView.m 3 | // Example 4 | // 5 | // Created by Daniel on 16/10/28. 6 | // Copyright © 2016年 Daniel. All rights reserved. 7 | // 8 | 9 | #import "LWCalendarHeader.h" 10 | 11 | static UIImage *selectImage = nil; 12 | 13 | @interface LWDayView (){ 14 | CGSize lastSize; 15 | } 16 | @property(nonatomic, weak) LWCalendarManager *manager; 17 | @property(nonatomic, weak) LWCalendarView *calendarDelegate; 18 | @end 19 | 20 | @implementation LWDayView 21 | 22 | @synthesize weekDelegate = _weekDelegate, dialogBuilder = _dialogBuilder; 23 | 24 | //根据frame获取半径 去宽高中较小的一边作为直径 25 | -(float)radiusFromFrame:(CGRect)frame{ 26 | float width = frame.size.width ; 27 | float height = frame.size.height ; 28 | return width < height ? width : height; 29 | } 30 | 31 | -(UIImage *) roundCorneredImage: (UIImage *) orig radius:(CGFloat) corner { 32 | UIGraphicsBeginImageContextWithOptions(orig.size, NO, 0); 33 | [[UIBezierPath bezierPathWithRoundedRect:(CGRect){CGPointZero, orig.size} 34 | cornerRadius:corner] addClip]; 35 | [orig drawInRect:(CGRect){CGPointZero, orig.size}]; 36 | UIImage* result = UIGraphicsGetImageFromCurrentImageContext(); 37 | UIGraphicsEndImageContext(); 38 | return result; 39 | } 40 | 41 | 42 | -(UIImage *) createImageWithColor:(UIColor*) color Frame:(CGRect)frame Radius:(CGFloat)corner{ 43 | UIGraphicsBeginImageContext(frame.size); 44 | CGContextRef context = UIGraphicsGetCurrentContext(); 45 | CGContextSetFillColorWithColor(context, [color CGColor]); 46 | CGContextFillRect(context, frame); 47 | UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext(); 48 | UIGraphicsEndImageContext(); 49 | return (corner > 0 ? [self roundCorneredImage:theImage radius:corner]:theImage); 50 | } 51 | 52 | -(UIImage *)getSelectImageWithFrame:(CGRect) vframe{ 53 | CGFloat size = [self radiusFromFrame:vframe]; 54 | CGRect frame = CGRectMake(0, 0, size, size); 55 | if (selectImage == nil) { 56 | selectImage = [self createImageWithColor:self.dialogBuilder.LWDatePickerViewSelectedColor 57 | Frame:frame 58 | Radius:size * 0.5]; 59 | }else{ 60 | if(!selectImage.size.height == size 61 | || !selectImage.size.width == size){ 62 | selectImage = [self createImageWithColor:self.dialogBuilder.LWDatePickerViewSelectedColor 63 | Frame:frame 64 | Radius:size * 0.5]; 65 | } 66 | } 67 | return selectImage; 68 | } 69 | 70 | #pragma mark 构造函数 71 | - (instancetype)initWithFrame:(CGRect)frame{ 72 | if (self = [super initWithFrame:frame]) { 73 | self.titleLabel.textAlignment = NSTextAlignmentCenter; 74 | self.imageView.contentMode = UIViewContentModeScaleAspectFit; 75 | 76 | [self addTarget:self action:@selector(onClick) forControlEvents:UIControlEventTouchUpInside]; 77 | 78 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(changeState) name:LWDAYVIEW_CHANGE_STATE object:nil]; 79 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(updateState) name:LWDAYVIEW_UPDATE_STATE object:nil]; 80 | [self updateWithBuilder:self.dialogBuilder]; 81 | } 82 | return self; 83 | } 84 | 85 | #pragma mark 析构函数 86 | -(void)dealloc{ 87 | [[NSNotificationCenter defaultCenter] removeObserver:self ]; 88 | } 89 | 90 | #pragma mark 不同状态下不同按钮的state 91 | //多选状态下除去起始和结束按钮的state 92 | -(void)multiNormalStateList{ 93 | //正常状态 多选情况下中间的按钮状态都不是selected只有两头是 所以正常情况就应该是选中状态 94 | [self setTitleColor:self.dialogBuilder.LWDatePickerViewSelectedTextColor forState:UIControlStateNormal]; 95 | [self setImage:nil forState:UIControlStateNormal]; 96 | [self setBackgroundImage:nil forState:UIControlStateNormal]; 97 | //高亮状态 98 | [self setTitleColor:self.dialogBuilder.LWDatePickerViewSelectedTextColor forState:UIControlStateHighlighted]; 99 | [self setImage:nil forState:UIControlStateHighlighted]; 100 | [self setBackgroundImage:nil forState:UIControlStateHighlighted]; 101 | //选中状态 102 | [self setTitleColor:self.dialogBuilder.LWDatePickerViewSelectedTextColor forState:UIControlStateSelected]; 103 | [self setImage:nil forState:UIControlStateSelected]; 104 | [self setBackgroundImage:nil forState:UIControlStateSelected]; 105 | 106 | } 107 | 108 | //普通按钮的state 109 | -(void)normalStateList{ 110 | [self setTitleColor:[UIColor grayColor] forState:UIControlStateDisabled]; 111 | //正常状态 112 | [self setTitleColor:self.dialogBuilder.LWDatePickerViewDefaultTextColor forState:UIControlStateNormal]; 113 | // 当前时间 114 | if (_date && [self.manager.helper date:_date isTheSameDayThan:self.calendarDelegate.currentDate] && self.enabled) { 115 | [self setImage:[NSBundle LWCalendarCircleImage] forState:UIControlStateNormal]; 116 | }else{ 117 | [self setImage:nil forState:UIControlStateNormal]; 118 | } 119 | [self setBackgroundImage:nil forState:UIControlStateNormal]; 120 | //高亮状态 121 | [self setTitleColor:self.dialogBuilder.LWDatePickerViewSelectedTextColor forState:UIControlStateHighlighted]; 122 | [self setImage:[self getSelectImageWithFrame:self.frame] forState:UIControlStateHighlighted]; 123 | [self setBackgroundImage:nil forState:UIControlStateHighlighted]; 124 | //选中状态 125 | [self setTitleColor:self.dialogBuilder.LWDatePickerViewSelectedTextColor forState:UIControlStateSelected]; 126 | [self setImage:[self getSelectImageWithFrame:self.frame] forState:UIControlStateSelected]; 127 | [self setBackgroundImage:nil forState:UIControlStateSelected]; 128 | } 129 | 130 | //起始按钮的state 131 | -(void)startStateList{ 132 | //正常状态 133 | [self setTitleColor:self.dialogBuilder.LWDatePickerViewDefaultTextColor forState:UIControlStateNormal]; 134 | [self setImage:nil forState:UIControlStateNormal]; 135 | [self setBackgroundImage:nil forState:UIControlStateNormal]; 136 | //高亮状态 137 | [self setTitleColor:self.dialogBuilder.LWDatePickerViewSelectedTextColor forState:UIControlStateHighlighted]; 138 | [self setImage:[self getSelectImageWithFrame:self.frame] forState:UIControlStateHighlighted]; 139 | [self setBackgroundImage:[NSBundle LWCalendarStartFilterImage] forState:UIControlStateHighlighted]; 140 | //选中状态 141 | [self setTitleColor:self.dialogBuilder.LWDatePickerViewSelectedTextColor forState:UIControlStateSelected]; 142 | [self setImage:[self getSelectImageWithFrame:self.frame] forState:UIControlStateSelected]; 143 | [self setBackgroundImage:[NSBundle LWCalendarStartFilterImage] forState:UIControlStateSelected]; 144 | } 145 | 146 | //结束按钮的state 147 | -(void)endStateList{ 148 | //正常状态 149 | [self setTitleColor:self.dialogBuilder.LWDatePickerViewDefaultTextColor forState:UIControlStateNormal]; 150 | [self setImage:nil forState:UIControlStateNormal]; 151 | [self setBackgroundImage:nil forState:UIControlStateNormal]; 152 | //高亮状态 153 | [self setTitleColor:self.dialogBuilder.LWDatePickerViewSelectedTextColor forState:UIControlStateHighlighted]; 154 | [self setImage:[self getSelectImageWithFrame:self.frame] forState:UIControlStateHighlighted]; 155 | [self setBackgroundImage:[NSBundle LWCalendarEndFilterImage] forState:UIControlStateHighlighted]; 156 | //选中状态 157 | [self setTitleColor:self.dialogBuilder.LWDatePickerViewSelectedTextColor forState:UIControlStateSelected]; 158 | [self setImage:[self getSelectImageWithFrame:self.frame] forState:UIControlStateSelected]; 159 | [self setBackgroundImage:[NSBundle LWCalendarEndFilterImage] forState:UIControlStateSelected]; 160 | } 161 | 162 | #pragma mark Notification回调函数 163 | //LWDayView点击事件通知 164 | - (void)changeState { 165 | if (self.calendarDelegate.selectedStartDay && self.calendarDelegate.selectedEndDay && ![self.manager.helper date:self.calendarDelegate.startDate isTheSameDayThan:self.calendarDelegate.endDate]) { 166 | if ([self.manager.helper date:_date isEqualOrAfter:self.calendarDelegate.startDate andEqualOrBefore:self.calendarDelegate.endDate]){ 167 | if ([self.manager.helper date:_date isTheSameDayThan:self.calendarDelegate.startDate]) { 168 | [self startStateList]; 169 | } else if ([self.manager.helper date:_date isTheSameDayThan:self.calendarDelegate.endDate]) { 170 | [self endStateList]; 171 | }else{ 172 | [self multiNormalStateList]; 173 | } 174 | }else{ 175 | [self normalStateList]; 176 | } 177 | [self setSelectColor]; 178 | 179 | } else { 180 | self.backgroundColor = [UIColor clearColor]; 181 | [self normalStateList]; 182 | } 183 | } 184 | //start或者end的date改变通知 逻辑应该与changeState类似 185 | -(void)updateState{ 186 | [self setDate:_date]; 187 | } 188 | 189 | //设置选中状态对应的背景色 190 | - (void)setSelectColor { 191 | //处于开始和结束时间范围内 192 | if ([self.manager.helper date:_date 193 | isEqualOrAfter:self.calendarDelegate.startDate 194 | andEqualOrBefore:self.calendarDelegate.endDate]) { 195 | // 同一个月 196 | if ([self.manager.helper date:self.calendarDelegate.startDate 197 | isTheSameMonthThan:self.calendarDelegate.endDate]) { 198 | if (self.enabled) { 199 | self.backgroundColor = self.dialogBuilder.LWDatePickerViewSelectedColor; 200 | } else { 201 | self.backgroundColor = [UIColor clearColor]; 202 | } 203 | } 204 | // 不同 205 | else { 206 | //不同月份之间需要注意没有显示日期的LWDayView,因此首先默认都显示选中背景 207 | self.backgroundColor = self.dialogBuilder.LWDatePickerViewSelectedColor; 208 | // 开始的是一个月的第一天 209 | if ([self.manager.helper date:_date 210 | isTheSameDayThan:[self.manager.helper firstDayOfMonth:self.calendarDelegate.startDate]] && !self.enabled) { 211 | self.backgroundColor = [UIColor clearColor]; 212 | } 213 | 214 | // 结束是一个月最后一天 215 | if ([self.manager.helper date:_date 216 | isTheSameDayThan:[self.manager.helper lastDayOfMonth:self.calendarDelegate.endDate]] && !self.enabled) { 217 | self.backgroundColor = [UIColor clearColor]; 218 | } 219 | } 220 | } else { 221 | //在选中时间范围外 222 | self.backgroundColor = [UIColor clearColor]; 223 | } 224 | } 225 | 226 | 227 | #pragma mark 触摸事件处理 228 | //每次touch开始时将select状态置为false touch结束后状态还原 这是为了能让我们的按钮显示正常 229 | -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 230 | self.selected = false; 231 | [super touchesBegan:touches withEvent:event]; 232 | } 233 | 234 | -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{ 235 | [super touchesMoved:touches withEvent:event]; 236 | self.highlighted = true; 237 | } 238 | 239 | -(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ 240 | [super touchesEnded:touches withEvent:event]; 241 | self.selected = true; 242 | } 243 | 244 | #pragma mark 按钮点击事件 245 | -(void)onClick{ 246 | // 多选 247 | if (self.manager.selectionType == LWCalendarSelectionTypeMultiple) { 248 | self.selected = !self.selected; 249 | if (self.selected) { 250 | [self.manager.selectedDateArray addObject:self.date]; 251 | } else { 252 | [self.manager.selectedDateArray enumerateObjectsUsingBlock:^(NSDate *obj, NSUInteger idx, BOOL * _Nonnull stop) { 253 | if ([self.manager.helper date:_date isTheSameDayThan:obj]) { 254 | [self.manager.selectedDateArray removeObjectAtIndex:idx]; 255 | } 256 | }]; 257 | } 258 | } else { 259 | //目前只有开始时间,没有选择结束时间,则当前选择的就是结束时间 260 | if (self.calendarDelegate.selectedStartDay && !self.calendarDelegate.selectedEndDay) { 261 | //如果选择的结束时间比开始时间早,则将当前选择的日期设置为开始时间 原来的开始时间变成结束时间 262 | if ([self.manager.helper date:_date isBefore:self.calendarDelegate.startDate]) { 263 | LWDayView *tmp = self.calendarDelegate.selectedStartDay; 264 | self.calendarDelegate.selectedStartDay = self; 265 | self.calendarDelegate.selectedStartDay.selected = true; 266 | self.calendarDelegate.selectedEndDay = tmp; 267 | self.calendarDelegate.selectedEndDay.selected = true; 268 | [[NSNotificationCenter defaultCenter] postNotificationName:LWDAYVIEW_CHANGE_STATE object:nil]; 269 | } else { 270 | // 如果不能选择时间段(单选) 271 | if (self.manager.selectionType == LWCalendarSelectionTypeSingle) { 272 | if (self.calendarDelegate.selectedStartDay) { 273 | self.calendarDelegate.selectedStartDay.selected = false; 274 | } 275 | self.calendarDelegate.selectedStartDay = self; 276 | self.calendarDelegate.selectedStartDay.selected = true; 277 | } else { 278 | self.calendarDelegate.selectedEndDay = self; 279 | self.calendarDelegate.selectedEndDay.selected = true; 280 | [[NSNotificationCenter defaultCenter] postNotificationName:LWDAYVIEW_CHANGE_STATE object:nil]; 281 | } 282 | } 283 | } else if (self.calendarDelegate.selectedStartDay && self.calendarDelegate.selectedEndDay) { 284 | self.calendarDelegate.selectedStartDay.selected = false; 285 | self.calendarDelegate.selectedEndDay.selected = false; 286 | self.calendarDelegate.selectedStartDay = self; 287 | self.calendarDelegate.selectedStartDay.selected = true; 288 | self.calendarDelegate.selectedEndDay = nil; 289 | [[NSNotificationCenter defaultCenter] postNotificationName:LWDAYVIEW_CHANGE_STATE object:nil]; 290 | } else if (!self.calendarDelegate.selectedStartDay && !self.calendarDelegate.selectedEndDay) { 291 | self.calendarDelegate.selectedStartDay = self; 292 | self.calendarDelegate.selectedStartDay.selected = true; 293 | } 294 | } 295 | [[NSNotificationCenter defaultCenter] postNotificationName:LWDAYVIEW_DATE_CHANGED object:nil]; 296 | } 297 | 298 | #pragma mark Override函数 确定title和image的坐标 299 | - (CGRect)titleRectForContentRect:(CGRect)contentRect { 300 | CGRect frame = contentRect; 301 | frame.origin.x = 0; 302 | frame.origin.y = 0; 303 | frame.size = self.frame.size; 304 | return frame; 305 | } 306 | 307 | - (CGRect)imageRectForContentRect:(CGRect)contentRect { 308 | CGRect frame = contentRect; 309 | frame.origin.x = 0; 310 | frame.origin.y = 0; 311 | frame.size = self.frame.size; 312 | return frame; 313 | } 314 | 315 | #pragma mark Get and Set 316 | -(void)setWeekDelegate:(LWWeekView *)weekDelegate{ 317 | _weekDelegate = weekDelegate; 318 | _manager = _weekDelegate.monthDelegate.calendarDelegate.dateViewDelegate.dialogDelegate.manager; 319 | _calendarDelegate = _weekDelegate.monthDelegate.calendarDelegate; 320 | } 321 | 322 | - (void)setDate:(NSDate *)date { 323 | _date = date; 324 | 325 | if (self.enabled) { 326 | 327 | // 过去的时间能否点击 328 | if (!self.manager.canSelectPastDays && 329 | ![self.manager.helper date:_date isTheSameDayThan:self.calendarDelegate.currentDate] && 330 | [_date compare:self.calendarDelegate.currentDate] == NSOrderedAscending) { 331 | self.enabled = false; 332 | } 333 | 334 | [self setTitle:[self.manager.dayDateFormatter stringFromDate:_date] forState:UIControlStateNormal]; 335 | 336 | // 当前时间 337 | if ([self.manager.helper date:_date isTheSameDayThan:self.calendarDelegate.currentDate] && self.enabled) { 338 | [self setImage:[NSBundle LWCalendarCircleImage] forState:UIControlStateNormal]; 339 | } 340 | 341 | // 多选状态设置 342 | if (self.manager.selectionType == LWCalendarSelectionTypeMultiple) { 343 | for (NSDate *date in self.manager.selectedDateArray) { 344 | self.selected = [self.manager.helper date:_date isTheSameDayThan:date]; 345 | if (self.selected) { 346 | break; 347 | } 348 | } 349 | return; 350 | } 351 | 352 | // 开始 353 | if (self.calendarDelegate.startDate) { 354 | if ([self.manager.helper date:_date isTheSameDayThan:self.calendarDelegate.startDate]) { 355 | if (self.calendarDelegate.selectedStartDay) { 356 | self.calendarDelegate.selectedStartDay.selected = false; 357 | } 358 | self.calendarDelegate.selectedStartDay = self; 359 | self.calendarDelegate.selectedStartDay.selected = true; 360 | } 361 | } 362 | // 结束 363 | if (self.calendarDelegate.selectedEndDay) { 364 | if ([self.manager.helper date:_date isTheSameDayThan:self.calendarDelegate.endDate]) { 365 | if (self.calendarDelegate.selectedEndDay) { 366 | self.calendarDelegate.selectedEndDay.selected = false; 367 | } 368 | self.calendarDelegate.selectedEndDay = self; 369 | self.calendarDelegate.selectedEndDay.selected = true; 370 | } 371 | } 372 | 373 | } 374 | [self changeState]; 375 | } 376 | 377 | -(void)setDialogBuilder:(LWDatePickerBuilder *)dialogBuilder{ 378 | if (dialogBuilder && _dialogBuilder != dialogBuilder) { 379 | _dialogBuilder = dialogBuilder; 380 | [self updateWithBuilder:dialogBuilder]; 381 | } 382 | } 383 | 384 | -(LWDatePickerBuilder *)dialogBuilder{ 385 | if(_dialogBuilder == nil){ 386 | if (self.weekDelegate) { 387 | _dialogBuilder = self.weekDelegate.dialogBuilder; 388 | }else{ 389 | _dialogBuilder = [LWDatePickerBuilder defaultBuilder]; 390 | } 391 | } 392 | return _dialogBuilder; 393 | } 394 | 395 | #pragma mark 根据Build参数更新UI或者约束 396 | -(void)updateWithBuilder:(LWDatePickerBuilder *)builder{ 397 | //title设置 398 | self.titleLabel.font = builder.LWDayViewFont; 399 | self.imageView.tintColor = builder.LWDatePickerViewSelectedColor; 400 | self.date = _date; 401 | } 402 | 403 | 404 | @end 405 | -------------------------------------------------------------------------------- /LWCalendar/LWMonthView.h: -------------------------------------------------------------------------------- 1 | // 2 | // LWMonthView.h 3 | // Example 4 | // 5 | // Created by Daniel on 16/10/28. 6 | // Copyright © 2016年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class LWCalendarView, LWDatePickerBuilder; 12 | 13 | /** 14 | * 应该包含一个标题,显示年月+一个星期指示器+天数布局 15 | */ 16 | @interface LWMonthView : UIView 17 | @property (nonatomic, strong)NSDate *date; 18 | @property (nonatomic, weak) LWCalendarView *calendarDelegate; 19 | @property (nonatomic, weak) LWDatePickerBuilder *dialogBuilder; 20 | @end 21 | -------------------------------------------------------------------------------- /LWCalendar/LWMonthView.m: -------------------------------------------------------------------------------- 1 | // 2 | // LWMonthView.m 3 | // Example 4 | // 5 | // Created by Daniel on 16/10/28. 6 | // Copyright © 2016年 Daniel. All rights reserved. 7 | // 8 | 9 | #import "LWCalendarHeader.h" 10 | 11 | 12 | 13 | @interface LWMonthView () 14 | @property (nonatomic, strong) NSMutableArray *weeksViews; 15 | @property (nonatomic, strong) UILabel *titleLab; 16 | @property (nonatomic, weak) LWCalendarManager *manager; 17 | @property (nonatomic, strong) LWWeekIndicator *weekIndicator; 18 | @end 19 | 20 | @implementation LWMonthView { 21 | NSInteger weekNumber; 22 | CGSize lastSize; 23 | } 24 | 25 | @synthesize 26 | calendarDelegate = _calendarDelegate, 27 | weekIndicator = _weekIndicator, 28 | titleLab = _titleLab, 29 | dialogBuilder = _dialogBuilder; 30 | 31 | 32 | #pragma mark 构造函数 33 | - (instancetype)initWithFrame:(CGRect)frame { 34 | if (self = [super initWithFrame:frame]) { 35 | _weeksViews = [NSMutableArray new]; 36 | [self updateWithBuilder:self.dialogBuilder]; 37 | } 38 | return self; 39 | } 40 | 41 | -(instancetype)init{ 42 | return [self initWithFrame:CGRectMake(0, 0, 0, 0)]; 43 | } 44 | 45 | -(void)layoutSubviews{ 46 | CGSize size = self.frame.size; 47 | if (!lastSize.width || size.width != lastSize.width || size.height != lastSize.height) { 48 | // 首次加载 49 | lastSize = size; 50 | [self resize]; 51 | } 52 | } 53 | 54 | 55 | - (void)resize { 56 | self.titleLab.frame = CGRectMake(0, 0, self.frame.size.width , self.dialogBuilder.LWCalendarTitleHeight); 57 | self.weekIndicator.frame = CGRectMake(self.dialogBuilder.LWCalendarMarginH, self.dialogBuilder.LWCalendarTitleHeight + self.dialogBuilder.LWCalendarLineGap, self.frame.size.width - self.dialogBuilder.LWCalendarMarginH * 2, self.dialogBuilder.LWWeekIndicatorHeight); 58 | CGFloat startY = self.dialogBuilder.LWCalendarTitleHeight + self.dialogBuilder.LWWeekIndicatorHeight + self.dialogBuilder.LWCalendarLineGap * 2; 59 | CGFloat startX = self.dialogBuilder.LWCalendarMarginH; 60 | CGFloat weekH = (self.frame.size.width - self.dialogBuilder.LWCalendarRowGap * 8 - self.dialogBuilder.LWCalendarMarginH * 2)/7; 61 | for (int i = 0; i < weekNumber; i++) { 62 | LWWeekView *weekView = _weeksViews[i]; 63 | if (weekView) { 64 | weekView.frame = CGRectMake(startX, startY + (weekH + self.dialogBuilder.LWCalendarLineGap) * i, self.frame.size.width - self.dialogBuilder.LWCalendarMarginH * 2, weekH); 65 | } 66 | } 67 | CGRect frame = self.frame; 68 | frame.size.height = weekNumber * weekH + self.dialogBuilder.LWCalendarTitleHeight + self.dialogBuilder.LWWeekIndicatorHeight + (weekNumber + 2) * self.dialogBuilder.LWCalendarLineGap; 69 | self.frame = frame; 70 | } 71 | 72 | 73 | 74 | 75 | #pragma mark Get and Set 76 | -(void)setCalendarDelegate:(LWCalendarView *)calendarDelegate{ 77 | _calendarDelegate = calendarDelegate; 78 | _manager = _calendarDelegate.dateViewDelegate.dialogDelegate.manager; 79 | } 80 | 81 | - (void)setDate:(NSDate *)date { 82 | _date = date; 83 | // 某月 84 | NSString *dateStr = [self.manager.titleDateFormatter stringFromDate:_date]; 85 | self.titleLab.text = dateStr; 86 | weekNumber = [self.manager.helper numberOfWeeks:_date]; 87 | // 有几周 88 | if (_weeksViews.count) { 89 | [_weeksViews makeObjectsPerformSelector:@selector(removeFromSuperview)]; 90 | [_weeksViews removeAllObjects]; 91 | } 92 | NSDate *firstDay = [self.manager.helper firstDayOfMonth:_date]; 93 | CGFloat startY = self.dialogBuilder.LWCalendarTitleHeight + self.dialogBuilder.LWWeekIndicatorHeight + self.dialogBuilder.LWCalendarLineGap * 2; 94 | CGFloat startX = self.dialogBuilder.LWCalendarMarginH; 95 | CGFloat weekH = (self.frame.size.width - self.dialogBuilder.LWCalendarRowGap * 8 - self.dialogBuilder.LWCalendarMarginH * 2)/7; 96 | for (int i = 0; i < weekNumber; i++) { 97 | LWWeekView *weekView = [[LWWeekView alloc] initWithFrame:CGRectMake(startX, startY + (weekH + self.dialogBuilder.LWCalendarLineGap) * i, self.frame.size.width - self.dialogBuilder.LWCalendarMarginH * 2, weekH)]; 98 | weekView.monthDelegate = self; 99 | weekView.theMonthFirstDay = firstDay; 100 | weekView.date = [self.manager.helper addToDate:firstDay weeks:i]; 101 | weekView.dialogBuilder = self.dialogBuilder; 102 | [self addSubview:weekView]; 103 | [_weeksViews addObject:weekView]; 104 | } 105 | CGRect frame = self.frame; 106 | frame.size.height = weekNumber * weekH + self.dialogBuilder.LWCalendarTitleHeight + self.dialogBuilder.LWWeekIndicatorHeight + (weekNumber + 2) * self.dialogBuilder.LWCalendarLineGap; 107 | self.frame = frame; 108 | [self updateWithBuilder:self.dialogBuilder]; 109 | } 110 | 111 | - (UILabel *)titleLab { 112 | if (_titleLab == nil) { 113 | _titleLab = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width , self.dialogBuilder.LWCalendarTitleHeight)]; 114 | _titleLab.textAlignment = NSTextAlignmentCenter; 115 | 116 | [self addSubview:_titleLab]; 117 | } 118 | return _titleLab; 119 | } 120 | 121 | 122 | -(LWWeekIndicator *)weekIndicator{ 123 | if (_weekIndicator == nil) { 124 | _weekIndicator = [[LWWeekIndicator alloc] initWithFrame:CGRectMake(self.dialogBuilder.LWCalendarMarginH, self.dialogBuilder.LWCalendarTitleHeight + self.dialogBuilder.LWCalendarLineGap, self.frame.size.width - self.dialogBuilder.LWCalendarMarginH * 2, self.dialogBuilder.LWWeekIndicatorHeight)]; 125 | _weekIndicator.monthDelegate = self; 126 | [self addSubview:_weekIndicator]; 127 | } 128 | return _weekIndicator; 129 | } 130 | 131 | -(void)setDialogBuilder:(LWDatePickerBuilder *)dialogBuilder{ 132 | if (dialogBuilder && _dialogBuilder != dialogBuilder) { 133 | _dialogBuilder = dialogBuilder; 134 | [self updateWithBuilder:dialogBuilder]; 135 | } 136 | } 137 | 138 | -(LWDatePickerBuilder *)dialogBuilder{ 139 | if(_dialogBuilder == nil){ 140 | if (self.calendarDelegate) { 141 | _dialogBuilder = self.calendarDelegate.dialogBuilder; 142 | }else{ 143 | _dialogBuilder = [LWDatePickerBuilder defaultBuilder]; 144 | } 145 | } 146 | return _dialogBuilder; 147 | } 148 | 149 | #pragma mark 根据Build参数更新UI或者约束 150 | -(void)updateWithBuilder:(LWDatePickerBuilder *)builder{ 151 | //更新标题 152 | self.titleLab.font = builder.LWCalendarTitleFont; 153 | self.titleLab.textColor = builder.LWDatePickerViewDefaultTextColor; 154 | //更新week指示器 155 | self.weekIndicator.dialogBuilder = builder; 156 | //更新weekView 157 | for (int i = 0; i < weekNumber; i++) { 158 | LWWeekView *weekView = _weeksViews[i]; 159 | weekView.dialogBuilder = builder; 160 | } 161 | 162 | } 163 | 164 | @end 165 | -------------------------------------------------------------------------------- /LWCalendar/LWWeekIndicator.h: -------------------------------------------------------------------------------- 1 | // 2 | // LWWeekIndicator.h 3 | // PriceCalender 4 | // 5 | // Created by luwei on 2017/1/5. 6 | // Copyright © 2017年 HarrisHan. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class LWDatePickerBuilder, LWMonthView; 12 | 13 | @interface LWWeekIndicator : UIView 14 | @property (nonatomic, weak) LWDatePickerBuilder *dialogBuilder; 15 | @property (nonatomic, weak) LWMonthView *monthDelegate; 16 | @end 17 | -------------------------------------------------------------------------------- /LWCalendar/LWWeekIndicator.m: -------------------------------------------------------------------------------- 1 | // 2 | // LWWeekIndicator.m 3 | // PriceCalender 4 | // 5 | // Created by luwei on 2017/1/5. 6 | // Copyright © 2017年 HarrisHan. All rights reserved. 7 | // 8 | 9 | #import "LWCalendarHeader.h" 10 | 11 | @interface LWWeekIndicator () 12 | @property(nonatomic, strong) UILabel *label1; 13 | @property(nonatomic, strong) UILabel *label2; 14 | @property(nonatomic, strong) UILabel *label3; 15 | @property(nonatomic, strong) UILabel *label4; 16 | @property(nonatomic, strong) UILabel *label5; 17 | @property(nonatomic, strong) UILabel *label6; 18 | @property(nonatomic, strong) UILabel *label7; 19 | @end 20 | 21 | @implementation LWWeekIndicator 22 | 23 | @synthesize 24 | label1 = _label1, 25 | label2 = _label2, 26 | label3 = _label3, 27 | label4 = _label4, 28 | label5 = _label5, 29 | label6 = _label6, 30 | label7 = _label7, 31 | dialogBuilder = _dialogBuilder; 32 | 33 | -(instancetype)init{ 34 | if (self = [super init]) { 35 | self.label1.text = @"日"; 36 | self.label2.text = @"一"; 37 | self.label3.text = @"二"; 38 | self.label4.text = @"三"; 39 | self.label5.text = @"四"; 40 | self.label6.text = @"五"; 41 | self.label7.text = @"六"; 42 | [self updateWithBuilder:self.dialogBuilder]; 43 | } 44 | return self; 45 | } 46 | 47 | -(instancetype)initWithFrame:(CGRect)frame{ 48 | if (self = [super initWithFrame:frame]) { 49 | self.label1.text = @"日"; 50 | self.label2.text = @"一"; 51 | self.label3.text = @"二"; 52 | self.label4.text = @"三"; 53 | self.label5.text = @"四"; 54 | self.label6.text = @"五"; 55 | self.label7.text = @"六"; 56 | } 57 | return self; 58 | } 59 | 60 | #pragma mark Get and Set 61 | -(UILabel *)label1{ 62 | if (_label1 == nil) { 63 | _label1 = [[UILabel alloc] init]; 64 | _label1.translatesAutoresizingMaskIntoConstraints = NO; 65 | _label1.textAlignment = NSTextAlignmentCenter; 66 | [self addSubview:_label1]; 67 | //添加约束 68 | NSLayoutConstraint *viewWidth = [NSLayoutConstraint constraintWithItem:_label1 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeWidth multiplier:(1.0f/7.0f) constant:0.0]; 69 | NSLayoutConstraint *viewLeft = [NSLayoutConstraint constraintWithItem:_label1 attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0.0]; 70 | NSLayoutConstraint *viewHeight = [NSLayoutConstraint constraintWithItem:_label1 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0]; 71 | NSLayoutConstraint *viewBottom = [NSLayoutConstraint constraintWithItem:_label1 attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0]; 72 | [self addConstraint:viewWidth]; 73 | [self addConstraint:viewLeft]; 74 | [self addConstraint:viewBottom]; 75 | [self addConstraint:viewHeight]; 76 | } 77 | return _label1; 78 | } 79 | 80 | -(UILabel *)label2{ 81 | if (_label2 == nil) { 82 | _label2 = [[UILabel alloc] init]; 83 | _label2.translatesAutoresizingMaskIntoConstraints = NO; 84 | _label2.textAlignment = NSTextAlignmentCenter; 85 | [self addSubview:_label2]; 86 | //添加约束 87 | NSLayoutConstraint *viewWidth = [NSLayoutConstraint constraintWithItem:_label2 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeWidth multiplier:(1.0f/7.0f) constant:0.0]; 88 | NSLayoutConstraint *viewLeft = [NSLayoutConstraint constraintWithItem:_label2 attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.label1 attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0]; 89 | NSLayoutConstraint *viewHeight = [NSLayoutConstraint constraintWithItem:_label2 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0]; 90 | NSLayoutConstraint *viewBottom = [NSLayoutConstraint constraintWithItem:_label2 attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0]; 91 | [self addConstraint:viewWidth]; 92 | [self addConstraint:viewLeft]; 93 | [self addConstraint:viewBottom]; 94 | [self addConstraint:viewHeight]; 95 | } 96 | return _label2; 97 | } 98 | 99 | -(UILabel *)label3{ 100 | if (_label3 == nil) { 101 | _label3 = [[UILabel alloc] init]; 102 | _label3.translatesAutoresizingMaskIntoConstraints = NO; 103 | _label3.textAlignment = NSTextAlignmentCenter; 104 | [self addSubview:_label3]; 105 | //添加约束 106 | NSLayoutConstraint *viewWidth = [NSLayoutConstraint constraintWithItem:_label3 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeWidth multiplier:(1.0f/7.0f) constant:0.0]; 107 | NSLayoutConstraint *viewLeft = [NSLayoutConstraint constraintWithItem:_label3 attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.label2 attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0]; 108 | NSLayoutConstraint *viewHeight = [NSLayoutConstraint constraintWithItem:_label3 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0]; 109 | NSLayoutConstraint *viewBottom = [NSLayoutConstraint constraintWithItem:_label3 attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0]; 110 | [self addConstraint:viewWidth]; 111 | [self addConstraint:viewLeft]; 112 | [self addConstraint:viewBottom]; 113 | [self addConstraint:viewHeight]; 114 | } 115 | return _label3; 116 | } 117 | 118 | -(UILabel *)label4{ 119 | if (_label4 == nil) { 120 | _label4 = [[UILabel alloc] init]; 121 | _label4.translatesAutoresizingMaskIntoConstraints = NO; 122 | _label4.textAlignment = NSTextAlignmentCenter; 123 | [self addSubview:_label4]; 124 | //添加约束 125 | NSLayoutConstraint *viewWidth = [NSLayoutConstraint constraintWithItem:_label4 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeWidth multiplier:(1.0f/7.0f) constant:0.0]; 126 | NSLayoutConstraint *viewLeft = [NSLayoutConstraint constraintWithItem:_label4 attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.label3 attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0]; 127 | NSLayoutConstraint *viewHeight = [NSLayoutConstraint constraintWithItem:_label4 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0]; 128 | NSLayoutConstraint *viewBottom = [NSLayoutConstraint constraintWithItem:_label4 attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0]; 129 | [self addConstraint:viewWidth]; 130 | [self addConstraint:viewLeft]; 131 | [self addConstraint:viewBottom]; 132 | [self addConstraint:viewHeight]; 133 | } 134 | return _label4; 135 | } 136 | 137 | -(UILabel *)label5{ 138 | if (_label5 == nil) { 139 | _label5 = [[UILabel alloc] init]; 140 | _label5.translatesAutoresizingMaskIntoConstraints = NO; 141 | _label5.textAlignment = NSTextAlignmentCenter; 142 | [self addSubview:_label5]; 143 | //添加约束 144 | NSLayoutConstraint *viewWidth = [NSLayoutConstraint constraintWithItem:_label5 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeWidth multiplier:(1.0f/7.0f) constant:0.0]; 145 | NSLayoutConstraint *viewLeft = [NSLayoutConstraint constraintWithItem:_label5 attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.label4 attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0]; 146 | NSLayoutConstraint *viewHeight = [NSLayoutConstraint constraintWithItem:_label5 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0]; 147 | NSLayoutConstraint *viewBottom = [NSLayoutConstraint constraintWithItem:_label5 attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0]; 148 | [self addConstraint:viewWidth]; 149 | [self addConstraint:viewLeft]; 150 | [self addConstraint:viewBottom]; 151 | [self addConstraint:viewHeight]; 152 | } 153 | return _label5; 154 | } 155 | 156 | -(UILabel *)label6{ 157 | if (_label6 == nil) { 158 | _label6 = [[UILabel alloc] init]; 159 | _label6.translatesAutoresizingMaskIntoConstraints = NO; 160 | _label6.textAlignment = NSTextAlignmentCenter; 161 | [self addSubview:_label6]; 162 | //添加约束 163 | NSLayoutConstraint *viewWidth = [NSLayoutConstraint constraintWithItem:_label6 attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeWidth multiplier:(1.0f/7.0f) constant:0.0]; 164 | NSLayoutConstraint *viewLeft = [NSLayoutConstraint constraintWithItem:_label6 attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.label5 attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0]; 165 | NSLayoutConstraint *viewHeight = [NSLayoutConstraint constraintWithItem:_label6 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0]; 166 | NSLayoutConstraint *viewBottom = [NSLayoutConstraint constraintWithItem:_label6 attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0]; 167 | [self addConstraint:viewWidth]; 168 | [self addConstraint:viewLeft]; 169 | [self addConstraint:viewBottom]; 170 | [self addConstraint:viewHeight]; 171 | } 172 | return _label6; 173 | } 174 | 175 | -(UILabel *)label7{ 176 | if (_label7 == nil) { 177 | _label7 = [[UILabel alloc] init]; 178 | _label7.translatesAutoresizingMaskIntoConstraints = NO; 179 | _label7.textAlignment = NSTextAlignmentCenter; 180 | [self addSubview:_label7]; 181 | //添加约束 182 | NSLayoutConstraint *viewRight = [NSLayoutConstraint constraintWithItem:_label7 attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0]; 183 | NSLayoutConstraint *viewLeft = [NSLayoutConstraint constraintWithItem:_label7 attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.label6 attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0]; 184 | NSLayoutConstraint *viewHeight = [NSLayoutConstraint constraintWithItem:_label7 attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0.0]; 185 | NSLayoutConstraint *viewBottom = [NSLayoutConstraint constraintWithItem:_label7 attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0]; 186 | [self addConstraint:viewRight]; 187 | [self addConstraint:viewLeft]; 188 | [self addConstraint:viewBottom]; 189 | [self addConstraint:viewHeight]; 190 | } 191 | return _label7; 192 | } 193 | 194 | -(void)setDialogBuilder:(LWDatePickerBuilder *)dialogBuilder{ 195 | if (dialogBuilder && _dialogBuilder != dialogBuilder) { 196 | _dialogBuilder = dialogBuilder; 197 | [self updateWithBuilder:dialogBuilder]; 198 | } 199 | } 200 | 201 | -(LWDatePickerBuilder *)dialogBuilder{ 202 | if(_dialogBuilder == nil){ 203 | if (self.monthDelegate && self.monthDelegate.calendarDelegate && self.monthDelegate.calendarDelegate.dateViewDelegate) { 204 | _dialogBuilder = self.monthDelegate.calendarDelegate.dateViewDelegate.dialogBuilder; 205 | }else{ 206 | _dialogBuilder = [LWDatePickerBuilder defaultBuilder]; 207 | } 208 | } 209 | return _dialogBuilder; 210 | } 211 | 212 | 213 | #pragma mark 根据Build参数更新UI或者约束 214 | -(void)updateWithBuilder:(LWDatePickerBuilder *)builder{ 215 | //label设置 216 | _label1.textColor = self.dialogBuilder.LWWeekIndicatorTextColor; 217 | _label1.font = self.dialogBuilder.LWWeekIndicatorTextFont; 218 | _label2.textColor = self.dialogBuilder.LWWeekIndicatorTextColor; 219 | _label2.font = self.dialogBuilder.LWWeekIndicatorTextFont; 220 | _label3.textColor = self.dialogBuilder.LWWeekIndicatorTextColor; 221 | _label3.font = self.dialogBuilder.LWWeekIndicatorTextFont; 222 | _label4.textColor = self.dialogBuilder.LWWeekIndicatorTextColor; 223 | _label4.font = self.dialogBuilder.LWWeekIndicatorTextFont; 224 | _label5.textColor = self.dialogBuilder.LWWeekIndicatorTextColor; 225 | _label5.font = self.dialogBuilder.LWWeekIndicatorTextFont; 226 | _label6.textColor = self.dialogBuilder.LWWeekIndicatorTextColor; 227 | _label6.font = self.dialogBuilder.LWWeekIndicatorTextFont; 228 | _label7.textColor = self.dialogBuilder.LWWeekIndicatorTextColor; 229 | _label7.font = self.dialogBuilder.LWWeekIndicatorTextFont; 230 | } 231 | 232 | @end 233 | -------------------------------------------------------------------------------- /LWCalendar/LWWeekView.h: -------------------------------------------------------------------------------- 1 | // 2 | // LWWeekView.h 3 | // Example 4 | // 5 | // Created by Daniel on 16/10/28. 6 | // Copyright © 2016年 Daniel. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class LWMonthView, LWDatePickerBuilder; 12 | 13 | @interface LWWeekView : UIView 14 | @property (nonatomic, strong) NSDate *theMonthFirstDay; 15 | @property (nonatomic, strong) NSDate *date; 16 | @property (nonatomic, weak) LWMonthView *monthDelegate; 17 | @property (nonatomic, weak) LWDatePickerBuilder *dialogBuilder; 18 | @end 19 | -------------------------------------------------------------------------------- /LWCalendar/LWWeekView.m: -------------------------------------------------------------------------------- 1 | // 2 | // LWWeekView.m 3 | // Example 4 | // 5 | // Created by Daniel on 16/10/28. 6 | // Copyright © 2016年 Daniel. All rights reserved. 7 | // 8 | 9 | #import "LWCalendarHeader.h" 10 | 11 | @interface LWWeekView () 12 | @property(nonatomic, weak) LWCalendarManager *manager; 13 | @end 14 | 15 | @implementation LWWeekView { 16 | CGFloat dayViewWidth; 17 | CGFloat dayViewHeight; 18 | CGSize lastSize; 19 | NSMutableArray *dayViews; 20 | } 21 | @synthesize monthDelegate = _monthDelegate, dialogBuilder = _dialogBuilder; 22 | 23 | - (instancetype)initWithFrame:(CGRect)frame { 24 | if (self = [super initWithFrame:frame]) { 25 | [self commonInit]; 26 | } 27 | return self; 28 | } 29 | 30 | -(instancetype)init{ 31 | if (self = [super init]) { 32 | [self commonInit]; 33 | } 34 | return self; 35 | } 36 | 37 | -(void)commonInit{ 38 | dayViews = [NSMutableArray new]; 39 | dayViewWidth = self.frame.size.width / 7; 40 | dayViewHeight = (self.frame.size.width - self.dialogBuilder.LWCalendarRowGap * 8 ) / 7; 41 | [self updateWithBuilder:self.dialogBuilder]; 42 | } 43 | 44 | -(void)layoutSubviews{ 45 | CGSize size = self.frame.size; 46 | if (!lastSize.width || size.width != lastSize.width || size.height != lastSize.height) { 47 | lastSize = size; 48 | [self resize]; 49 | } 50 | } 51 | 52 | - (void)resize { 53 | if (dayViews.count > 0) { 54 | dayViewWidth = self.frame.size.width / 7; 55 | dayViewHeight = (self.frame.size.width - self.dialogBuilder.LWCalendarRowGap * 8 ) / 7; 56 | 57 | for (int i = 0; i < 7; i++) { 58 | LWDayView *dayView = dayViews[i]; 59 | dayView.frame = CGRectMake(dayViewWidth * i, 0, dayViewWidth, dayViewHeight); 60 | } 61 | } 62 | } 63 | 64 | 65 | 66 | #pragma mark Get and Set 67 | -(void)setMonthDelegate:(LWMonthView *)monthDelegate{ 68 | _monthDelegate = monthDelegate; 69 | _manager = _monthDelegate.calendarDelegate.dateViewDelegate.dialogDelegate.manager; 70 | } 71 | 72 | - (void)setDate:(NSDate *)date { 73 | _date = date; 74 | if (dayViews.count) { 75 | [dayViews makeObjectsPerformSelector:@selector(removeFromSuperview)]; 76 | [dayViews removeAllObjects]; 77 | } 78 | NSDate *firstDate = [self.manager.helper firstWeekDayOfWeek:_date]; 79 | 80 | for (int i = 0; i < 7; i++) { 81 | LWDayView *dayView = [[LWDayView alloc] initWithFrame:CGRectMake(dayViewWidth * i, 0, dayViewWidth, dayViewHeight)]; 82 | dayView.weekDelegate = self; 83 | dayView.dialogBuilder = self.dialogBuilder; 84 | NSDate *dayDate = [self.manager.helper addToDate:firstDate days:i]; 85 | 86 | BOOL isSameMonth = [self.manager.helper date:dayDate isTheSameMonthThan:_theMonthFirstDay]; 87 | if (!isSameMonth) { 88 | 89 | if ([self.manager.helper date:dayDate isAfter:[self.manager.helper lastDayOfMonth:_theMonthFirstDay]]) { 90 | dayDate = [self.manager.helper lastDayOfMonth:_theMonthFirstDay]; 91 | } else if ([self.manager.helper date:dayDate isBefore:_theMonthFirstDay]) { 92 | dayDate = _theMonthFirstDay; 93 | } 94 | } 95 | dayView.enabled = isSameMonth; 96 | dayView.date = dayDate; 97 | 98 | [self addSubview:dayView]; 99 | [dayViews addObject:dayView]; 100 | } 101 | } 102 | 103 | -(void)setDialogBuilder:(LWDatePickerBuilder *)dialogBuilder{ 104 | if (dialogBuilder && _dialogBuilder != dialogBuilder) { 105 | _dialogBuilder = dialogBuilder; 106 | [self updateWithBuilder:dialogBuilder]; 107 | } 108 | } 109 | 110 | -(LWDatePickerBuilder *)dialogBuilder{ 111 | if(_dialogBuilder == nil){ 112 | if (self.monthDelegate) { 113 | _dialogBuilder = self.monthDelegate.dialogBuilder; 114 | }else{ 115 | _dialogBuilder = [LWDatePickerBuilder defaultBuilder]; 116 | } 117 | } 118 | return _dialogBuilder; 119 | } 120 | 121 | #pragma mark 根据Build参数更新UI或者约束 122 | -(void)updateWithBuilder:(LWDatePickerBuilder *)builder{ 123 | //dayView设置 124 | for (int i = 0; i < dayViews.count; i++) { 125 | LWDayView *dayView = dayViews[i]; 126 | dayView.dialogBuilder = builder; 127 | } 128 | } 129 | 130 | @end 131 | -------------------------------------------------------------------------------- /LWCalendar/NSBundle+LWCalendar.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSBundle+MJRefresh.h 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 16/6/13. 6 | // Copyright © 2016年 小码哥. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSBundle (LWCalendar) 12 | + (instancetype)LWCalendarBundle; 13 | + (UIImage *)LWCalendarCircleImage; 14 | + (UIImage *)LWCalendarStartFilterImage; 15 | + (UIImage *)LWCalendarEndFilterImage; 16 | @end 17 | -------------------------------------------------------------------------------- /LWCalendar/NSBundle+LWCalendar.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSBundle+MJRefresh.m 3 | // MJRefreshExample 4 | // 5 | // Created by MJ Lee on 16/6/13. 6 | // Copyright © 2016年 小码哥. All rights reserved. 7 | // 8 | 9 | #import "LWCalendarHeader.h" 10 | 11 | @implementation NSBundle (LWCalendar) 12 | 13 | + (instancetype)LWCalendarBundle{ 14 | static NSBundle *calendarBundle = nil; 15 | if (calendarBundle == nil) { 16 | // 这里不使用mainBundle是为了适配pod 1.x和0.x 17 | calendarBundle = [NSBundle bundleWithPath:[[NSBundle bundleForClass:[LWDayView class]] pathForResource:@"LWCalendar" ofType:@"bundle"]]; 18 | } 19 | return calendarBundle; 20 | } 21 | 22 | + (UIImage *)LWCalendarCircleImage{ 23 | static UIImage *circleImage = nil; 24 | if (circleImage == nil) { 25 | circleImage = [[UIImage imageWithContentsOfFile:[[self LWCalendarBundle] pathForResource:@"circle@2x" ofType:@"png"]] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; 26 | } 27 | return circleImage; 28 | } 29 | 30 | + (UIImage *)LWCalendarStartFilterImage{ 31 | static UIImage *startFiltermage = nil; 32 | if (startFiltermage == nil) { 33 | startFiltermage = [[UIImage imageWithContentsOfFile:[[self LWCalendarBundle] pathForResource:@"start_filter@2x" ofType:@"png"]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; 34 | } 35 | return startFiltermage; 36 | } 37 | 38 | + (UIImage *)LWCalendarEndFilterImage{ 39 | static UIImage *endFilterImage = nil; 40 | if (endFilterImage == nil) { 41 | endFilterImage = [[UIImage imageWithContentsOfFile:[[self LWCalendarBundle] pathForResource:@"end_filter@2x" ofType:@"png"]] imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal]; 42 | } 43 | return endFilterImage; 44 | } 45 | @end 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LWCalendar 2 | 参考[ZYCalendarView](https://github.com/Yanyinghenmei/ZYCalendarView) 模仿了Android的material design设计 3 | 4 | ![calender.gif](http://luwei2012.github.io/images/IOS/CustomView/ZYCalender_Record.gif) 5 | 6 | 目前还没有开放定制化的API,想要定制UI只能修改源码 7 | ## Usage 8 | ### 推荐使用pod 9 | 10 | 1. 在podfile中添加pod 'LWCalendar' 11 | 12 | 2.在需要使用的地方添加 13 | 14 | ```objc 15 | #import "LWCalendarHeader.h" 16 | ``` 17 | 3.实现代理DatePickerDelegate 18 | ```objc 19 | @interface ViewController () 20 | 21 | @end 22 | 23 | -(void)onDateSet:(LWDatePickerDialog *)dialog StartDate:(NSDate *)start EndDate:(NSDate *)end{ 24 | NSLog(@"onDateSet"); 25 | } 26 | 27 | ``` 28 | 4.创建和显示 29 | ```objc 30 | [[LWDatePickerDialog initWithDate:[NSDate date] Delegate:self] show]; 31 | ``` 32 | ### 使用源码 33 | 34 | 1.下载源码,将LWCalendar文件夹加入自己的工程 35 | 36 | 2.在需要使用的地方添加 37 | 38 | ```objc 39 | #import "LWCalendarHeader.h" 40 | ``` 41 | 3.实现代理DatePickerDelegate 42 | ```objc 43 | @interface ViewController () 44 | 45 | @end 46 | 47 | -(void)onDateSet:(LWDatePickerDialog *)dialog StartDate:(NSDate *)start EndDate:(NSDate *)end{ 48 | NSLog(@"onDateSet"); 49 | } 50 | 51 | ``` 52 | 4.创建和显示 53 | ```objc 54 | [[LWDatePickerDialog initWithDate:[NSDate date] Delegate:self] show]; 55 | ``` 56 | 57 | ## 部分参数说明 58 | ![calender.gif](http://luwei2012.github.io/images/IOS/CustomView/LWCalendar标注.png) 59 | 60 | 几乎UI的每个部分都可以定制,具体参见LWDatePickerBuilder里面的参数说明 61 | 62 | ## To do 63 | 64 | 1.寻找UI设计师帮忙设计布局,这个布局还是有点丑...... 65 | 66 | 2.设计和开放多选模式的接口 67 | 68 | 3.添加时间选择器,就是Android上看着很炫的钟表 69 | 70 | ## Author 71 | 72 | luwei2012 73 | 74 | ## License 75 | 76 | CoreTextView is available under the GNU license. See the LICENSE file for more info. 77 | -------------------------------------------------------------------------------- /_Pods.xcodeproj: -------------------------------------------------------------------------------- 1 | Example/Pods/Pods.xcodeproj --------------------------------------------------------------------------------