├── .gitignore ├── .swift-version ├── Demo ├── Demo │ ├── zh-Hans.lproj │ │ ├── LaunchScreen.strings │ │ └── Main.strings │ ├── Info.plist │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── ViewController.swift │ └── AppDelegate.swift ├── Pods │ ├── Target Support Files │ │ ├── Pods-Demo │ │ │ ├── Pods-Demo.modulemap │ │ │ ├── Pods-Demo-dummy.m │ │ │ ├── Pods-Demo-umbrella.h │ │ │ ├── Pods-Demo.debug.xcconfig │ │ │ ├── Pods-Demo.release.xcconfig │ │ │ ├── Info.plist │ │ │ ├── Pods-Demo-acknowledgements.markdown │ │ │ ├── Pods-Demo-acknowledgements.plist │ │ │ ├── Pods-Demo-frameworks.sh │ │ │ └── Pods-Demo-resources.sh │ │ ├── FSCalendar │ │ │ ├── FSCalendar.modulemap │ │ │ ├── FSCalendar-dummy.m │ │ │ ├── FSCalendar-prefix.pch │ │ │ ├── FSCalendar.xcconfig │ │ │ ├── Info.plist │ │ │ └── FSCalendar-umbrella.h │ │ └── PGActionSheetCalendar │ │ │ ├── PGActionSheetCalendar.modulemap │ │ │ ├── PGActionSheetCalendar-dummy.m │ │ │ ├── PGActionSheetCalendar-prefix.pch │ │ │ ├── PGActionSheetCalendar-umbrella.h │ │ │ ├── PGActionSheetCalendar.xcconfig │ │ │ └── Info.plist │ ├── Manifest.lock │ ├── FSCalendar │ │ ├── FSCalendar │ │ │ ├── FSCalendarCollectionView.h │ │ │ ├── FSCalendarDelegationFactory.h │ │ │ ├── FSCalendarScopeHandle.h │ │ │ ├── FSCalendarStickyHeader.h │ │ │ ├── FSCalendarWeekdayView.h │ │ │ ├── FSCalendarCollectionViewLayout.h │ │ │ ├── FSCalendarDelegationProxy.h │ │ │ ├── FSCalendarHeaderView.h │ │ │ ├── FSCalendarConstants.m │ │ │ ├── FSCalendarDelegationFactory.m │ │ │ ├── FSCalendarCalculator.h │ │ │ ├── FSCalendarTransitionCoordinator.h │ │ │ ├── FSCalendarDelegationProxy.m │ │ │ ├── FSCalendarScopeHandle.m │ │ │ ├── FSCalendarExtensions.h │ │ │ ├── FSCalendarCollectionView.m │ │ │ ├── FSCalendarDynamicHeader.h │ │ │ ├── FSCalendarCell.h │ │ │ ├── FSCalendarWeekdayView.m │ │ │ ├── FSCalendarStickyHeader.m │ │ │ ├── FSCalendarConstants.h │ │ │ ├── FSCalendarAppearance.h │ │ │ ├── FSCalendar+Deprecated.m │ │ │ ├── FSCalendarHeaderView.m │ │ │ ├── FSCalendarCalculator.m │ │ │ ├── FSCalendarExtensions.m │ │ │ └── FSCalendarAppearance.m │ │ ├── LICENSE │ │ └── README.md │ ├── PGActionSheetCalendar │ │ ├── PGActionSheetCalendar │ │ │ ├── PGActionSheetCalendarDelegate.swift │ │ │ ├── PGActionSheetCalendarView.swift │ │ │ ├── PGActionSheetCalendar.swift │ │ │ └── PGActionSheetCalendarHeader.swift │ │ ├── LICENSE │ │ └── README.md │ └── Pods.xcodeproj │ │ └── xcuserdata │ │ └── piggybear.xcuserdatad │ │ └── xcschemes │ │ ├── xcschememanagement.plist │ │ ├── Pods-Demo.xcscheme │ │ ├── FSCalendar.xcscheme │ │ └── PGActionSheetCalendar.xcscheme ├── Podfile ├── Demo.xcodeproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcuserdata │ │ │ └── piggybear.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── xcuserdata │ │ └── piggybear.xcuserdatad │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── Demo.xcworkspace │ ├── xcuserdata │ │ └── piggybear.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ └── contents.xcworkspacedata └── Podfile.lock ├── PGActionSheetCalendar.gif ├── PGActionSheetCalendar ├── PGActionSheetCalendarDelegate.swift ├── PGActionSheetCalendarView.swift ├── PGActionSheetCalendar.swift └── PGActionSheetCalendarHeader.swift ├── PGActionSheetCalendar.podspec ├── LICENSE └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.swift-version: -------------------------------------------------------------------------------- 1 | 3.0 2 | -------------------------------------------------------------------------------- /Demo/Demo/zh-Hans.lproj/LaunchScreen.strings: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /PGActionSheetCalendar.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhuxiong121/PGActionSheetCalendar/HEAD/PGActionSheetCalendar.gif -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-Demo/Pods-Demo.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_Demo { 2 | umbrella header "Pods-Demo-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/FSCalendar/FSCalendar.modulemap: -------------------------------------------------------------------------------- 1 | framework module FSCalendar { 2 | umbrella header "FSCalendar-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Demo/Podfile: -------------------------------------------------------------------------------- 1 | source 'https://github.com/CocoaPods/Specs.git' 2 | 3 | use_frameworks! 4 | platform :ios, '8.0' 5 | 6 | target ‘Demo’ do 7 | pod 'PGActionSheetCalendar' 8 | end 9 | 10 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-Demo/Pods-Demo-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_Demo : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_Demo 5 | @end 6 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/FSCalendar/FSCalendar-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_FSCalendar : NSObject 3 | @end 4 | @implementation PodsDummy_FSCalendar 5 | @end 6 | -------------------------------------------------------------------------------- /Demo/Demo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Demo/Demo.xcworkspace/xcuserdata/piggybear.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhuxiong121/PGActionSheetCalendar/HEAD/Demo/Demo.xcworkspace/xcuserdata/piggybear.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/PGActionSheetCalendar/PGActionSheetCalendar.modulemap: -------------------------------------------------------------------------------- 1 | framework module PGActionSheetCalendar { 2 | umbrella header "PGActionSheetCalendar-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/PGActionSheetCalendar/PGActionSheetCalendar-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_PGActionSheetCalendar : NSObject 3 | @end 4 | @implementation PodsDummy_PGActionSheetCalendar 5 | @end 6 | -------------------------------------------------------------------------------- /Demo/Demo.xcodeproj/project.xcworkspace/xcuserdata/piggybear.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xiaozhuxiong121/PGActionSheetCalendar/HEAD/Demo/Demo.xcodeproj/project.xcworkspace/xcuserdata/piggybear.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Demo/Demo.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/FSCalendar/FSCalendar-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/PGActionSheetCalendar/PGActionSheetCalendar-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Demo/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - FSCalendar (2.7.9) 3 | - PGActionSheetCalendar (1.0.5): 4 | - FSCalendar 5 | 6 | DEPENDENCIES: 7 | - PGActionSheetCalendar 8 | 9 | SPEC CHECKSUMS: 10 | FSCalendar: a04b09f16f811bc92e82f3cf852a15225233b9d5 11 | PGActionSheetCalendar: 136ba67ddc70afe58a63cc0ef6b3fe66ac8807e5 12 | 13 | PODFILE CHECKSUM: 594666a7667363d3b16c0f5388b9fd297f4e276e 14 | 15 | COCOAPODS: 1.3.1 16 | -------------------------------------------------------------------------------- /Demo/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - FSCalendar (2.7.9) 3 | - PGActionSheetCalendar (1.0.5): 4 | - FSCalendar 5 | 6 | DEPENDENCIES: 7 | - PGActionSheetCalendar 8 | 9 | SPEC CHECKSUMS: 10 | FSCalendar: a04b09f16f811bc92e82f3cf852a15225233b9d5 11 | PGActionSheetCalendar: 136ba67ddc70afe58a63cc0ef6b3fe66ac8807e5 12 | 13 | PODFILE CHECKSUM: 594666a7667363d3b16c0f5388b9fd297f4e276e 14 | 15 | COCOAPODS: 1.3.1 16 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-Demo/Pods-Demo-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_DemoVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_DemoVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarCollectionView.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarCollectionView.h 3 | // FSCalendar 4 | // 5 | // Created by Wenchao Ding on 10/25/15. 6 | // Copyright (c) 2015 Wenchao Ding. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FSCalendarCollectionView : UICollectionView 12 | 13 | @end 14 | 15 | 16 | @interface FSCalendarSeparator : UICollectionReusableView 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /Demo/Demo.xcodeproj/xcuserdata/piggybear.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Demo.xcscheme 8 | 9 | orderHint 10 | 3 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /PGActionSheetCalendar/PGActionSheetCalendarDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PGActionSheetCalendarDelegate.swift 3 | // PGActionSheetCalendar 4 | // 5 | // Created by piggybear on 2017/10/12. 6 | // Copyright © 2017年 piggybear. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | @objc public protocol PGActionSheetCalendarDelegate: NSObjectProtocol { 12 | @objc optional func calendar(_ calendar: PGActionSheetCalendar, didSelectDate components: DateComponents) 13 | } 14 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/PGActionSheetCalendar/PGActionSheetCalendar-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double PGActionSheetCalendarVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char PGActionSheetCalendarVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarDelegationFactory.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarDelegationFactory.h 3 | // FSCalendar 4 | // 5 | // Created by dingwenchao on 19/12/2016. 6 | // Copyright © 2016 wenchaoios. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "FSCalendarDelegationProxy.h" 11 | 12 | @interface FSCalendarDelegationFactory : NSObject 13 | 14 | + (FSCalendarDelegationProxy *)dataSourceProxy; 15 | + (FSCalendarDelegationProxy *)delegateProxy; 16 | 17 | @end 18 | -------------------------------------------------------------------------------- /Demo/Pods/PGActionSheetCalendar/PGActionSheetCalendar/PGActionSheetCalendarDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PGActionSheetCalendarDelegate.swift 3 | // PGActionSheetCalendar 4 | // 5 | // Created by piggybear on 2017/10/12. 6 | // Copyright © 2017年 piggybear. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | @objc public protocol PGActionSheetCalendarDelegate: NSObjectProtocol { 12 | @objc optional func calendar(_ calendar: PGActionSheetCalendar, didSelectDate components: DateComponents) 13 | } 14 | -------------------------------------------------------------------------------- /Demo/Demo/zh-Hans.lproj/Main.strings: -------------------------------------------------------------------------------- 1 | 2 | /* Class = "UIButton"; normalTitle = "基本用法"; ObjectID = "2B8-Lj-G44"; */ 3 | "2B8-Lj-G44.normalTitle" = "基本用法"; 4 | 5 | /* Class = "UIButton"; normalTitle = "设置按钮样式"; ObjectID = "31e-M5-GNT"; */ 6 | "31e-M5-GNT.normalTitle" = "设置按钮样式"; 7 | 8 | /* Class = "UIButton"; normalTitle = "设置日历样式"; ObjectID = "Z4y-NA-fZP"; */ 9 | "Z4y-NA-fZP.normalTitle" = "设置日历样式"; 10 | 11 | /* Class = "UIButton"; normalTitle = "设置Title"; ObjectID = "uzX-95-6QY"; */ 12 | "uzX-95-6QY.normalTitle" = "设置Title"; 13 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarScopeHandle.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarScopeHandle.h 3 | // FSCalendar 4 | // 5 | // Created by dingwenchao on 4/29/16. 6 | // Copyright © 2016 Wenchao Ding. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class FSCalendar; 12 | 13 | @interface FSCalendarScopeHandle : UIView 14 | 15 | @property (weak, nonatomic) UIPanGestureRecognizer *panGesture; 16 | @property (weak, nonatomic) FSCalendar *calendar; 17 | 18 | - (void)handlePan:(id)sender; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarStickyHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarStaticHeader.h 3 | // FSCalendar 4 | // 5 | // Created by dingwenchao on 9/17/15. 6 | // Copyright (c) 2015 Wenchao Ding. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class FSCalendar,FSCalendarAppearance; 12 | 13 | @interface FSCalendarStickyHeader : UICollectionReusableView 14 | 15 | @property (weak, nonatomic) FSCalendar *calendar; 16 | 17 | @property (weak, nonatomic) UILabel *titleLabel; 18 | 19 | @property (strong, nonatomic) NSDate *month; 20 | 21 | - (void)configureAppearance; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/FSCalendar/FSCalendar.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/FSCalendar 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" 4 | OTHER_LDFLAGS = -framework "QuartzCore" -framework "UIKit" 5 | PODS_BUILD_DIR = $BUILD_DIR 6 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/FSCalendar 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarWeekdayView.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarWeekdayView.h 3 | // FSCalendar 4 | // 5 | // Created by dingwenchao on 03/11/2016. 6 | // Copyright © 2016 dingwenchao. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @class FSCalendar; 15 | 16 | @interface FSCalendarWeekdayView : UIView 17 | 18 | /** 19 | An array of UILabel objects displaying the weekday symbols. 20 | */ 21 | @property (readonly, nonatomic) NSArray *weekdayLabels; 22 | 23 | - (void)configureAppearance; 24 | 25 | @end 26 | 27 | NS_ASSUME_NONNULL_END 28 | -------------------------------------------------------------------------------- /PGActionSheetCalendar.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = "PGActionSheetCalendar" 3 | s.version = "1.0.5" 4 | s.summary = "PGActionSheetCalendar" 5 | s.homepage = "https://github.com/xiaozhuxiong121/PGActionSheetCalendar" 6 | s.license = "MIT" 7 | s.author = { "piggybear" => "piggybear_net@163.com" } 8 | s.platform = :ios, "8.0" 9 | s.source = { :git => "https://github.com/xiaozhuxiong121/PGActionSheetCalendar.git", :tag => s.version } 10 | s.source_files = "PGActionSheetCalendar", "PGActionSheetCalendar/**/*.swift" 11 | s.frameworks = "UIKit" 12 | s.requires_arc = true 13 | 14 | s.dependency 'FSCalendar' 15 | end 16 | 17 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarCollectionViewLayout.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarAnimationLayout.h 3 | // FSCalendar 4 | // 5 | // Created by dingwenchao on 1/3/16. 6 | // Copyright © 2016 Wenchao Ding. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class FSCalendar; 12 | 13 | @interface FSCalendarCollectionViewLayout : UICollectionViewLayout 14 | 15 | @property (weak, nonatomic) FSCalendar *calendar; 16 | 17 | @property (assign, nonatomic) CGFloat interitemSpacing; 18 | @property (assign, nonatomic) UIEdgeInsets sectionInsets; 19 | @property (assign, nonatomic) UICollectionViewScrollDirection scrollDirection; 20 | @property (assign, nonatomic) CGSize headerReferenceSize; 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Demo/Pods/Pods.xcodeproj/xcuserdata/piggybear.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | FSCalendar.xcscheme 8 | 9 | isShown 10 | 11 | 12 | PGActionSheetCalendar.xcscheme 13 | 14 | isShown 15 | 16 | 17 | Pods-Demo.xcscheme 18 | 19 | isShown 20 | 21 | 22 | 23 | SuppressBuildableAutocreation 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/PGActionSheetCalendar/PGActionSheetCalendar.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = $PODS_CONFIGURATION_BUILD_DIR/PGActionSheetCalendar 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/FSCalendar" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Private" "${PODS_ROOT}/Headers/Public" 5 | OTHER_LDFLAGS = -framework "UIKit" 6 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 7 | PODS_BUILD_DIR = $BUILD_DIR 8 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 9 | PODS_ROOT = ${SRCROOT} 10 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/PGActionSheetCalendar 11 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 12 | SKIP_INSTALL = YES 13 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarDelegationProxy.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarDelegationProxy.h 3 | // FSCalendar 4 | // 5 | // Created by dingwenchao on 11/12/2016. 6 | // Copyright © 2016 Wenchao Ding. All rights reserved. 7 | // 8 | // https://github.com/WenchaoD 9 | // 10 | // 1. Smart proxy delegation http://petersteinberger.com/blog/2013/smart-proxy-delegation/ 11 | // 2. Manage deprecated delegation functions 12 | // 13 | 14 | #import 15 | #import "FSCalendar.h" 16 | 17 | NS_ASSUME_NONNULL_BEGIN 18 | 19 | @interface FSCalendarDelegationProxy : NSProxy 20 | 21 | @property (weak , nonatomic) id delegation; 22 | @property (strong, nonatomic) Protocol *protocol; 23 | @property (strong, nonatomic) NSDictionary *deprecations; 24 | 25 | - (instancetype)init; 26 | - (SEL)deprecatedSelectorOfSelector:(SEL)selector; 27 | 28 | @end 29 | 30 | NS_ASSUME_NONNULL_END 31 | 32 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-Demo/Pods-Demo.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/FSCalendar" "$PODS_CONFIGURATION_BUILD_DIR/PGActionSheetCalendar" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/FSCalendar/FSCalendar.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/PGActionSheetCalendar/PGActionSheetCalendar.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "FSCalendar" -framework "PGActionSheetCalendar" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = $BUILD_DIR 9 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-Demo/Pods-Demo.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "$PODS_CONFIGURATION_BUILD_DIR/FSCalendar" "$PODS_CONFIGURATION_BUILD_DIR/PGActionSheetCalendar" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 5 | OTHER_CFLAGS = $(inherited) -iquote "$PODS_CONFIGURATION_BUILD_DIR/FSCalendar/FSCalendar.framework/Headers" -iquote "$PODS_CONFIGURATION_BUILD_DIR/PGActionSheetCalendar/PGActionSheetCalendar.framework/Headers" 6 | OTHER_LDFLAGS = $(inherited) -framework "FSCalendar" -framework "PGActionSheetCalendar" 7 | OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" 8 | PODS_BUILD_DIR = $BUILD_DIR 9 | PODS_CONFIGURATION_BUILD_DIR = $PODS_BUILD_DIR/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/FSCalendar/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 | 2.7.9 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-Demo/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 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/PGActionSheetCalendar/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.5 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/FSCalendar/FSCalendar-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | #import "FSCalendar.h" 14 | #import "FSCalendarAppearance.h" 15 | #import "FSCalendarCalculator.h" 16 | #import "FSCalendarCell.h" 17 | #import "FSCalendarCollectionView.h" 18 | #import "FSCalendarCollectionViewLayout.h" 19 | #import "FSCalendarConstants.h" 20 | #import "FSCalendarDelegationFactory.h" 21 | #import "FSCalendarDelegationProxy.h" 22 | #import "FSCalendarDynamicHeader.h" 23 | #import "FSCalendarExtensions.h" 24 | #import "FSCalendarHeaderView.h" 25 | #import "FSCalendarScopeHandle.h" 26 | #import "FSCalendarStickyHeader.h" 27 | #import "FSCalendarTransitionCoordinator.h" 28 | #import "FSCalendarWeekdayView.h" 29 | 30 | FOUNDATION_EXPORT double FSCalendarVersionNumber; 31 | FOUNDATION_EXPORT const unsigned char FSCalendarVersionString[]; 32 | 33 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 piggybear 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Demo/Pods/PGActionSheetCalendar/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 piggybear 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013-2016 FSCalendar (https://github.com/WenchaoD/FSCalendar) 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![PGActionSheetCalendar](PGActionSheetCalendar.gif) 2 | 3 | # PGActionSheetCalendar 4 | > 使用FSCalendar进行封装的 5 | 6 | # CocoaPods安装 7 | ``` 8 | pod 'PGActionSheetCalendar' 9 | ``` 10 | # 使用 11 | ``` 12 | let calendar = PGActionSheetCalendar() 13 | present(calendar, animated: false, completion: nil) 14 | ``` 15 | # 高级用法 16 | 有两种监听选中日期的方法 17 | 18 | 1、代理 19 | 20 | ``` 21 | calendar.delegate = self 22 | 23 | func calendar(_ calendar: PGActionSheetCalendar, didSelectDate components: DateComponents) { 24 | print("year = ", components.year!,"month = ", components.month!, "day = ", components.day!) 25 | } 26 | ``` 27 | 2、闭包 28 | 29 | ``` 30 | calendar.didSelectDateComponents = {components in 31 | print("year = ", components.year!,"month = ", components.month!, "day = ", components.day!) 32 | } 33 | ``` 34 | 设置title 35 | 36 | ``` 37 | let label = calendar.titleLabel 38 | label.text = "PGCalendar" 39 | ``` 40 | 41 | 设置按钮的样式 42 | 43 | ``` 44 | calendar.cancelButton.setTitleColor(UIColor.red, for: .normal) 45 | calendar.sureButton.setTitleColor(UIColor.red, for: .normal) 46 | ``` 47 | 48 | 设置日历的样式 49 | 50 | [https://github.com/WenchaoD/FSCalendar](https://github.com/WenchaoD/FSCalendar/blob/master/MOREUSAGE.md) -------------------------------------------------------------------------------- /Demo/Pods/PGActionSheetCalendar/README.md: -------------------------------------------------------------------------------- 1 | ![PGActionSheetCalendar](PGActionSheetCalendar.gif) 2 | 3 | # PGActionSheetCalendar 4 | > 使用FSCalendar进行封装的 5 | 6 | # CocoaPods安装 7 | ``` 8 | pod 'PGActionSheetCalendar' 9 | ``` 10 | # 使用 11 | ``` 12 | let calendar = PGActionSheetCalendar() 13 | present(calendar, animated: false, completion: nil) 14 | ``` 15 | # 高级用法 16 | 有两种监听选中日期的方法 17 | 18 | 1、代理 19 | 20 | ``` 21 | calendar.delegate = self 22 | 23 | func calendar(_ calendar: PGActionSheetCalendar, didSelectDate components: DateComponents) { 24 | print("year = ", components.year!,"month = ", components.month!, "day = ", components.day!) 25 | } 26 | ``` 27 | 2、闭包 28 | 29 | ``` 30 | calendar.didSelectDateComponents = {components in 31 | print("year = ", components.year!,"month = ", components.month!, "day = ", components.day!) 32 | } 33 | ``` 34 | 设置title 35 | 36 | ``` 37 | let label = calendar.titleLabel 38 | label.text = "PGCalendar" 39 | ``` 40 | 41 | 设置按钮的样式 42 | 43 | ``` 44 | calendar.cancelButton.setTitleColor(UIColor.red, for: .normal) 45 | calendar.sureButton.setTitleColor(UIColor.red, for: .normal) 46 | ``` 47 | 48 | 设置日历的样式 49 | 50 | [https://github.com/WenchaoD/FSCalendar](https://github.com/WenchaoD/FSCalendar/blob/master/MOREUSAGE.md) -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarHeaderView.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarHeader.h 3 | // Pods 4 | // 5 | // Created by Wenchao Ding on 29/1/15. 6 | // 7 | // 8 | 9 | #import 10 | 11 | 12 | @class FSCalendar, FSCalendarAppearance, FSCalendarHeaderLayout, FSCalendarCollectionView; 13 | 14 | @interface FSCalendarHeaderView : UIView 15 | 16 | @property (weak, nonatomic) FSCalendarCollectionView *collectionView; 17 | @property (weak, nonatomic) FSCalendarHeaderLayout *collectionViewLayout; 18 | @property (weak, nonatomic) FSCalendar *calendar; 19 | 20 | @property (assign, nonatomic) CGFloat scrollOffset; 21 | @property (assign, nonatomic) UICollectionViewScrollDirection scrollDirection; 22 | @property (assign, nonatomic) BOOL scrollEnabled; 23 | @property (assign, nonatomic) BOOL needsAdjustingViewFrame; 24 | @property (assign, nonatomic) BOOL needsAdjustingMonthPosition; 25 | 26 | - (void)setScrollOffset:(CGFloat)scrollOffset animated:(BOOL)animated; 27 | - (void)reloadData; 28 | - (void)configureAppearance; 29 | 30 | @end 31 | 32 | 33 | @interface FSCalendarHeaderCell : UICollectionViewCell 34 | 35 | @property (weak, nonatomic) UILabel *titleLabel; 36 | @property (weak, nonatomic) FSCalendarHeaderView *header; 37 | 38 | @end 39 | 40 | @interface FSCalendarHeaderLayout : UICollectionViewFlowLayout 41 | 42 | @end 43 | 44 | @interface FSCalendarHeaderTouchDeliver : UIView 45 | 46 | @property (weak, nonatomic) FSCalendar *calendar; 47 | @property (weak, nonatomic) FSCalendarHeaderView *header; 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /Demo/Demo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Demo/Demo/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarConstants.m: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarConstane.m 3 | // FSCalendar 4 | // 5 | // Created by dingwenchao on 8/28/15. 6 | // Copyright © 2016 Wenchao Ding. All rights reserved. 7 | // 8 | // https://github.com/WenchaoD 9 | // 10 | 11 | #import "FSCalendarConstants.h" 12 | 13 | CGFloat const FSCalendarStandardHeaderHeight = 40; 14 | CGFloat const FSCalendarStandardWeekdayHeight = 25; 15 | CGFloat const FSCalendarStandardMonthlyPageHeight = 300.0; 16 | CGFloat const FSCalendarStandardWeeklyPageHeight = 108+1/3.0; 17 | CGFloat const FSCalendarStandardCellDiameter = 100/3.0; 18 | CGFloat const FSCalendarStandardSeparatorThickness = 0.5; 19 | CGFloat const FSCalendarAutomaticDimension = -1; 20 | CGFloat const FSCalendarDefaultBounceAnimationDuration = 0.15; 21 | CGFloat const FSCalendarStandardRowHeight = 38; 22 | CGFloat const FSCalendarStandardTitleTextSize = 13.5; 23 | CGFloat const FSCalendarStandardSubtitleTextSize = 10; 24 | CGFloat const FSCalendarStandardWeekdayTextSize = 14; 25 | CGFloat const FSCalendarStandardHeaderTextSize = 16.5; 26 | CGFloat const FSCalendarMaximumEventDotDiameter = 4.8; 27 | CGFloat const FSCalendarStandardScopeHandleHeight = 26; 28 | 29 | NSInteger const FSCalendarDefaultHourComponent = 0; 30 | 31 | NSString * const FSCalendarDefaultCellReuseIdentifier = @"_FSCalendarDefaultCellReuseIdentifier"; 32 | NSString * const FSCalendarBlankCellReuseIdentifier = @"_FSCalendarBlankCellReuseIdentifier"; 33 | NSString * const FSCalendarInvalidArgumentsExceptionName = @"Invalid argument exception"; 34 | 35 | CGPoint const CGPointInfinity = { 36 | .x = CGFLOAT_MAX, 37 | .y = CGFLOAT_MAX 38 | }; 39 | 40 | CGSize const CGSizeAutomatic = { 41 | .width = FSCalendarAutomaticDimension, 42 | .height = FSCalendarAutomaticDimension 43 | }; 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarDelegationFactory.m: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarDelegationFactory.m 3 | // FSCalendar 4 | // 5 | // Created by dingwenchao on 19/12/2016. 6 | // Copyright © 2016 wenchaoios. All rights reserved. 7 | // 8 | 9 | #import "FSCalendarDelegationFactory.h" 10 | 11 | #define FSCalendarSelectorEntry(SEL1,SEL2) NSStringFromSelector(@selector(SEL1)):NSStringFromSelector(@selector(SEL2)) 12 | 13 | @implementation FSCalendarDelegationFactory 14 | 15 | + (FSCalendarDelegationProxy *)dataSourceProxy 16 | { 17 | FSCalendarDelegationProxy *delegation = [[FSCalendarDelegationProxy alloc] init]; 18 | delegation.protocol = @protocol(FSCalendarDataSource); 19 | delegation.deprecations = @{FSCalendarSelectorEntry(calendar:numberOfEventsForDate:, calendar:hasEventForDate:)}; 20 | return delegation; 21 | } 22 | 23 | + (FSCalendarDelegationProxy *)delegateProxy 24 | { 25 | FSCalendarDelegationProxy *delegation = [[FSCalendarDelegationProxy alloc] init]; 26 | delegation.protocol = @protocol(FSCalendarDelegateAppearance); 27 | delegation.deprecations = @{ 28 | FSCalendarSelectorEntry(calendarCurrentPageDidChange:, calendarCurrentMonthDidChange:), 29 | FSCalendarSelectorEntry(calendar:shouldSelectDate:atMonthPosition:, calendar:shouldSelectDate:), 30 | FSCalendarSelectorEntry(calendar:didSelectDate:atMonthPosition:, calendar:didSelectDate:), 31 | FSCalendarSelectorEntry(calendar:shouldDeselectDate:atMonthPosition:, calendar:shouldDeselectDate:), 32 | FSCalendarSelectorEntry(calendar:didDeselectDate:atMonthPosition:, calendar:didDeselectDate:) 33 | }; 34 | return delegation; 35 | } 36 | 37 | @end 38 | 39 | #undef FSCalendarSelectorEntry 40 | 41 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarCalculator.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarCalculator.h 3 | // FSCalendar 4 | // 5 | // Created by dingwenchao on 30/10/2016. 6 | // Copyright © 2016 Wenchao Ding. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | struct FSCalendarCoordinate { 13 | NSInteger row; 14 | NSInteger column; 15 | }; 16 | typedef struct FSCalendarCoordinate FSCalendarCoordinate; 17 | 18 | @interface FSCalendarCalculator : NSObject 19 | 20 | @property (weak , nonatomic) FSCalendar *calendar; 21 | 22 | @property (readonly, nonatomic) NSInteger numberOfSections; 23 | 24 | - (instancetype)initWithCalendar:(FSCalendar *)calendar; 25 | 26 | - (NSDate *)safeDateForDate:(NSDate *)date; 27 | 28 | - (NSDate *)dateForIndexPath:(NSIndexPath *)indexPath; 29 | - (NSDate *)dateForIndexPath:(NSIndexPath *)indexPath scope:(FSCalendarScope)scope; 30 | - (NSIndexPath *)indexPathForDate:(NSDate *)date; 31 | - (NSIndexPath *)indexPathForDate:(NSDate *)date scope:(FSCalendarScope)scope; 32 | - (NSIndexPath *)indexPathForDate:(NSDate *)date atMonthPosition:(FSCalendarMonthPosition)position; 33 | - (NSIndexPath *)indexPathForDate:(NSDate *)date atMonthPosition:(FSCalendarMonthPosition)position scope:(FSCalendarScope)scope; 34 | 35 | - (NSDate *)pageForSection:(NSInteger)section; 36 | - (NSDate *)weekForSection:(NSInteger)section; 37 | - (NSDate *)monthForSection:(NSInteger)section; 38 | - (NSDate *)monthHeadForSection:(NSInteger)section; 39 | 40 | - (NSInteger)numberOfHeadPlaceholdersForMonth:(NSDate *)month; 41 | - (NSInteger)numberOfRowsInMonth:(NSDate *)month; 42 | - (NSInteger)numberOfRowsInSection:(NSInteger)section; 43 | 44 | - (FSCalendarMonthPosition)monthPositionForIndexPath:(NSIndexPath *)indexPath; 45 | - (FSCalendarCoordinate)coordinateForIndexPath:(NSIndexPath *)indexPath; 46 | 47 | - (void)reloadSections; 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /Demo/Demo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | } 88 | ], 89 | "info" : { 90 | "version" : 1, 91 | "author" : "xcode" 92 | } 93 | } -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarTransitionCoordinator.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarTransitionCoordinator.h 3 | // FSCalendar 4 | // 5 | // Created by dingwenchao on 3/13/16. 6 | // Copyright © 2016 Wenchao Ding. All rights reserved. 7 | // 8 | 9 | #import "FSCalendar.h" 10 | #import "FSCalendarCollectionView.h" 11 | #import "FSCalendarCollectionViewLayout.h" 12 | #import "FSCalendarScopeHandle.h" 13 | 14 | typedef NS_ENUM(NSUInteger, FSCalendarTransition) { 15 | FSCalendarTransitionNone, 16 | FSCalendarTransitionMonthToWeek, 17 | FSCalendarTransitionWeekToMonth 18 | }; 19 | typedef NS_ENUM(NSUInteger, FSCalendarTransitionState) { 20 | FSCalendarTransitionStateIdle, 21 | FSCalendarTransitionStateChanging, 22 | FSCalendarTransitionStateFinishing, 23 | }; 24 | 25 | @interface FSCalendarTransitionCoordinator : NSObject 26 | 27 | @property (weak, nonatomic) FSCalendar *calendar; 28 | @property (weak, nonatomic) FSCalendarCollectionView *collectionView; 29 | @property (weak, nonatomic) FSCalendarCollectionViewLayout *collectionViewLayout; 30 | 31 | @property (assign, nonatomic) FSCalendarTransition transition; 32 | @property (assign, nonatomic) FSCalendarTransitionState state; 33 | 34 | @property (assign, nonatomic) CGSize cachedMonthSize; 35 | 36 | @property (readonly, nonatomic) FSCalendarScope representingScope; 37 | 38 | - (instancetype)initWithCalendar:(FSCalendar *)calendar; 39 | 40 | - (void)performScopeTransitionFromScope:(FSCalendarScope)fromScope toScope:(FSCalendarScope)toScope animated:(BOOL)animated; 41 | - (void)performBoundingRectTransitionFromMonth:(NSDate *)fromMonth toMonth:(NSDate *)toMonth duration:(CGFloat)duration; 42 | 43 | - (void)handleScopeGesture:(id)sender; 44 | 45 | @end 46 | 47 | 48 | @interface FSCalendarTransitionAttributes : NSObject 49 | 50 | @property (assign, nonatomic) CGRect sourceBounds; 51 | @property (assign, nonatomic) CGRect targetBounds; 52 | @property (strong, nonatomic) NSDate *sourcePage; 53 | @property (strong, nonatomic) NSDate *targetPage; 54 | @property (assign, nonatomic) NSInteger focusedRowNumber; 55 | @property (assign, nonatomic) NSDate *focusedDate; 56 | @property (strong, nonatomic) NSDate *firstDayOfMonth; 57 | 58 | @end 59 | 60 | -------------------------------------------------------------------------------- /Demo/Demo/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // PGCalendar 4 | // 5 | // Created by piggybear on 2017/10/12. 6 | // Copyright © 2017年 piggybear. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import PGActionSheetCalendar 11 | 12 | class ViewController: UIViewController { 13 | 14 | override func viewDidLoad() { 15 | super.viewDidLoad() 16 | } 17 | 18 | 19 | @IBAction func button1Handler(_ sender: Any) { 20 | let calendar = PGActionSheetCalendar() 21 | present(calendar, animated: false, completion: nil) 22 | } 23 | 24 | @IBAction func button2Handler(_ sender: Any) { 25 | let calendar = PGActionSheetCalendar() 26 | let label = calendar.titleLabel 27 | label.text = "PGCalendar" 28 | calendar.delegate = self 29 | present(calendar, animated: false, completion: nil) 30 | } 31 | 32 | @IBAction func button3Handler(_ sender: Any) { 33 | let calendar = PGActionSheetCalendar() 34 | calendar.delegate = self 35 | present(calendar, animated: false, completion: nil) 36 | calendar.cancelButton.setTitleColor(UIColor.red, for: .normal) 37 | calendar.sureButton.setTitleColor(UIColor.orange, for: .normal) 38 | } 39 | 40 | @IBAction func button4Handler(_ sender: Any) { 41 | let calendar = PGActionSheetCalendar() 42 | calendar.didSelectDateComponents = {components in 43 | print("year = ", components.year!,"month = ", components.month!, "day = ", components.day!) 44 | } 45 | present(calendar, animated: false, completion: nil) 46 | calendar.calendar.appearance.weekdayTextColor = UIColor.red 47 | calendar.calendar.appearance.headerTitleColor = UIColor.red 48 | calendar.calendar.appearance.selectionColor = UIColor.blue 49 | calendar.calendar.appearance.todayColor = UIColor.orange 50 | calendar.calendar.appearance.todaySelectionColor = UIColor.black 51 | } 52 | } 53 | 54 | extension ViewController: PGActionSheetCalendarDelegate { 55 | func calendar(_ calendar: PGActionSheetCalendar, didSelectDate components: DateComponents) { 56 | print("year = ", components.year!,"month = ", components.month!, "day = ", components.day!) 57 | } 58 | } 59 | 60 | -------------------------------------------------------------------------------- /Demo/Demo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Demo 4 | // 5 | // Created by piggybear on 2017/10/13. 6 | // Copyright © 2017年 piggybear. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // 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. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // 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. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // 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. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Demo/Pods/Pods.xcodeproj/xcuserdata/piggybear.xcuserdatad/xcschemes/Pods-Demo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 45 | 46 | 52 | 53 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Demo/Pods/Pods.xcodeproj/xcuserdata/piggybear.xcuserdatad/xcschemes/FSCalendar.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 45 | 46 | 52 | 53 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarDelegationProxy.m: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarDelegationProxy.m 3 | // FSCalendar 4 | // 5 | // Created by dingwenchao on 11/12/2016. 6 | // Copyright © 2016 Wenchao Ding. All rights reserved. 7 | // 8 | 9 | #import "FSCalendarDelegationProxy.h" 10 | #import 11 | 12 | @implementation FSCalendarDelegationProxy 13 | 14 | - (instancetype)init 15 | { 16 | return self; 17 | } 18 | 19 | - (BOOL)respondsToSelector:(SEL)selector 20 | { 21 | BOOL responds = [self.delegation respondsToSelector:selector]; 22 | if (!responds) responds = [self.delegation respondsToSelector:[self deprecatedSelectorOfSelector:selector]]; 23 | if (!responds) responds = [super respondsToSelector:selector]; 24 | return responds; 25 | } 26 | 27 | - (BOOL)conformsToProtocol:(Protocol *)protocol 28 | { 29 | return [self.delegation conformsToProtocol:protocol]; 30 | } 31 | 32 | - (void)forwardInvocation:(NSInvocation *)invocation 33 | { 34 | SEL selector = invocation.selector; 35 | if (![self.delegation respondsToSelector:selector]) { 36 | selector = [self deprecatedSelectorOfSelector:selector]; 37 | invocation.selector = selector; 38 | } 39 | if ([self.delegation respondsToSelector:selector]) { 40 | [invocation invokeWithTarget:self.delegation]; 41 | } 42 | } 43 | 44 | - (NSMethodSignature *)methodSignatureForSelector:(SEL)sel 45 | { 46 | if ([self.delegation respondsToSelector:sel]) { 47 | return [(NSObject *)self.delegation methodSignatureForSelector:sel]; 48 | } 49 | SEL selector = [self deprecatedSelectorOfSelector:sel]; 50 | if ([self.delegation respondsToSelector:selector]) { 51 | return [(NSObject *)self.delegation methodSignatureForSelector:selector]; 52 | } 53 | #if TARGET_INTERFACE_BUILDER 54 | return [NSObject methodSignatureForSelector:@selector(init)]; 55 | #endif 56 | struct objc_method_description desc = protocol_getMethodDescription(self.protocol, sel, NO, YES); 57 | const char *types = desc.types; 58 | return types?[NSMethodSignature signatureWithObjCTypes:types]:[NSObject methodSignatureForSelector:@selector(init)]; 59 | } 60 | 61 | - (SEL)deprecatedSelectorOfSelector:(SEL)selector 62 | { 63 | NSString *selectorString = NSStringFromSelector(selector); 64 | selectorString = self.deprecations[selectorString]; 65 | return NSSelectorFromString(selectorString); 66 | } 67 | 68 | @end 69 | -------------------------------------------------------------------------------- /Demo/Pods/Pods.xcodeproj/xcuserdata/piggybear.xcuserdatad/xcschemes/PGActionSheetCalendar.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 43 | 44 | 45 | 46 | 52 | 53 | 55 | 56 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarScopeHandle.m: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarScopeHandle.m 3 | // FSCalendar 4 | // 5 | // Created by dingwenchao on 4/29/16. 6 | // Copyright © 2016 Wenchao Ding. All rights reserved. 7 | // 8 | 9 | #import "FSCalendarScopeHandle.h" 10 | #import "FSCalendar.h" 11 | #import "FSCalendarTransitionCoordinator.h" 12 | #import "FSCalendarDynamicHeader.h" 13 | #import "FSCalendarExtensions.h" 14 | 15 | @interface FSCalendarScopeHandle () 16 | 17 | @property (weak, nonatomic) UIView *topBorder; 18 | @property (weak, nonatomic) UIView *handleIndicator; 19 | 20 | @property (weak, nonatomic) FSCalendarAppearance *appearance; 21 | 22 | @property (assign, nonatomic) CGFloat lastTranslation; 23 | 24 | @end 25 | 26 | @implementation FSCalendarScopeHandle 27 | 28 | - (instancetype)initWithFrame:(CGRect)frame 29 | { 30 | self = [super initWithFrame:frame]; 31 | if (self) { 32 | 33 | UIView *view; 34 | 35 | view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 1)]; 36 | view.backgroundColor = FSCalendarStandardLineColor; 37 | [self addSubview:view]; 38 | self.topBorder = view; 39 | 40 | view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 6)]; 41 | view.layer.shouldRasterize = YES; 42 | view.layer.masksToBounds = YES; 43 | view.layer.cornerRadius = 3; 44 | view.layer.backgroundColor = FSCalendarStandardScopeHandleColor.CGColor; 45 | [self addSubview:view]; 46 | self.handleIndicator = view; 47 | 48 | UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; 49 | panGesture.minimumNumberOfTouches = 1; 50 | panGesture.maximumNumberOfTouches = 2; 51 | [self addGestureRecognizer:panGesture]; 52 | self.panGesture = panGesture; 53 | 54 | self.exclusiveTouch = YES; 55 | 56 | } 57 | return self; 58 | } 59 | 60 | - (void)layoutSubviews 61 | { 62 | [super layoutSubviews]; 63 | self.topBorder.frame = CGRectMake(0, 0, self.fs_width, 1); 64 | self.handleIndicator.center = CGPointMake(self.fs_width/2, self.fs_height/2-0.5); 65 | } 66 | 67 | - (void)handlePan:(id)sender 68 | { 69 | [self.calendar.transitionCoordinator handleScopeGesture:sender]; 70 | } 71 | 72 | - (void)setCalendar:(FSCalendar *)calendar 73 | { 74 | _calendar = calendar; 75 | self.panGesture.delegate = self.calendar.transitionCoordinator; 76 | } 77 | 78 | @end 79 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarExtensions.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarExtensions.h 3 | // FSCalendar 4 | // 5 | // Created by dingwenchao on 10/8/16. 6 | // Copyright © 2016 Wenchao Ding. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface UIView (FSCalendarExtensions) 15 | 16 | @property (nonatomic) CGFloat fs_width; 17 | @property (nonatomic) CGFloat fs_height; 18 | 19 | @property (nonatomic) CGFloat fs_top; 20 | @property (nonatomic) CGFloat fs_left; 21 | @property (nonatomic) CGFloat fs_bottom; 22 | @property (nonatomic) CGFloat fs_right; 23 | 24 | @end 25 | 26 | 27 | @interface CALayer (FSCalendarExtensions) 28 | 29 | @property (nonatomic) CGFloat fs_width; 30 | @property (nonatomic) CGFloat fs_height; 31 | 32 | @property (nonatomic) CGFloat fs_top; 33 | @property (nonatomic) CGFloat fs_left; 34 | @property (nonatomic) CGFloat fs_bottom; 35 | @property (nonatomic) CGFloat fs_right; 36 | 37 | @end 38 | 39 | 40 | @interface NSCalendar (FSCalendarExtensions) 41 | 42 | - (nullable NSDate *)fs_firstDayOfMonth:(NSDate *)month; 43 | - (nullable NSDate *)fs_lastDayOfMonth:(NSDate *)month; 44 | - (nullable NSDate *)fs_firstDayOfWeek:(NSDate *)week; 45 | - (nullable NSDate *)fs_lastDayOfWeek:(NSDate *)week; 46 | - (nullable NSDate *)fs_middleDayOfWeek:(NSDate *)week; 47 | - (NSInteger)fs_numberOfDaysInMonth:(NSDate *)month; 48 | 49 | @end 50 | 51 | @interface NSMapTable (FSCalendarExtensions) 52 | 53 | - (void)setObject:(nullable id)obj forKeyedSubscript:(id)key; 54 | - (id)objectForKeyedSubscript:(id)key; 55 | 56 | @end 57 | 58 | @interface NSCache (FSCalendarExtensions) 59 | 60 | - (void)setObject:(nullable id)obj forKeyedSubscript:(id)key; 61 | - (id)objectForKeyedSubscript:(id)key; 62 | 63 | @end 64 | 65 | 66 | @interface NSObject (FSCalendarExtensions) 67 | 68 | #define IVAR_DEF(SET,GET,TYPE) \ 69 | - (void)fs_set##SET##Variable:(TYPE)value forKey:(NSString *)key; \ 70 | - (TYPE)fs_##GET##VariableForKey:(NSString *)key; 71 | IVAR_DEF(Bool, bool, BOOL) 72 | IVAR_DEF(Float, float, CGFloat) 73 | IVAR_DEF(Integer, integer, NSInteger) 74 | IVAR_DEF(UnsignedInteger, unsignedInteger, NSUInteger) 75 | #undef IVAR_DEF 76 | 77 | - (void)fs_setVariable:(id)variable forKey:(NSString *)key; 78 | - (id)fs_variableForKey:(NSString *)key; 79 | 80 | - (nullable id)fs_performSelector:(SEL)selector withObjects:(nullable id)firstObject, ... NS_REQUIRES_NIL_TERMINATION; 81 | 82 | @end 83 | 84 | NS_ASSUME_NONNULL_END 85 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarCollectionView.m: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarCollectionView.m 3 | // FSCalendar 4 | // 5 | // Created by Wenchao Ding on 10/25/15. 6 | // Copyright (c) 2015 Wenchao Ding. All rights reserved. 7 | // 8 | // Reject -[UIScrollView(UIScrollViewInternal) _adjustContentOffsetIfNecessary] 9 | 10 | 11 | #import "FSCalendarCollectionView.h" 12 | #import "FSCalendarExtensions.h" 13 | #import "FSCalendarConstants.h" 14 | 15 | @interface FSCalendarCollectionView () 16 | 17 | - (void)initialize; 18 | 19 | @end 20 | 21 | @implementation FSCalendarCollectionView 22 | 23 | @synthesize scrollsToTop = _scrollsToTop, contentInset = _contentInset; 24 | 25 | - (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout 26 | { 27 | self = [super initWithFrame:frame collectionViewLayout:layout]; 28 | if (self) { 29 | [self initialize]; 30 | } 31 | return self; 32 | } 33 | 34 | - (instancetype)initWithFrame:(CGRect)frame 35 | { 36 | self = [super initWithFrame:frame]; 37 | if (self) { 38 | [self initialize]; 39 | } 40 | return self; 41 | } 42 | 43 | - (void)initialize 44 | { 45 | self.scrollsToTop = NO; 46 | self.contentInset = UIEdgeInsetsZero; 47 | 48 | #ifdef __IPHONE_9_0 49 | if ([self respondsToSelector:@selector(setSemanticContentAttribute:)]) { 50 | self.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; 51 | } 52 | #endif 53 | 54 | #ifdef __IPHONE_10_0 55 | SEL selector = NSSelectorFromString(@"setPrefetchingEnabled:"); 56 | if (selector && [self respondsToSelector:selector]) { 57 | [self fs_performSelector:selector withObjects:@NO, nil]; 58 | } 59 | #endif 60 | } 61 | 62 | - (void)setContentInset:(UIEdgeInsets)contentInset 63 | { 64 | [super setContentInset:UIEdgeInsetsZero]; 65 | if (contentInset.top) { 66 | self.contentOffset = CGPointMake(self.contentOffset.x, self.contentOffset.y+contentInset.top); 67 | } 68 | } 69 | 70 | - (void)setScrollsToTop:(BOOL)scrollsToTop 71 | { 72 | [super setScrollsToTop:NO]; 73 | } 74 | 75 | @end 76 | 77 | 78 | @implementation FSCalendarSeparator 79 | 80 | - (instancetype)initWithFrame:(CGRect)frame 81 | { 82 | self = [super initWithFrame:frame]; 83 | if (self) { 84 | self.backgroundColor = FSCalendarStandardSeparatorColor; 85 | } 86 | return self; 87 | } 88 | 89 | - (void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes 90 | { 91 | self.frame = layoutAttributes.frame; 92 | } 93 | 94 | @end 95 | 96 | 97 | 98 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-Demo/Pods-Demo-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## FSCalendar 5 | 6 | Copyright (c) 2013-2016 FSCalendar (https://github.com/WenchaoD/FSCalendar) 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | 26 | 27 | ## PGActionSheetCalendar 28 | 29 | MIT License 30 | 31 | Copyright (c) 2017 piggybear 32 | 33 | Permission is hereby granted, free of charge, to any person obtaining a copy 34 | of this software and associated documentation files (the "Software"), to deal 35 | in the Software without restriction, including without limitation the rights 36 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 37 | copies of the Software, and to permit persons to whom the Software is 38 | furnished to do so, subject to the following conditions: 39 | 40 | The above copyright notice and this permission notice shall be included in all 41 | copies or substantial portions of the Software. 42 | 43 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 44 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 45 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 46 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 47 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 48 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 49 | SOFTWARE. 50 | 51 | Generated by CocoaPods - https://cocoapods.org 52 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarDynamicHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarDynamicHeader.h 3 | // Pods 4 | // 5 | // Created by DingWenchao on 6/29/15. 6 | // 7 | // 动感头文件,仅供框架内部使用。 8 | // Private header, don't use it. 9 | // 10 | 11 | #import 12 | #import 13 | 14 | #import "FSCalendar.h" 15 | #import "FSCalendarCell.h" 16 | #import "FSCalendarHeaderView.h" 17 | #import "FSCalendarStickyHeader.h" 18 | #import "FSCalendarCollectionView.h" 19 | #import "FSCalendarCollectionViewLayout.h" 20 | #import "FSCalendarScopeHandle.h" 21 | #import "FSCalendarCalculator.h" 22 | #import "FSCalendarTransitionCoordinator.h" 23 | #import "FSCalendarDelegationProxy.h" 24 | 25 | @interface FSCalendar (Dynamic) 26 | 27 | @property (readonly, nonatomic) FSCalendarCollectionView *collectionView; 28 | @property (readonly, nonatomic) FSCalendarScopeHandle *scopeHandle; 29 | @property (readonly, nonatomic) FSCalendarCollectionViewLayout *collectionViewLayout; 30 | @property (readonly, nonatomic) FSCalendarTransitionCoordinator *transitionCoordinator; 31 | @property (readonly, nonatomic) FSCalendarCalculator *calculator; 32 | @property (readonly, nonatomic) BOOL floatingMode; 33 | @property (readonly, nonatomic) NSArray *visibleStickyHeaders; 34 | @property (readonly, nonatomic) CGFloat preferredHeaderHeight; 35 | @property (readonly, nonatomic) CGFloat preferredWeekdayHeight; 36 | @property (readonly, nonatomic) UIView *bottomBorder; 37 | 38 | @property (readonly, nonatomic) NSCalendar *gregorian; 39 | @property (readonly, nonatomic) NSDateComponents *components; 40 | @property (readonly, nonatomic) NSDateFormatter *formatter; 41 | 42 | @property (readonly, nonatomic) UIView *contentView; 43 | @property (readonly, nonatomic) UIView *daysContainer; 44 | 45 | @property (assign, nonatomic) BOOL needsAdjustingViewFrame; 46 | 47 | - (void)invalidateHeaders; 48 | - (void)adjustMonthPosition; 49 | - (void)configureAppearance; 50 | 51 | - (BOOL)isPageInRange:(NSDate *)page; 52 | - (BOOL)isDateInRange:(NSDate *)date; 53 | 54 | - (CGSize)sizeThatFits:(CGSize)size scope:(FSCalendarScope)scope; 55 | 56 | @end 57 | 58 | @interface FSCalendarAppearance (Dynamic) 59 | 60 | @property (readwrite, nonatomic) FSCalendar *calendar; 61 | 62 | @property (readonly, nonatomic) NSDictionary *backgroundColors; 63 | @property (readonly, nonatomic) NSDictionary *titleColors; 64 | @property (readonly, nonatomic) NSDictionary *subtitleColors; 65 | @property (readonly, nonatomic) NSDictionary *borderColors; 66 | 67 | @end 68 | 69 | @interface FSCalendarWeekdayView (Dynamic) 70 | 71 | @property (readwrite, nonatomic) FSCalendar *calendar; 72 | 73 | @end 74 | 75 | @interface FSCalendarCollectionViewLayout (Dynamic) 76 | 77 | @property (readonly, nonatomic) CGSize estimatedItemSize; 78 | 79 | @end 80 | 81 | @interface FSCalendarDelegationProxy() 82 | @end 83 | 84 | 85 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarCell.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarCell.h 3 | // Pods 4 | // 5 | // Created by Wenchao Ding on 12/3/15. 6 | // 7 | // 8 | 9 | #import 10 | 11 | @class FSCalendar, FSCalendarAppearance, FSCalendarEventIndicator; 12 | 13 | typedef NS_ENUM(NSUInteger, FSCalendarMonthPosition); 14 | 15 | @interface FSCalendarCell : UICollectionViewCell 16 | 17 | #pragma mark - Public properties 18 | 19 | /** 20 | The day text label of the cell 21 | */ 22 | @property (weak, nonatomic) UILabel *titleLabel; 23 | 24 | 25 | /** 26 | The subtitle label of the cell 27 | */ 28 | @property (weak, nonatomic) UILabel *subtitleLabel; 29 | 30 | 31 | /** 32 | The shape layer of the cell 33 | */ 34 | @property (weak, nonatomic) CAShapeLayer *shapeLayer; 35 | 36 | /** 37 | The imageView below shape layer of the cell 38 | */ 39 | @property (weak, nonatomic) UIImageView *imageView; 40 | 41 | 42 | /** 43 | The collection of event dots of the cell 44 | */ 45 | @property (weak, nonatomic) FSCalendarEventIndicator *eventIndicator; 46 | 47 | /** 48 | A boolean value indicates that whether the cell is "placeholder". Default is NO. 49 | */ 50 | @property (assign, nonatomic, getter=isPlaceholder) BOOL placeholder; 51 | 52 | #pragma mark - Private properties 53 | 54 | @property (weak, nonatomic) FSCalendar *calendar; 55 | @property (weak, nonatomic) FSCalendarAppearance *appearance; 56 | 57 | @property (strong, nonatomic) NSString *subtitle; 58 | @property (strong, nonatomic) UIImage *image; 59 | @property (assign, nonatomic) FSCalendarMonthPosition monthPosition; 60 | 61 | @property (assign, nonatomic) NSInteger numberOfEvents; 62 | @property (assign, nonatomic) BOOL dateIsToday; 63 | @property (assign, nonatomic) BOOL weekend; 64 | 65 | @property (strong, nonatomic) UIColor *preferredFillDefaultColor; 66 | @property (strong, nonatomic) UIColor *preferredFillSelectionColor; 67 | @property (strong, nonatomic) UIColor *preferredTitleDefaultColor; 68 | @property (strong, nonatomic) UIColor *preferredTitleSelectionColor; 69 | @property (strong, nonatomic) UIColor *preferredSubtitleDefaultColor; 70 | @property (strong, nonatomic) UIColor *preferredSubtitleSelectionColor; 71 | @property (strong, nonatomic) UIColor *preferredBorderDefaultColor; 72 | @property (strong, nonatomic) UIColor *preferredBorderSelectionColor; 73 | @property (assign, nonatomic) CGPoint preferredTitleOffset; 74 | @property (assign, nonatomic) CGPoint preferredSubtitleOffset; 75 | @property (assign, nonatomic) CGPoint preferredImageOffset; 76 | @property (assign, nonatomic) CGPoint preferredEventOffset; 77 | 78 | @property (strong, nonatomic) NSArray *preferredEventDefaultColors; 79 | @property (strong, nonatomic) NSArray *preferredEventSelectionColors; 80 | @property (assign, nonatomic) CGFloat preferredBorderRadius; 81 | 82 | // Add subviews to self.contentView and set up constraints 83 | - (instancetype)initWithFrame:(CGRect)frame NS_REQUIRES_SUPER; 84 | - (instancetype)initWithCoder:(NSCoder *)aDecoder NS_REQUIRES_SUPER; 85 | 86 | // For DIY overridden 87 | - (void)layoutSubviews NS_REQUIRES_SUPER; // Configure frames of subviews 88 | - (void)configureAppearance NS_REQUIRES_SUPER; // Configure appearance for cell 89 | 90 | - (UIColor *)colorForCurrentStateInDictionary:(NSDictionary *)dictionary; 91 | - (void)performSelecting; 92 | 93 | @end 94 | 95 | @interface FSCalendarEventIndicator : UIView 96 | 97 | @property (assign, nonatomic) NSInteger numberOfEvents; 98 | @property (strong, nonatomic) id color; 99 | 100 | @end 101 | 102 | @interface FSCalendarBlankCell : UICollectionViewCell 103 | 104 | - (void)configureAppearance; 105 | 106 | @end 107 | 108 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarWeekdayView.m: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarWeekdayView.m 3 | // FSCalendar 4 | // 5 | // Created by dingwenchao on 03/11/2016. 6 | // Copyright © 2016 Wenchao Ding. All rights reserved. 7 | // 8 | 9 | #import "FSCalendarWeekdayView.h" 10 | #import "FSCalendar.h" 11 | #import "FSCalendarDynamicHeader.h" 12 | #import "FSCalendarExtensions.h" 13 | 14 | @interface FSCalendarWeekdayView() 15 | 16 | @property (strong, nonatomic) NSPointerArray *weekdayPointers; 17 | @property (weak , nonatomic) UIView *contentView; 18 | @property (weak , nonatomic) FSCalendar *calendar; 19 | 20 | - (void)commonInit; 21 | 22 | @end 23 | 24 | @implementation FSCalendarWeekdayView 25 | 26 | - (instancetype)initWithFrame:(CGRect)frame 27 | { 28 | self = [super initWithFrame:frame]; 29 | if (self) { 30 | [self commonInit]; 31 | } 32 | return self; 33 | } 34 | 35 | - (instancetype)initWithCoder:(NSCoder *)coder 36 | { 37 | self = [super initWithCoder:coder]; 38 | if (self) { 39 | [self commonInit]; 40 | } 41 | return self; 42 | } 43 | 44 | - (void)commonInit 45 | { 46 | UIView *contentView = [[UIView alloc] initWithFrame:CGRectZero]; 47 | [self addSubview:contentView]; 48 | _contentView = contentView; 49 | 50 | _weekdayPointers = [NSPointerArray weakObjectsPointerArray]; 51 | for (int i = 0; i < 7; i++) { 52 | UILabel *weekdayLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 53 | weekdayLabel.textAlignment = NSTextAlignmentCenter; 54 | [self.contentView addSubview:weekdayLabel]; 55 | [_weekdayPointers addPointer:(__bridge void * _Nullable)(weekdayLabel)]; 56 | } 57 | } 58 | 59 | - (void)layoutSubviews 60 | { 61 | [super layoutSubviews]; 62 | 63 | self.contentView.frame = self.bounds; 64 | 65 | // Position Calculation 66 | NSInteger count = self.weekdayPointers.count; 67 | size_t size = sizeof(CGFloat)*count; 68 | CGFloat *widths = malloc(size); 69 | CGFloat contentWidth = self.contentView.fs_width; 70 | FSCalendarSliceCake(contentWidth, count, widths); 71 | 72 | CGFloat x = 0; 73 | for (NSInteger i = 0; i < count; i++) { 74 | CGFloat width = widths[i]; 75 | UILabel *label = [self.weekdayPointers pointerAtIndex:i]; 76 | label.frame = CGRectMake(x, 0, width, self.contentView.fs_height); 77 | x += width; 78 | } 79 | free(widths); 80 | } 81 | 82 | - (void)setCalendar:(FSCalendar *)calendar 83 | { 84 | _calendar = calendar; 85 | [self configureAppearance]; 86 | } 87 | 88 | - (NSArray *)weekdayLabels 89 | { 90 | return self.weekdayPointers.allObjects; 91 | } 92 | 93 | - (void)configureAppearance 94 | { 95 | BOOL useVeryShortWeekdaySymbols = (self.calendar.appearance.caseOptions & (15<<4) ) == FSCalendarCaseOptionsWeekdayUsesSingleUpperCase; 96 | NSArray *weekdaySymbols = useVeryShortWeekdaySymbols ? self.calendar.gregorian.veryShortStandaloneWeekdaySymbols : self.calendar.gregorian.shortStandaloneWeekdaySymbols; 97 | BOOL useDefaultWeekdayCase = (self.calendar.appearance.caseOptions & (15<<4) ) == FSCalendarCaseOptionsWeekdayUsesDefaultCase; 98 | 99 | for (NSInteger i = 0; i < self.weekdayPointers.count; i++) { 100 | NSInteger index = (i + self.calendar.firstWeekday-1) % 7; 101 | UILabel *label = [self.weekdayPointers pointerAtIndex:i]; 102 | label.font = self.calendar.appearance.weekdayFont; 103 | label.textColor = self.calendar.appearance.weekdayTextColor; 104 | label.text = useDefaultWeekdayCase ? weekdaySymbols[index] : [weekdaySymbols[index] uppercaseString]; 105 | } 106 | 107 | } 108 | 109 | @end 110 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-Demo/Pods-Demo-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 | Copyright (c) 2013-2016 FSCalendar (https://github.com/WenchaoD/FSCalendar) 18 | 19 | Permission is hereby granted, free of charge, to any person obtaining a copy 20 | of this software and associated documentation files (the "Software"), to deal 21 | in the Software without restriction, including without limitation the rights 22 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 23 | copies of the Software, and to permit persons to whom the Software is 24 | furnished to do so, subject to the following conditions: 25 | 26 | The above copyright notice and this permission notice shall be included in 27 | all copies or substantial portions of the Software. 28 | 29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 30 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 31 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 32 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 33 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 34 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 35 | THE SOFTWARE. 36 | 37 | License 38 | MIT 39 | Title 40 | FSCalendar 41 | Type 42 | PSGroupSpecifier 43 | 44 | 45 | FooterText 46 | MIT License 47 | 48 | Copyright (c) 2017 piggybear 49 | 50 | Permission is hereby granted, free of charge, to any person obtaining a copy 51 | of this software and associated documentation files (the "Software"), to deal 52 | in the Software without restriction, including without limitation the rights 53 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 54 | copies of the Software, and to permit persons to whom the Software is 55 | furnished to do so, subject to the following conditions: 56 | 57 | The above copyright notice and this permission notice shall be included in all 58 | copies or substantial portions of the Software. 59 | 60 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 61 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 62 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 63 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 64 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 65 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 66 | SOFTWARE. 67 | 68 | License 69 | MIT 70 | Title 71 | PGActionSheetCalendar 72 | Type 73 | PSGroupSpecifier 74 | 75 | 76 | FooterText 77 | Generated by CocoaPods - https://cocoapods.org 78 | Title 79 | 80 | Type 81 | PSGroupSpecifier 82 | 83 | 84 | StringsTable 85 | Acknowledgements 86 | Title 87 | Acknowledgements 88 | 89 | 90 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarStickyHeader.m: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarStaticHeader.m 3 | // FSCalendar 4 | // 5 | // Created by dingwenchao on 9/17/15. 6 | // Copyright (c) 2015 Wenchao Ding. All rights reserved. 7 | // 8 | 9 | #import "FSCalendarStickyHeader.h" 10 | #import "FSCalendar.h" 11 | #import "FSCalendarWeekdayView.h" 12 | #import "FSCalendarExtensions.h" 13 | #import "FSCalendarConstants.h" 14 | #import "FSCalendarDynamicHeader.h" 15 | 16 | @interface FSCalendarStickyHeader () 17 | 18 | @property (weak , nonatomic) UIView *contentView; 19 | @property (weak , nonatomic) UIView *bottomBorder; 20 | @property (weak , nonatomic) FSCalendarWeekdayView *weekdayView; 21 | 22 | @end 23 | 24 | @implementation FSCalendarStickyHeader 25 | 26 | - (instancetype)initWithFrame:(CGRect)frame 27 | { 28 | self = [super initWithFrame:frame]; 29 | if (self) { 30 | 31 | UIView *view; 32 | UILabel *label; 33 | 34 | view = [[UIView alloc] initWithFrame:CGRectZero]; 35 | view.backgroundColor = [UIColor clearColor]; 36 | [self addSubview:view]; 37 | self.contentView = view; 38 | 39 | label = [[UILabel alloc] initWithFrame:CGRectZero]; 40 | label.textAlignment = NSTextAlignmentCenter; 41 | label.numberOfLines = 0; 42 | [_contentView addSubview:label]; 43 | self.titleLabel = label; 44 | 45 | view = [[UIView alloc] initWithFrame:CGRectZero]; 46 | view.backgroundColor = FSCalendarStandardLineColor; 47 | [_contentView addSubview:view]; 48 | self.bottomBorder = view; 49 | 50 | FSCalendarWeekdayView *weekdayView = [[FSCalendarWeekdayView alloc] init]; 51 | [self.contentView addSubview:weekdayView]; 52 | self.weekdayView = weekdayView; 53 | } 54 | return self; 55 | } 56 | 57 | - (void)layoutSubviews 58 | { 59 | [super layoutSubviews]; 60 | 61 | _contentView.frame = self.bounds; 62 | 63 | CGFloat weekdayHeight = _calendar.preferredWeekdayHeight; 64 | CGFloat weekdayMargin = weekdayHeight * 0.1; 65 | CGFloat titleWidth = _contentView.fs_width; 66 | 67 | self.weekdayView.frame = CGRectMake(0, _contentView.fs_height-weekdayHeight-weekdayMargin, self.contentView.fs_width, weekdayHeight); 68 | 69 | CGFloat titleHeight = [@"1" sizeWithAttributes:@{NSFontAttributeName:self.calendar.appearance.headerTitleFont}].height*1.5 + weekdayMargin*3; 70 | 71 | _bottomBorder.frame = CGRectMake(0, _contentView.fs_height-weekdayHeight-weekdayMargin*2, _contentView.fs_width, 1.0); 72 | _titleLabel.frame = CGRectMake(0, _bottomBorder.fs_bottom-titleHeight-weekdayMargin, titleWidth,titleHeight); 73 | 74 | } 75 | 76 | #pragma mark - Properties 77 | 78 | - (void)setCalendar:(FSCalendar *)calendar 79 | { 80 | if (![_calendar isEqual:calendar]) { 81 | _calendar = calendar; 82 | _weekdayView.calendar = calendar; 83 | [self configureAppearance]; 84 | } 85 | } 86 | 87 | #pragma mark - Private methods 88 | 89 | - (void)configureAppearance 90 | { 91 | _titleLabel.font = self.calendar.appearance.headerTitleFont; 92 | _titleLabel.textColor = self.calendar.appearance.headerTitleColor; 93 | [self.weekdayView configureAppearance]; 94 | } 95 | 96 | - (void)setMonth:(NSDate *)month 97 | { 98 | _month = month; 99 | _calendar.formatter.dateFormat = self.calendar.appearance.headerDateFormat; 100 | BOOL usesUpperCase = (self.calendar.appearance.caseOptions & 15) == FSCalendarCaseOptionsHeaderUsesUpperCase; 101 | NSString *text = [_calendar.formatter stringFromDate:_month]; 102 | text = usesUpperCase ? text.uppercaseString : text; 103 | self.titleLabel.text = text; 104 | } 105 | 106 | @end 107 | 108 | 109 | -------------------------------------------------------------------------------- /PGActionSheetCalendar/PGActionSheetCalendarView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PGActionSheetCalendarView.swift 3 | // PGActionSheetCalendar 4 | // 5 | // Created by piggybear on 2017/10/12. 6 | // Copyright © 2017年 piggybear. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import FSCalendar 11 | 12 | class PGActionSheetCalendarView: UIView { 13 | //MARK: - internal property 14 | var calendar: FSCalendar? 15 | var cancelButtonHandler: ButtonHandler? 16 | var sureButtonHandler: ButtonHandler? 17 | var headerView:PGActionSheetCalendarHeader! 18 | 19 | //MARK: - private property 20 | private let headerHeight:CGFloat = 40 21 | fileprivate var didSelectDate: Date? 22 | 23 | override init(frame: CGRect) { 24 | super.init(frame: frame) 25 | setup() 26 | } 27 | 28 | required init?(coder aDecoder: NSCoder) { 29 | fatalError("init(coder:) has not been implemented") 30 | } 31 | 32 | override func layoutSubviews() { 33 | super.layoutSubviews() 34 | if calendar?.selectedDate != nil { 35 | self.didSelectDate = calendar?.selectedDate 36 | calendar?.appearance.todayColor = UIColor.clear 37 | calendar?.appearance.titleTodayColor = UIColor.blue.withAlphaComponent(0.5) 38 | } 39 | } 40 | 41 | private func setup() { 42 | var frame = self.bounds 43 | frame.size.height = headerHeight 44 | headerView = PGActionSheetCalendarHeader(frame: frame) 45 | self.addSubview(headerView) 46 | 47 | headerView.backgroundColor = UIColor(red: 236 / 255.0, green: 231 / 255.0, blue: 242 / 255.0, alpha: 1.0) 48 | headerView.sureButtonHandler = {[unowned self] _ in 49 | if self.sureButtonHandler != nil { 50 | let calendar = Calendar.current 51 | let components: DateComponents = calendar.dateComponents([.year, .month, .day], from: self.didSelectDate!) 52 | self.sureButtonHandler!(components) 53 | } 54 | } 55 | headerView.cancelButtonHandler = {[unowned self] _ in 56 | if self.cancelButtonHandler != nil { 57 | self.cancelButtonHandler!(nil) 58 | } 59 | } 60 | 61 | var calendarFrame = self.bounds 62 | calendarFrame.origin.y = headerView.frame.maxY 63 | calendarFrame.size.height = self.bounds.size.height - headerView.frame.size.height 64 | calendar = FSCalendar(frame: calendarFrame) 65 | calendar?.backgroundColor = UIColor.white 66 | calendar?.appearance.headerDateFormat = "yyyy年MM月" 67 | calendar?.appearance.headerMinimumDissolvedAlpha = 0 68 | calendar?.appearance.todayColor = UIColor.blue.withAlphaComponent(0.5) 69 | calendar?.appearance.selectionColor = UIColor.blue.withAlphaComponent(0.5) 70 | calendar?.appearance.headerTitleFont = UIFont.boldSystemFont(ofSize: 16.5) 71 | calendar?.appearance.weekdayFont = UIFont.boldSystemFont(ofSize: 14) 72 | calendar?.appearance.weekdayTextColor = UIColor.blue.withAlphaComponent(0.5) 73 | calendar?.appearance.headerTitleColor = UIColor.blue.withAlphaComponent(0.5) 74 | calendar?.delegate = self 75 | calendar?.dataSource = self 76 | self.addSubview(calendar!) 77 | self.didSelectDate = calendar?.today 78 | } 79 | } 80 | 81 | extension PGActionSheetCalendarView: FSCalendarDataSource { 82 | func calendar(_ calendar: FSCalendar, titleFor date: Date) -> String? { 83 | let currentCalendar = Calendar.current 84 | if currentCalendar.isDateInToday(date) { 85 | return "今" 86 | } 87 | return nil 88 | } 89 | } 90 | 91 | extension PGActionSheetCalendarView: FSCalendarDelegate { 92 | public func calendar(_ calendar: FSCalendar, didSelect date: Date) { 93 | calendar.appearance.todayColor = UIColor.clear 94 | calendar.appearance.titleTodayColor = UIColor.blue.withAlphaComponent(0.5) 95 | self.didSelectDate = date 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /Demo/Pods/PGActionSheetCalendar/PGActionSheetCalendar/PGActionSheetCalendarView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PGActionSheetCalendarView.swift 3 | // PGActionSheetCalendar 4 | // 5 | // Created by piggybear on 2017/10/12. 6 | // Copyright © 2017年 piggybear. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import FSCalendar 11 | 12 | class PGActionSheetCalendarView: UIView { 13 | //MARK: - internal property 14 | var calendar: FSCalendar? 15 | var cancelButtonHandler: ButtonHandler? 16 | var sureButtonHandler: ButtonHandler? 17 | var headerView:PGActionSheetCalendarHeader! 18 | 19 | //MARK: - private property 20 | private let headerHeight:CGFloat = 40 21 | fileprivate var didSelectDate: Date? 22 | 23 | override init(frame: CGRect) { 24 | super.init(frame: frame) 25 | setup() 26 | } 27 | 28 | required init?(coder aDecoder: NSCoder) { 29 | fatalError("init(coder:) has not been implemented") 30 | } 31 | 32 | override func layoutSubviews() { 33 | super.layoutSubviews() 34 | if calendar?.selectedDate != nil { 35 | self.didSelectDate = calendar?.selectedDate 36 | calendar?.appearance.todayColor = UIColor.clear 37 | calendar?.appearance.titleTodayColor = UIColor.blue.withAlphaComponent(0.5) 38 | } 39 | } 40 | 41 | private func setup() { 42 | var frame = self.bounds 43 | frame.size.height = headerHeight 44 | headerView = PGActionSheetCalendarHeader(frame: frame) 45 | self.addSubview(headerView) 46 | 47 | headerView.backgroundColor = UIColor(red: 236 / 255.0, green: 231 / 255.0, blue: 242 / 255.0, alpha: 1.0) 48 | headerView.sureButtonHandler = {[unowned self] _ in 49 | if self.sureButtonHandler != nil { 50 | let calendar = Calendar.current 51 | let components: DateComponents = calendar.dateComponents([.year, .month, .day], from: self.didSelectDate!) 52 | self.sureButtonHandler!(components) 53 | } 54 | } 55 | headerView.cancelButtonHandler = {[unowned self] _ in 56 | if self.cancelButtonHandler != nil { 57 | self.cancelButtonHandler!(nil) 58 | } 59 | } 60 | 61 | var calendarFrame = self.bounds 62 | calendarFrame.origin.y = headerView.frame.maxY 63 | calendarFrame.size.height = self.bounds.size.height - headerView.frame.size.height 64 | calendar = FSCalendar(frame: calendarFrame) 65 | calendar?.backgroundColor = UIColor.white 66 | calendar?.appearance.headerDateFormat = "yyyy年MM月" 67 | calendar?.appearance.headerMinimumDissolvedAlpha = 0 68 | calendar?.appearance.todayColor = UIColor.blue.withAlphaComponent(0.5) 69 | calendar?.appearance.selectionColor = UIColor.blue.withAlphaComponent(0.5) 70 | calendar?.appearance.headerTitleFont = UIFont.boldSystemFont(ofSize: 16.5) 71 | calendar?.appearance.weekdayFont = UIFont.boldSystemFont(ofSize: 14) 72 | calendar?.appearance.weekdayTextColor = UIColor.blue.withAlphaComponent(0.5) 73 | calendar?.appearance.headerTitleColor = UIColor.blue.withAlphaComponent(0.5) 74 | calendar?.delegate = self 75 | calendar?.dataSource = self 76 | self.addSubview(calendar!) 77 | self.didSelectDate = calendar?.today 78 | } 79 | } 80 | 81 | extension PGActionSheetCalendarView: FSCalendarDataSource { 82 | func calendar(_ calendar: FSCalendar, titleFor date: Date) -> String? { 83 | let currentCalendar = Calendar.current 84 | if currentCalendar.isDateInToday(date) { 85 | return "今" 86 | } 87 | return nil 88 | } 89 | } 90 | 91 | extension PGActionSheetCalendarView: FSCalendarDelegate { 92 | public func calendar(_ calendar: FSCalendar, didSelect date: Date) { 93 | calendar.appearance.todayColor = UIColor.clear 94 | calendar.appearance.titleTodayColor = UIColor.blue.withAlphaComponent(0.5) 95 | self.didSelectDate = date 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarConstants.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarConstane.h 3 | // FSCalendar 4 | // 5 | // Created by dingwenchao on 8/28/15. 6 | // Copyright © 2016 Wenchao Ding. All rights reserved. 7 | // 8 | // https://github.com/WenchaoD 9 | // 10 | 11 | #import 12 | #import 13 | 14 | #pragma mark - Constants 15 | 16 | CG_EXTERN CGFloat const FSCalendarStandardHeaderHeight; 17 | CG_EXTERN CGFloat const FSCalendarStandardWeekdayHeight; 18 | CG_EXTERN CGFloat const FSCalendarStandardMonthlyPageHeight; 19 | CG_EXTERN CGFloat const FSCalendarStandardWeeklyPageHeight; 20 | CG_EXTERN CGFloat const FSCalendarStandardCellDiameter; 21 | CG_EXTERN CGFloat const FSCalendarStandardSeparatorThickness; 22 | CG_EXTERN CGFloat const FSCalendarAutomaticDimension; 23 | CG_EXTERN CGFloat const FSCalendarDefaultBounceAnimationDuration; 24 | CG_EXTERN CGFloat const FSCalendarStandardRowHeight; 25 | CG_EXTERN CGFloat const FSCalendarStandardTitleTextSize; 26 | CG_EXTERN CGFloat const FSCalendarStandardSubtitleTextSize; 27 | CG_EXTERN CGFloat const FSCalendarStandardWeekdayTextSize; 28 | CG_EXTERN CGFloat const FSCalendarStandardHeaderTextSize; 29 | CG_EXTERN CGFloat const FSCalendarMaximumEventDotDiameter; 30 | CG_EXTERN CGFloat const FSCalendarStandardScopeHandleHeight; 31 | 32 | UIKIT_EXTERN NSInteger const FSCalendarDefaultHourComponent; 33 | 34 | UIKIT_EXTERN NSString * const FSCalendarDefaultCellReuseIdentifier; 35 | UIKIT_EXTERN NSString * const FSCalendarBlankCellReuseIdentifier; 36 | UIKIT_EXTERN NSString * const FSCalendarInvalidArgumentsExceptionName; 37 | 38 | CG_EXTERN CGPoint const CGPointInfinity; 39 | CG_EXTERN CGSize const CGSizeAutomatic; 40 | 41 | #if TARGET_INTERFACE_BUILDER 42 | #define FSCalendarDeviceIsIPad NO 43 | #else 44 | #define FSCalendarDeviceIsIPad [[UIDevice currentDevice].model hasPrefix:@"iPad"] 45 | #endif 46 | 47 | #define FSCalendarStandardSelectionColor FSColorRGBA(31,119,219,1.0) 48 | #define FSCalendarStandardTodayColor FSColorRGBA(198,51,42 ,1.0) 49 | #define FSCalendarStandardTitleTextColor FSColorRGBA(14,69,221 ,1.0) 50 | #define FSCalendarStandardEventDotColor FSColorRGBA(31,119,219,0.75) 51 | 52 | #define FSCalendarStandardLineColor [[UIColor lightGrayColor] colorWithAlphaComponent:0.30] 53 | #define FSCalendarStandardSeparatorColor [[UIColor lightGrayColor] colorWithAlphaComponent:0.60] 54 | #define FSCalendarStandardScopeHandleColor [[UIColor lightGrayColor] colorWithAlphaComponent:0.50] 55 | 56 | #define FSColorRGBA(r,g,b,a) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:a] 57 | #define FSCalendarInAppExtension [[[NSBundle mainBundle] bundlePath] hasSuffix:@".appex"] 58 | 59 | #if CGFLOAT_IS_DOUBLE 60 | #define FSCalendarFloor(c) floor(c) 61 | #define FSCalendarRound(c) round(c) 62 | #define FSCalendarCeil(c) ceil(c) 63 | #define FSCalendarMod(c1,c2) fmod(c1,c2) 64 | #else 65 | #define FSCalendarFloor(c) floorf(c) 66 | #define FSCalendarRound(c) roundf(c) 67 | #define FSCalendarCeil(c) ceilf(c) 68 | #define FSCalendarMod(c1,c2) fmodf(c1,c2) 69 | #endif 70 | 71 | #define FSCalendarUseWeakSelf __weak __typeof__(self) FSCalendarWeakSelf = self; 72 | #define FSCalendarUseStrongSelf __strong __typeof__(self) self = FSCalendarWeakSelf; 73 | 74 | 75 | #pragma mark - Deprecated 76 | 77 | #define FSCalendarDeprecated(instead) DEPRECATED_MSG_ATTRIBUTE(" Use " # instead " instead") 78 | 79 | FSCalendarDeprecated('borderRadius') 80 | typedef NS_ENUM(NSUInteger, FSCalendarCellShape) { 81 | FSCalendarCellShapeCircle = 0, 82 | FSCalendarCellShapeRectangle = 1 83 | }; 84 | 85 | typedef NS_ENUM(NSUInteger, FSCalendarUnit) { 86 | FSCalendarUnitMonth = NSCalendarUnitMonth, 87 | FSCalendarUnitWeekOfYear = NSCalendarUnitWeekOfYear, 88 | FSCalendarUnitDay = NSCalendarUnitDay 89 | }; 90 | 91 | static inline void FSCalendarSliceCake(CGFloat cake, NSInteger count, CGFloat *pieces) { 92 | CGFloat total = cake; 93 | for (int i = 0; i < count; i++) { 94 | NSInteger remains = count - i; 95 | CGFloat piece = FSCalendarRound(total/remains*2)*0.5; 96 | total -= piece; 97 | pieces[i] = piece; 98 | } 99 | } 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /PGActionSheetCalendar/PGActionSheetCalendar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PGActionSheetCalendar.swift 3 | // PGActionSheetCalendar 4 | // 5 | // Created by piggybear on 2017/10/12. 6 | // Copyright © 2017年 piggybear. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import FSCalendar 11 | 12 | internal struct ScreenSize { 13 | static let width: CGFloat = UIScreen.main.bounds.size.width 14 | static let height: CGFloat = UIScreen.main.bounds.size.height 15 | } 16 | 17 | public class PGActionSheetCalendar: UIViewController { 18 | //MARK: - public property 19 | public var calendar: FSCalendar { 20 | return self.calendarView.calendar! 21 | } 22 | public var cancelButton: UIButton { 23 | return self.calendarView.headerView.cancelButton 24 | } 25 | public var sureButton: UIButton { 26 | return self.calendarView.headerView.sureButton 27 | } 28 | public var titleLabel: UILabel { 29 | return self.calendarView.headerView.titleLabel 30 | } 31 | public weak var delegate: PGActionSheetCalendarDelegate? 32 | public var didSelectDateComponents: ((_ components: DateComponents)->())? 33 | 34 | //MARK: - private property 35 | fileprivate var calendarView: PGActionSheetCalendarView! 36 | fileprivate let calendarHeight: CGFloat = 300 37 | fileprivate var overlayView: UIView? 38 | fileprivate var contentView: UIView! 39 | 40 | //MARK: - system cycle 41 | public convenience init() { 42 | self.init(nibName: nil, bundle: nil) 43 | 44 | self.modalPresentationStyle = .custom 45 | overlayView = UIView(frame: self.view.bounds) 46 | overlayView?.backgroundColor = UIColor.black.withAlphaComponent(0.6) 47 | overlayView?.alpha = 0 48 | self.view.addSubview(overlayView!) 49 | let tap = UITapGestureRecognizer(target: self, action: #selector(overlayViewTapHandler)) 50 | overlayView?.addGestureRecognizer(tap) 51 | 52 | 53 | let frame = CGRect(x: 0, y: ScreenSize.height, width: ScreenSize.width, height: calendarHeight) 54 | contentView = UIView(frame: frame) 55 | contentView.backgroundColor = UIColor.white 56 | self.view.addSubview(contentView) 57 | calendarView = PGActionSheetCalendarView(frame: frame) 58 | contentView.addSubview(calendarView) 59 | calendarView.cancelButtonHandler = {[unowned self] _ in 60 | self.overlayViewTapHandler() 61 | } 62 | calendarView.sureButtonHandler = {[unowned self] components in 63 | if self.delegate != nil { 64 | self.delegate?.calendar!(self, didSelectDate: components!) 65 | } 66 | if self.didSelectDateComponents != nil { 67 | self.didSelectDateComponents!(components!) 68 | } 69 | self.overlayViewTapHandler() 70 | } 71 | } 72 | 73 | public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { 74 | super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) 75 | } 76 | 77 | public required init?(coder aDecoder: NSCoder) { 78 | fatalError("init(coder:) has not been implemented") 79 | } 80 | 81 | public override func viewWillLayoutSubviews() { 82 | super.viewWillLayoutSubviews() 83 | var bottom: CGFloat = 0 84 | if #available(iOS 11.0, *) { 85 | bottom = self.view.safeAreaInsets.bottom 86 | } 87 | let frame = CGRect(x: 0, 88 | y: 0, 89 | width: ScreenSize.width, 90 | height: calendarHeight) 91 | self.calendarView.frame = frame 92 | let contentViewFrame = CGRect(x: 0, 93 | y: ScreenSize.height - calendarHeight - bottom, 94 | width: ScreenSize.width, 95 | height: calendarHeight + bottom) 96 | UIView.animate(withDuration: 0.3, animations: { 97 | self.contentView.frame = contentViewFrame 98 | self.overlayView?.alpha = 1.0 99 | }) 100 | } 101 | 102 | // private method 103 | @objc func overlayViewTapHandler() { 104 | var bottom: CGFloat = 0 105 | if #available(iOS 11.0, *) { 106 | bottom = self.view.safeAreaInsets.bottom 107 | } 108 | let frame = CGRect(x: 0, y: ScreenSize.height, width: ScreenSize.width, height: calendarHeight + bottom) 109 | UIView.animate(withDuration: 0.3, animations: { 110 | self.contentView.frame = frame 111 | self.overlayView?.alpha = 0 112 | }) { _ in 113 | self.dismiss(animated: false, completion: nil) 114 | } 115 | } 116 | } 117 | 118 | -------------------------------------------------------------------------------- /Demo/Pods/PGActionSheetCalendar/PGActionSheetCalendar/PGActionSheetCalendar.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PGActionSheetCalendar.swift 3 | // PGActionSheetCalendar 4 | // 5 | // Created by piggybear on 2017/10/12. 6 | // Copyright © 2017年 piggybear. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import FSCalendar 11 | 12 | internal struct ScreenSize { 13 | static let width: CGFloat = UIScreen.main.bounds.size.width 14 | static let height: CGFloat = UIScreen.main.bounds.size.height 15 | } 16 | 17 | public class PGActionSheetCalendar: UIViewController { 18 | //MARK: - public property 19 | public var calendar: FSCalendar { 20 | return self.calendarView.calendar! 21 | } 22 | public var cancelButton: UIButton { 23 | return self.calendarView.headerView.cancelButton 24 | } 25 | public var sureButton: UIButton { 26 | return self.calendarView.headerView.sureButton 27 | } 28 | public var titleLabel: UILabel { 29 | return self.calendarView.headerView.titleLabel 30 | } 31 | public weak var delegate: PGActionSheetCalendarDelegate? 32 | public var didSelectDateComponents: ((_ components: DateComponents)->())? 33 | 34 | //MARK: - private property 35 | fileprivate var calendarView: PGActionSheetCalendarView! 36 | fileprivate let calendarHeight: CGFloat = 300 37 | fileprivate var overlayView: UIView? 38 | fileprivate var contentView: UIView! 39 | 40 | //MARK: - system cycle 41 | public convenience init() { 42 | self.init(nibName: nil, bundle: nil) 43 | 44 | self.modalPresentationStyle = .custom 45 | overlayView = UIView(frame: self.view.bounds) 46 | overlayView?.backgroundColor = UIColor.black.withAlphaComponent(0.6) 47 | overlayView?.alpha = 0 48 | self.view.addSubview(overlayView!) 49 | let tap = UITapGestureRecognizer(target: self, action: #selector(overlayViewTapHandler)) 50 | overlayView?.addGestureRecognizer(tap) 51 | 52 | 53 | let frame = CGRect(x: 0, y: ScreenSize.height, width: ScreenSize.width, height: calendarHeight) 54 | contentView = UIView(frame: frame) 55 | contentView.backgroundColor = UIColor.white 56 | self.view.addSubview(contentView) 57 | calendarView = PGActionSheetCalendarView(frame: frame) 58 | contentView.addSubview(calendarView) 59 | calendarView.cancelButtonHandler = {[unowned self] _ in 60 | self.overlayViewTapHandler() 61 | } 62 | calendarView.sureButtonHandler = {[unowned self] components in 63 | if self.delegate != nil { 64 | self.delegate?.calendar!(self, didSelectDate: components!) 65 | } 66 | if self.didSelectDateComponents != nil { 67 | self.didSelectDateComponents!(components!) 68 | } 69 | self.overlayViewTapHandler() 70 | } 71 | } 72 | 73 | public override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) { 74 | super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) 75 | } 76 | 77 | public required init?(coder aDecoder: NSCoder) { 78 | fatalError("init(coder:) has not been implemented") 79 | } 80 | 81 | public override func viewWillLayoutSubviews() { 82 | super.viewWillLayoutSubviews() 83 | var bottom: CGFloat = 0 84 | if #available(iOS 11.0, *) { 85 | bottom = self.view.safeAreaInsets.bottom 86 | } 87 | let frame = CGRect(x: 0, 88 | y: 0, 89 | width: ScreenSize.width, 90 | height: calendarHeight) 91 | self.calendarView.frame = frame 92 | let contentViewFrame = CGRect(x: 0, 93 | y: ScreenSize.height - calendarHeight - bottom, 94 | width: ScreenSize.width, 95 | height: calendarHeight + bottom) 96 | UIView.animate(withDuration: 0.3, animations: { 97 | self.contentView.frame = contentViewFrame 98 | self.overlayView?.alpha = 1.0 99 | }) 100 | } 101 | 102 | // private method 103 | @objc func overlayViewTapHandler() { 104 | var bottom: CGFloat = 0 105 | if #available(iOS 11.0, *) { 106 | bottom = self.view.safeAreaInsets.bottom 107 | } 108 | let frame = CGRect(x: 0, y: ScreenSize.height, width: ScreenSize.width, height: calendarHeight + bottom) 109 | UIView.animate(withDuration: 0.3, animations: { 110 | self.contentView.frame = frame 111 | self.overlayView?.alpha = 0 112 | }) { _ in 113 | self.dismiss(animated: false, completion: nil) 114 | } 115 | } 116 | } 117 | 118 | -------------------------------------------------------------------------------- /PGActionSheetCalendar/PGActionSheetCalendarHeader.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PGActionSheetCalendarHeader.swift 3 | // PGActionSheetCalendar 4 | // 5 | // Created by piggybear on 2017/10/12. 6 | // Copyright © 2017年 piggybear. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | typealias ButtonHandler = (_ components: DateComponents?)->() 11 | 12 | class PGActionSheetCalendarHeader: UIView { 13 | 14 | var cancelButtonHandler: ButtonHandler? 15 | var sureButtonHandler: ButtonHandler? 16 | var cancelButton: UIButton! 17 | var sureButton: UIButton! 18 | var titleLabel: UILabel! 19 | 20 | override init(frame: CGRect) { 21 | super.init(frame: frame) 22 | setupSureButton() 23 | setupCancelButton() 24 | setupTitleLabel() 25 | } 26 | 27 | required init?(coder aDecoder: NSCoder) { 28 | fatalError("init(coder:) has not been implemented") 29 | } 30 | 31 | private func setupCancelButton() { 32 | cancelButton = UIButton() 33 | cancelButton.setTitle("取消", for: .normal) 34 | cancelButton.setTitleColor(UIColor.gray, for: .normal) 35 | cancelButton.setTitleColor(UIColor.darkGray, for: .highlighted) 36 | cancelButton.titleLabel?.font = UIFont.systemFont(ofSize: 15) 37 | self.addSubview(cancelButton) 38 | cancelButton.translatesAutoresizingMaskIntoConstraints = false 39 | let leftConstraint = NSLayoutConstraint(item: cancelButton, attribute: .leading, relatedBy: .equal, toItem: self, attribute: .leading, multiplier: 1.0, constant: 5) 40 | let centerY = NSLayoutConstraint(item: cancelButton, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1.0, constant: 0) 41 | self.addConstraints([leftConstraint, centerY]) 42 | 43 | let widthConstraint = NSLayoutConstraint(item: cancelButton, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 50) 44 | let heightConstraint = NSLayoutConstraint(item: cancelButton, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 40) 45 | cancelButton.addConstraints([widthConstraint, heightConstraint]) 46 | cancelButton.addTarget(self, action: #selector(cancelButtonAction), for: .touchUpInside) 47 | } 48 | 49 | private func setupSureButton() { 50 | sureButton = UIButton() 51 | sureButton.setTitle("确定", for: .normal) 52 | sureButton.setTitleColor(UIColor.blue.withAlphaComponent(0.6), for: .normal) 53 | sureButton.setTitleColor(UIColor.blue.withAlphaComponent(0.8), for: .highlighted) 54 | sureButton.titleLabel?.font = UIFont.systemFont(ofSize: 15) 55 | self.addSubview(sureButton) 56 | sureButton.translatesAutoresizingMaskIntoConstraints = false 57 | let sureButtonRightConstraint = NSLayoutConstraint(item: sureButton, attribute: .trailing, relatedBy: .equal, toItem: self, attribute: .trailing, multiplier: 1.0, constant: -5) 58 | let sureButtonCenterY = NSLayoutConstraint(item: sureButton, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1.0, constant: 0) 59 | self.addConstraints([sureButtonRightConstraint, sureButtonCenterY]) 60 | let sureButtonWidthConstraint = NSLayoutConstraint(item: sureButton, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 50) 61 | let sureButtonHeightConstraint = NSLayoutConstraint(item: sureButton, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 40) 62 | sureButton.addConstraints([sureButtonWidthConstraint, sureButtonHeightConstraint]) 63 | sureButton.addTarget(self, action: #selector(sureButtonAction), for: .touchUpInside) 64 | } 65 | 66 | private func setupTitleLabel() { 67 | titleLabel = UILabel() 68 | titleLabel.font = UIFont.boldSystemFont(ofSize: 17) 69 | titleLabel.textColor = UIColor(red: 113 / 255, green: 113 / 255, blue: 113 / 255, alpha: 1.0) 70 | self.addSubview(titleLabel) 71 | titleLabel.translatesAutoresizingMaskIntoConstraints = false 72 | let centerY = NSLayoutConstraint(item: titleLabel, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1.0, constant: 0) 73 | let centerX = NSLayoutConstraint(item: titleLabel, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1.0, constant: 0) 74 | self.addConstraints([centerX, centerY]) 75 | } 76 | 77 | @objc private func sureButtonAction() { 78 | if sureButtonHandler != nil { 79 | self.sureButtonHandler!(nil) 80 | } 81 | } 82 | 83 | @objc private func cancelButtonAction() { 84 | if cancelButtonHandler != nil { 85 | self.cancelButtonHandler!(nil) 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Demo/Pods/PGActionSheetCalendar/PGActionSheetCalendar/PGActionSheetCalendarHeader.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PGActionSheetCalendarHeader.swift 3 | // PGActionSheetCalendar 4 | // 5 | // Created by piggybear on 2017/10/12. 6 | // Copyright © 2017年 piggybear. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | typealias ButtonHandler = (_ components: DateComponents?)->() 11 | 12 | class PGActionSheetCalendarHeader: UIView { 13 | 14 | var cancelButtonHandler: ButtonHandler? 15 | var sureButtonHandler: ButtonHandler? 16 | var cancelButton: UIButton! 17 | var sureButton: UIButton! 18 | var titleLabel: UILabel! 19 | 20 | override init(frame: CGRect) { 21 | super.init(frame: frame) 22 | setupSureButton() 23 | setupCancelButton() 24 | setupTitleLabel() 25 | } 26 | 27 | required init?(coder aDecoder: NSCoder) { 28 | fatalError("init(coder:) has not been implemented") 29 | } 30 | 31 | private func setupCancelButton() { 32 | cancelButton = UIButton() 33 | cancelButton.setTitle("取消", for: .normal) 34 | cancelButton.setTitleColor(UIColor.gray, for: .normal) 35 | cancelButton.setTitleColor(UIColor.darkGray, for: .highlighted) 36 | cancelButton.titleLabel?.font = UIFont.systemFont(ofSize: 15) 37 | self.addSubview(cancelButton) 38 | cancelButton.translatesAutoresizingMaskIntoConstraints = false 39 | let leftConstraint = NSLayoutConstraint(item: cancelButton, attribute: .leading, relatedBy: .equal, toItem: self, attribute: .leading, multiplier: 1.0, constant: 5) 40 | let centerY = NSLayoutConstraint(item: cancelButton, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1.0, constant: 0) 41 | self.addConstraints([leftConstraint, centerY]) 42 | 43 | let widthConstraint = NSLayoutConstraint(item: cancelButton, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 50) 44 | let heightConstraint = NSLayoutConstraint(item: cancelButton, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 40) 45 | cancelButton.addConstraints([widthConstraint, heightConstraint]) 46 | cancelButton.addTarget(self, action: #selector(cancelButtonAction), for: .touchUpInside) 47 | } 48 | 49 | private func setupSureButton() { 50 | sureButton = UIButton() 51 | sureButton.setTitle("确定", for: .normal) 52 | sureButton.setTitleColor(UIColor.blue.withAlphaComponent(0.6), for: .normal) 53 | sureButton.setTitleColor(UIColor.blue.withAlphaComponent(0.8), for: .highlighted) 54 | sureButton.titleLabel?.font = UIFont.systemFont(ofSize: 15) 55 | self.addSubview(sureButton) 56 | sureButton.translatesAutoresizingMaskIntoConstraints = false 57 | let sureButtonRightConstraint = NSLayoutConstraint(item: sureButton, attribute: .trailing, relatedBy: .equal, toItem: self, attribute: .trailing, multiplier: 1.0, constant: -5) 58 | let sureButtonCenterY = NSLayoutConstraint(item: sureButton, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1.0, constant: 0) 59 | self.addConstraints([sureButtonRightConstraint, sureButtonCenterY]) 60 | let sureButtonWidthConstraint = NSLayoutConstraint(item: sureButton, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 50) 61 | let sureButtonHeightConstraint = NSLayoutConstraint(item: sureButton, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 40) 62 | sureButton.addConstraints([sureButtonWidthConstraint, sureButtonHeightConstraint]) 63 | sureButton.addTarget(self, action: #selector(sureButtonAction), for: .touchUpInside) 64 | } 65 | 66 | private func setupTitleLabel() { 67 | titleLabel = UILabel() 68 | titleLabel.font = UIFont.boldSystemFont(ofSize: 17) 69 | titleLabel.textColor = UIColor(red: 113 / 255, green: 113 / 255, blue: 113 / 255, alpha: 1.0) 70 | self.addSubview(titleLabel) 71 | titleLabel.translatesAutoresizingMaskIntoConstraints = false 72 | let centerY = NSLayoutConstraint(item: titleLabel, attribute: .centerY, relatedBy: .equal, toItem: self, attribute: .centerY, multiplier: 1.0, constant: 0) 73 | let centerX = NSLayoutConstraint(item: titleLabel, attribute: .centerX, relatedBy: .equal, toItem: self, attribute: .centerX, multiplier: 1.0, constant: 0) 74 | self.addConstraints([centerX, centerY]) 75 | } 76 | 77 | @objc private func sureButtonAction() { 78 | if sureButtonHandler != nil { 79 | self.sureButtonHandler!(nil) 80 | } 81 | } 82 | 83 | @objc private func cancelButtonAction() { 84 | if cancelButtonHandler != nil { 85 | self.cancelButtonHandler!(nil) 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-Demo/Pods-Demo-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 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 10 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 11 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 12 | 13 | install_framework() 14 | { 15 | if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then 16 | local source="${BUILT_PRODUCTS_DIR}/$1" 17 | elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then 18 | local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" 19 | elif [ -r "$1" ]; then 20 | local source="$1" 21 | fi 22 | 23 | local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 24 | 25 | if [ -L "${source}" ]; then 26 | echo "Symlinked..." 27 | source="$(readlink "${source}")" 28 | fi 29 | 30 | # Use filter instead of exclude so missing patterns don't throw errors. 31 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" 32 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" 33 | 34 | local basename 35 | basename="$(basename -s .framework "$1")" 36 | binary="${destination}/${basename}.framework/${basename}" 37 | if ! [ -r "$binary" ]; then 38 | binary="${destination}/${basename}" 39 | fi 40 | 41 | # Strip invalid architectures so "fat" simulator / device frameworks work on device 42 | if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then 43 | strip_invalid_archs "$binary" 44 | fi 45 | 46 | # Resign the code if required by the build settings to avoid unstable apps 47 | code_sign_if_enabled "${destination}/$(basename "$1")" 48 | 49 | # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. 50 | if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then 51 | local swift_runtime_libs 52 | swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) 53 | for lib in $swift_runtime_libs; do 54 | echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" 55 | rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" 56 | code_sign_if_enabled "${destination}/${lib}" 57 | done 58 | fi 59 | } 60 | 61 | # Copies the dSYM of a vendored framework 62 | install_dsym() { 63 | local source="$1" 64 | if [ -r "$source" ]; then 65 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DWARF_DSYM_FOLDER_PATH}\"" 66 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DWARF_DSYM_FOLDER_PATH}" 67 | fi 68 | } 69 | 70 | # Signs a framework with the provided identity 71 | code_sign_if_enabled() { 72 | if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then 73 | # Use the current code_sign_identitiy 74 | echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" 75 | local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS} --preserve-metadata=identifier,entitlements '$1'" 76 | 77 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 78 | code_sign_cmd="$code_sign_cmd &" 79 | fi 80 | echo "$code_sign_cmd" 81 | eval "$code_sign_cmd" 82 | fi 83 | } 84 | 85 | # Strip invalid architectures 86 | strip_invalid_archs() { 87 | binary="$1" 88 | # Get architectures for current file 89 | archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | rev)" 90 | stripped="" 91 | for arch in $archs; do 92 | if ! [[ "${ARCHS}" == *"$arch"* ]]; then 93 | # Strip non-valid architectures in-place 94 | lipo -remove "$arch" -output "$binary" "$binary" || exit 1 95 | stripped="$stripped $arch" 96 | fi 97 | done 98 | if [[ "$stripped" ]]; then 99 | echo "Stripped $binary of architectures:$stripped" 100 | fi 101 | } 102 | 103 | 104 | if [[ "$CONFIGURATION" == "Debug" ]]; then 105 | install_framework "${BUILT_PRODUCTS_DIR}/FSCalendar/FSCalendar.framework" 106 | install_framework "${BUILT_PRODUCTS_DIR}/PGActionSheetCalendar/PGActionSheetCalendar.framework" 107 | fi 108 | if [[ "$CONFIGURATION" == "Release" ]]; then 109 | install_framework "${BUILT_PRODUCTS_DIR}/FSCalendar/FSCalendar.framework" 110 | install_framework "${BUILT_PRODUCTS_DIR}/PGActionSheetCalendar/PGActionSheetCalendar.framework" 111 | fi 112 | if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then 113 | wait 114 | fi 115 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-Demo/Pods-Demo-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 | # This protects against multiple targets copying the same framework dependency at the same time. The solution 12 | # was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html 13 | RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") 14 | 15 | case "${TARGETED_DEVICE_FAMILY}" in 16 | 1,2) 17 | TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" 18 | ;; 19 | 1) 20 | TARGET_DEVICE_ARGS="--target-device iphone" 21 | ;; 22 | 2) 23 | TARGET_DEVICE_ARGS="--target-device ipad" 24 | ;; 25 | 3) 26 | TARGET_DEVICE_ARGS="--target-device tv" 27 | ;; 28 | 4) 29 | TARGET_DEVICE_ARGS="--target-device watch" 30 | ;; 31 | *) 32 | TARGET_DEVICE_ARGS="--target-device mac" 33 | ;; 34 | esac 35 | 36 | install_resource() 37 | { 38 | if [[ "$1" = /* ]] ; then 39 | RESOURCE_PATH="$1" 40 | else 41 | RESOURCE_PATH="${PODS_ROOT}/$1" 42 | fi 43 | if [[ ! -e "$RESOURCE_PATH" ]] ; then 44 | cat << EOM 45 | error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. 46 | EOM 47 | exit 1 48 | fi 49 | case $RESOURCE_PATH in 50 | *.storyboard) 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\" .storyboard`.storyboardc $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}" || true 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\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS} 53 | ;; 54 | *.xib) 55 | 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}" || true 56 | 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} 57 | ;; 58 | *.framework) 59 | echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 60 | mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 61 | echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true 62 | rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" 63 | ;; 64 | *.xcdatamodel) 65 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true 66 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" 67 | ;; 68 | *.xcdatamodeld) 69 | echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true 70 | xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" 71 | ;; 72 | *.xcmappingmodel) 73 | echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true 74 | xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" 75 | ;; 76 | *.xcassets) 77 | ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" 78 | XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") 79 | ;; 80 | *) 81 | echo "$RESOURCE_PATH" || true 82 | echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" 83 | ;; 84 | esac 85 | } 86 | 87 | mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 88 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 89 | if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then 90 | mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 91 | rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" 92 | fi 93 | rm -f "$RESOURCES_TO_COPY" 94 | 95 | if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "$XCASSET_FILES" ] 96 | then 97 | # Find all other xcassets (this unfortunately includes those of path pods and other targets). 98 | OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) 99 | while read line; do 100 | if [[ $line != "${PODS_ROOT}*" ]]; then 101 | XCASSET_FILES+=("$line") 102 | fi 103 | done <<<"$OTHER_XCASSETS" 104 | 105 | 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}" 106 | fi 107 | -------------------------------------------------------------------------------- /Demo/Demo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 36 | 48 | 60 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarAppearance.h: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarAppearance.h 3 | // Pods 4 | // 5 | // Created by DingWenchao on 6/29/15. 6 | // Copyright © 2016 Wenchao Ding. All rights reserved. 7 | // 8 | // https://github.com/WenchaoD 9 | // 10 | 11 | #import "FSCalendarConstants.h" 12 | 13 | @class FSCalendar; 14 | 15 | typedef NS_ENUM(NSInteger, FSCalendarCellState) { 16 | FSCalendarCellStateNormal = 0, 17 | FSCalendarCellStateSelected = 1, 18 | FSCalendarCellStatePlaceholder = 1 << 1, 19 | FSCalendarCellStateDisabled = 1 << 2, 20 | FSCalendarCellStateToday = 1 << 3, 21 | FSCalendarCellStateWeekend = 1 << 4, 22 | FSCalendarCellStateTodaySelected = FSCalendarCellStateToday|FSCalendarCellStateSelected 23 | }; 24 | 25 | typedef NS_ENUM(NSUInteger, FSCalendarSeparators) { 26 | FSCalendarSeparatorNone = 0, 27 | FSCalendarSeparatorInterRows = 1 28 | }; 29 | 30 | typedef NS_OPTIONS(NSUInteger, FSCalendarCaseOptions) { 31 | FSCalendarCaseOptionsHeaderUsesDefaultCase = 0, 32 | FSCalendarCaseOptionsHeaderUsesUpperCase = 1, 33 | 34 | FSCalendarCaseOptionsWeekdayUsesDefaultCase = 0 << 4, 35 | FSCalendarCaseOptionsWeekdayUsesUpperCase = 1 << 4, 36 | FSCalendarCaseOptionsWeekdayUsesSingleUpperCase = 2 << 4, 37 | }; 38 | 39 | /** 40 | * FSCalendarAppearance determines the fonts and colors of components in the calendar. 41 | * 42 | * @see FSCalendarDelegateAppearance 43 | */ 44 | @interface FSCalendarAppearance : NSObject 45 | 46 | /** 47 | * The font of the day text. 48 | */ 49 | @property (strong, nonatomic) UIFont *titleFont; 50 | 51 | /** 52 | * The font of the subtitle text. 53 | */ 54 | @property (strong, nonatomic) UIFont *subtitleFont; 55 | 56 | /** 57 | * The font of the weekday text. 58 | */ 59 | @property (strong, nonatomic) UIFont *weekdayFont; 60 | 61 | /** 62 | * The font of the month text. 63 | */ 64 | @property (strong, nonatomic) UIFont *headerTitleFont; 65 | 66 | /** 67 | * The offset of the day text from default position. 68 | */ 69 | @property (assign, nonatomic) CGPoint titleOffset; 70 | 71 | /** 72 | * The offset of the day text from default position. 73 | */ 74 | @property (assign, nonatomic) CGPoint subtitleOffset; 75 | 76 | /** 77 | * The offset of the event dots from default position. 78 | */ 79 | @property (assign, nonatomic) CGPoint eventOffset; 80 | 81 | /** 82 | * The offset of the image from default position. 83 | */ 84 | @property (assign, nonatomic) CGPoint imageOffset; 85 | 86 | /** 87 | * The color of event dots. 88 | */ 89 | @property (strong, nonatomic) UIColor *eventDefaultColor; 90 | 91 | /** 92 | * The color of event dots. 93 | */ 94 | @property (strong, nonatomic) UIColor *eventSelectionColor; 95 | 96 | /** 97 | * The color of weekday text. 98 | */ 99 | @property (strong, nonatomic) UIColor *weekdayTextColor; 100 | 101 | /** 102 | * The color of month header text. 103 | */ 104 | @property (strong, nonatomic) UIColor *headerTitleColor; 105 | 106 | /** 107 | * The date format of the month header. 108 | */ 109 | @property (strong, nonatomic) NSString *headerDateFormat; 110 | 111 | /** 112 | * The alpha value of month label staying on the fringes. 113 | */ 114 | @property (assign, nonatomic) CGFloat headerMinimumDissolvedAlpha; 115 | 116 | /** 117 | * The day text color for unselected state. 118 | */ 119 | @property (strong, nonatomic) UIColor *titleDefaultColor; 120 | 121 | /** 122 | * The day text color for selected state. 123 | */ 124 | @property (strong, nonatomic) UIColor *titleSelectionColor; 125 | 126 | /** 127 | * The day text color for today in the calendar. 128 | */ 129 | @property (strong, nonatomic) UIColor *titleTodayColor; 130 | 131 | /** 132 | * The day text color for days out of current month. 133 | */ 134 | @property (strong, nonatomic) UIColor *titlePlaceholderColor; 135 | 136 | /** 137 | * The day text color for weekend. 138 | */ 139 | @property (strong, nonatomic) UIColor *titleWeekendColor; 140 | 141 | /** 142 | * The subtitle text color for unselected state. 143 | */ 144 | @property (strong, nonatomic) UIColor *subtitleDefaultColor; 145 | 146 | /** 147 | * The subtitle text color for selected state. 148 | */ 149 | @property (strong, nonatomic) UIColor *subtitleSelectionColor; 150 | 151 | /** 152 | * The subtitle text color for today in the calendar. 153 | */ 154 | @property (strong, nonatomic) UIColor *subtitleTodayColor; 155 | 156 | /** 157 | * The subtitle text color for days out of current month. 158 | */ 159 | @property (strong, nonatomic) UIColor *subtitlePlaceholderColor; 160 | 161 | /** 162 | * The subtitle text color for weekend. 163 | */ 164 | @property (strong, nonatomic) UIColor *subtitleWeekendColor; 165 | 166 | /** 167 | * The fill color of the shape for selected state. 168 | */ 169 | @property (strong, nonatomic) UIColor *selectionColor; 170 | 171 | /** 172 | * The fill color of the shape for today. 173 | */ 174 | @property (strong, nonatomic) UIColor *todayColor; 175 | 176 | /** 177 | * The fill color of the shape for today and selected state. 178 | */ 179 | @property (strong, nonatomic) UIColor *todaySelectionColor; 180 | 181 | /** 182 | * The border color of the shape for unselected state. 183 | */ 184 | @property (strong, nonatomic) UIColor *borderDefaultColor; 185 | 186 | /** 187 | * The border color of the shape for selected state. 188 | */ 189 | @property (strong, nonatomic) UIColor *borderSelectionColor; 190 | 191 | /** 192 | * The border radius, while 1 means a circle, 0 means a rectangle, and the middle value will give it a corner radius. 193 | */ 194 | @property (assign, nonatomic) CGFloat borderRadius; 195 | 196 | /** 197 | * The case options manage the case of month label and weekday symbols. 198 | * 199 | * @see FSCalendarCaseOptions 200 | */ 201 | @property (assign, nonatomic) FSCalendarCaseOptions caseOptions; 202 | 203 | /** 204 | * The line integrations for calendar. 205 | * 206 | */ 207 | @property (assign, nonatomic) FSCalendarSeparators separators; 208 | 209 | #if TARGET_INTERFACE_BUILDER 210 | 211 | // For preview only 212 | @property (assign, nonatomic) BOOL fakeSubtitles; 213 | @property (assign, nonatomic) BOOL fakeEventDots; 214 | @property (assign, nonatomic) NSInteger fakedSelectedDay; 215 | 216 | #endif 217 | 218 | @end 219 | 220 | /** 221 | * These functions and attributes are deprecated. 222 | */ 223 | @interface FSCalendarAppearance (Deprecated) 224 | 225 | @property (assign, nonatomic) BOOL useVeryShortWeekdaySymbols FSCalendarDeprecated('caseOptions'); 226 | @property (assign, nonatomic) CGFloat titleVerticalOffset FSCalendarDeprecated('titleOffset'); 227 | @property (assign, nonatomic) CGFloat subtitleVerticalOffset FSCalendarDeprecated('subtitleOffset'); 228 | @property (strong, nonatomic) UIColor *eventColor FSCalendarDeprecated('eventDefaultColor'); 229 | @property (assign, nonatomic) FSCalendarCellShape cellShape FSCalendarDeprecated('borderRadius'); 230 | @property (assign, nonatomic) BOOL adjustsFontSizeToFitContentSize DEPRECATED_MSG_ATTRIBUTE("The attribute \'adjustsFontSizeToFitContentSize\' is not neccesary anymore."); 231 | - (void)invalidateAppearance FSCalendarDeprecated('FSCalendar setNeedsConfigureAppearance'); 232 | 233 | @end 234 | 235 | 236 | 237 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendar+Deprecated.m: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendar+Deprecated.m 3 | // FSCalendar 4 | // 5 | // Created by dingwenchao on 4/29/16. 6 | // Copyright © 2016 Wenchao Ding. All rights reserved. 7 | // 8 | 9 | #import "FSCalendar.h" 10 | #import "FSCalendarExtensions.h" 11 | #import "FSCalendarDynamicHeader.h" 12 | 13 | #pragma mark - Deprecate 14 | 15 | @implementation FSCalendar (Deprecated) 16 | 17 | @dynamic identifier, lineHeightMultiplier; 18 | 19 | - (void)setShowsPlaceholders:(BOOL)showsPlaceholders 20 | { 21 | self.placeholderType = showsPlaceholders ? FSCalendarPlaceholderTypeFillSixRows : FSCalendarPlaceholderTypeNone; 22 | } 23 | 24 | - (BOOL)showsPlaceholders 25 | { 26 | return self.placeholderType == FSCalendarPlaceholderTypeFillSixRows; 27 | } 28 | 29 | #pragma mark - Public methods 30 | 31 | - (NSInteger)yearOfDate:(NSDate *)date 32 | { 33 | if (!date) return NSNotFound; 34 | NSDateComponents *component = [self.gregorian components:NSCalendarUnitYear fromDate:date]; 35 | return component.year; 36 | } 37 | 38 | - (NSInteger)monthOfDate:(NSDate *)date 39 | { 40 | if (!date) return NSNotFound; 41 | NSDateComponents *component = [self.gregorian components:NSCalendarUnitMonth 42 | fromDate:date]; 43 | return component.month; 44 | } 45 | 46 | - (NSInteger)dayOfDate:(NSDate *)date 47 | { 48 | if (!date) return NSNotFound; 49 | NSDateComponents *component = [self.gregorian components:NSCalendarUnitDay 50 | fromDate:date]; 51 | return component.day; 52 | } 53 | 54 | - (NSInteger)weekdayOfDate:(NSDate *)date 55 | { 56 | if (!date) return NSNotFound; 57 | NSDateComponents *component = [self.gregorian components:NSCalendarUnitWeekday fromDate:date]; 58 | return component.weekday; 59 | } 60 | 61 | - (NSInteger)weekOfDate:(NSDate *)date 62 | { 63 | if (!date) return NSNotFound; 64 | NSDateComponents *component = [self.gregorian components:NSCalendarUnitWeekOfYear fromDate:date]; 65 | return component.weekOfYear; 66 | } 67 | 68 | - (NSDate *)dateByIgnoringTimeComponentsOfDate:(NSDate *)date 69 | { 70 | if (!date) return nil; 71 | NSDateComponents *components = [self.gregorian components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:date]; 72 | return [self.gregorian dateFromComponents:components]; 73 | } 74 | 75 | - (NSDate *)tomorrowOfDate:(NSDate *)date 76 | { 77 | if (!date) return nil; 78 | NSDateComponents *components = [self.gregorian components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour fromDate:date]; 79 | components.day++; 80 | components.hour = FSCalendarDefaultHourComponent; 81 | return [self.gregorian dateFromComponents:components]; 82 | } 83 | 84 | - (NSDate *)yesterdayOfDate:(NSDate *)date 85 | { 86 | if (!date) return nil; 87 | NSDateComponents *components = [self.gregorian components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour fromDate:date]; 88 | components.day--; 89 | components.hour = FSCalendarDefaultHourComponent; 90 | return [self.gregorian dateFromComponents:components]; 91 | } 92 | 93 | - (NSDate *)dateWithYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day 94 | { 95 | NSDateComponents *components = self.components; 96 | components.year = year; 97 | components.month = month; 98 | components.day = day; 99 | components.hour = FSCalendarDefaultHourComponent; 100 | NSDate *date = [self.gregorian dateFromComponents:components]; 101 | components.year = NSIntegerMax; 102 | components.month = NSIntegerMax; 103 | components.day = NSIntegerMax; 104 | components.hour = NSIntegerMax; 105 | return date; 106 | } 107 | 108 | - (NSDate *)dateByAddingYears:(NSInteger)years toDate:(NSDate *)date 109 | { 110 | if (!date) return nil; 111 | NSDateComponents *components = self.components; 112 | components.year = years; 113 | NSDate *d = [self.gregorian dateByAddingComponents:components toDate:date options:0]; 114 | components.year = NSIntegerMax; 115 | return d; 116 | } 117 | 118 | - (NSDate *)dateBySubstractingYears:(NSInteger)years fromDate:(NSDate *)date 119 | { 120 | if (!date) return nil; 121 | return [self dateByAddingYears:-years toDate:date]; 122 | } 123 | 124 | - (NSDate *)dateByAddingMonths:(NSInteger)months toDate:(NSDate *)date 125 | { 126 | if (!date) return nil; 127 | NSDateComponents *components = self.components; 128 | components.month = months; 129 | NSDate *d = [self.gregorian dateByAddingComponents:components toDate:date options:0]; 130 | components.month = NSIntegerMax; 131 | return d; 132 | } 133 | 134 | - (NSDate *)dateBySubstractingMonths:(NSInteger)months fromDate:(NSDate *)date 135 | { 136 | return [self dateByAddingMonths:-months toDate:date]; 137 | } 138 | 139 | - (NSDate *)dateByAddingWeeks:(NSInteger)weeks toDate:(NSDate *)date 140 | { 141 | if (!date) return nil; 142 | NSDateComponents *components = self.components; 143 | components.weekOfYear = weeks; 144 | NSDate *d = [self.gregorian dateByAddingComponents:components toDate:date options:0]; 145 | components.weekOfYear = NSIntegerMax; 146 | return d; 147 | } 148 | 149 | - (NSDate *)dateBySubstractingWeeks:(NSInteger)weeks fromDate:(NSDate *)date 150 | { 151 | return [self dateByAddingWeeks:-weeks toDate:date]; 152 | } 153 | 154 | - (NSDate *)dateByAddingDays:(NSInteger)days toDate:(NSDate *)date 155 | { 156 | if (!date) return nil; 157 | NSDateComponents *components = self.components; 158 | components.day = days; 159 | NSDate *d = [self.gregorian dateByAddingComponents:components toDate:date options:0]; 160 | components.day = NSIntegerMax; 161 | return d; 162 | } 163 | 164 | - (NSDate *)dateBySubstractingDays:(NSInteger)days fromDate:(NSDate *)date 165 | { 166 | return [self dateByAddingDays:-days toDate:date]; 167 | } 168 | 169 | - (NSInteger)yearsFromDate:(NSDate *)fromDate toDate:(NSDate *)toDate 170 | { 171 | NSDateComponents *components = [self.gregorian components:NSCalendarUnitYear 172 | fromDate:fromDate 173 | toDate:toDate 174 | options:0]; 175 | return components.year; 176 | } 177 | 178 | - (NSInteger)monthsFromDate:(NSDate *)fromDate toDate:(NSDate *)toDate 179 | { 180 | NSDateComponents *components = [self.gregorian components:NSCalendarUnitMonth 181 | fromDate:fromDate 182 | toDate:toDate 183 | options:0]; 184 | return components.month; 185 | } 186 | 187 | - (NSInteger)weeksFromDate:(NSDate *)fromDate toDate:(NSDate *)toDate 188 | { 189 | NSDateComponents *components = [self.gregorian components:NSCalendarUnitWeekOfYear 190 | fromDate:fromDate 191 | toDate:toDate 192 | options:0]; 193 | return components.weekOfYear; 194 | } 195 | 196 | - (NSInteger)daysFromDate:(NSDate *)fromDate toDate:(NSDate *)toDate 197 | { 198 | NSDateComponents *components = [self.gregorian components:NSCalendarUnitDay 199 | fromDate:fromDate 200 | toDate:toDate 201 | options:0]; 202 | return components.day; 203 | } 204 | 205 | - (BOOL)isDate:(NSDate *)date1 equalToDate:(NSDate *)date2 toCalendarUnit:(FSCalendarUnit)unit 206 | { 207 | switch (unit) { 208 | case FSCalendarUnitMonth: 209 | return [self.gregorian isDate:date1 equalToDate:date2 toUnitGranularity:NSCalendarUnitMonth]; 210 | case FSCalendarUnitWeekOfYear: 211 | return [self.gregorian isDate:date1 equalToDate:date2 toUnitGranularity:NSCalendarUnitYear]; 212 | case FSCalendarUnitDay: 213 | return [self.gregorian isDate:date1 inSameDayAsDate:date2]; 214 | } 215 | return NO; 216 | } 217 | 218 | - (BOOL)isDateInToday:(NSDate *)date 219 | { 220 | return [self isDate:date equalToDate:[NSDate date] toCalendarUnit:FSCalendarUnitDay]; 221 | } 222 | 223 | - (void)setIdentifier:(NSString *)identifier 224 | { 225 | NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:identifier]; 226 | [self setValue:gregorian forKey:@"gregorian"]; 227 | [self fs_performSelector:NSSelectorFromString(@"invalidateDateTools") withObjects:nil, nil]; 228 | 229 | if ([[self valueForKey:@"hasValidateVisibleLayout"] boolValue]) { 230 | [self reloadData]; 231 | } 232 | [self fs_setVariable:[self.gregorian dateBySettingHour:0 minute:0 second:0 ofDate:self.minimumDate options:0] forKey:@"_minimumDate"]; 233 | [self fs_setVariable:[self.gregorian dateBySettingHour:0 minute:0 second:0 ofDate:self.currentPage options:0] forKey:@"_currentPage"]; 234 | [self fs_performSelector:NSSelectorFromString(@"scrollToPageForDate:animated") withObjects:self.today, @NO, nil]; 235 | } 236 | 237 | - (NSString *)identifier 238 | { 239 | return self.gregorian.calendarIdentifier; 240 | } 241 | 242 | - (void)setLineHeightMultiplier:(CGFloat)lineHeightMultiplier 243 | { 244 | self.rowHeight = FSCalendarStandardRowHeight*MAX(1, FSCalendarDeviceIsIPad*1.5); 245 | } 246 | 247 | @end 248 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarHeaderView.m: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarHeader.m 3 | // Pods 4 | // 5 | // Created by Wenchao Ding on 29/1/15. 6 | // 7 | // 8 | 9 | #import "FSCalendar.h" 10 | #import "FSCalendarExtensions.h" 11 | #import "FSCalendarHeaderView.h" 12 | #import "FSCalendarCollectionView.h" 13 | #import "FSCalendarDynamicHeader.h" 14 | 15 | @interface FSCalendarHeaderView () 16 | 17 | - (void)scrollToOffset:(CGFloat)scrollOffset animated:(BOOL)animated; 18 | - (void)configureCell:(FSCalendarHeaderCell *)cell atIndexPath:(NSIndexPath *)indexPath; 19 | 20 | @end 21 | 22 | @implementation FSCalendarHeaderView 23 | 24 | #pragma mark - Life cycle 25 | 26 | - (instancetype)initWithFrame:(CGRect)frame 27 | { 28 | self = [super initWithFrame:frame]; 29 | if (self) { 30 | [self initialize]; 31 | } 32 | return self; 33 | } 34 | 35 | - (id)initWithCoder:(NSCoder *)aDecoder 36 | { 37 | self = [super initWithCoder:aDecoder]; 38 | if (self) { 39 | [self initialize]; 40 | } 41 | return self; 42 | } 43 | 44 | - (void)initialize 45 | { 46 | _needsAdjustingViewFrame = YES; 47 | _needsAdjustingMonthPosition = YES; 48 | _scrollDirection = UICollectionViewScrollDirectionHorizontal; 49 | _scrollEnabled = YES; 50 | 51 | FSCalendarHeaderLayout *collectionViewLayout = [[FSCalendarHeaderLayout alloc] init]; 52 | self.collectionViewLayout = collectionViewLayout; 53 | 54 | FSCalendarCollectionView *collectionView = [[FSCalendarCollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:collectionViewLayout]; 55 | collectionView.scrollEnabled = NO; 56 | collectionView.userInteractionEnabled = NO; 57 | collectionView.backgroundColor = [UIColor clearColor]; 58 | collectionView.dataSource = self; 59 | collectionView.delegate = self; 60 | collectionView.showsHorizontalScrollIndicator = NO; 61 | collectionView.showsVerticalScrollIndicator = NO; 62 | [self addSubview:collectionView]; 63 | [collectionView registerClass:[FSCalendarHeaderCell class] forCellWithReuseIdentifier:@"cell"]; 64 | self.collectionView = collectionView; 65 | } 66 | 67 | - (void)layoutSubviews 68 | { 69 | [super layoutSubviews]; 70 | 71 | if (_needsAdjustingViewFrame) { 72 | _needsAdjustingViewFrame = NO; 73 | _collectionViewLayout.itemSize = CGSizeMake(1, 1); 74 | [_collectionViewLayout invalidateLayout]; 75 | _collectionView.frame = CGRectMake(0, self.fs_height*0.1, self.fs_width, self.fs_height*0.9); 76 | } 77 | 78 | if (_needsAdjustingMonthPosition) { 79 | _needsAdjustingMonthPosition = NO; 80 | [self scrollToOffset:_scrollOffset animated:NO]; 81 | } 82 | 83 | } 84 | 85 | - (void)dealloc 86 | { 87 | _collectionView.dataSource = nil; 88 | _collectionView.delegate = nil; 89 | } 90 | 91 | #pragma mark - 92 | 93 | - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView 94 | { 95 | return 1; 96 | } 97 | 98 | - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section 99 | { 100 | NSInteger numberOfSections = self.calendar.collectionView.numberOfSections; 101 | if (self.scrollDirection == UICollectionViewScrollDirectionVertical) { 102 | return numberOfSections; 103 | } 104 | return numberOfSections + 2; 105 | } 106 | 107 | - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath 108 | { 109 | FSCalendarHeaderCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath]; 110 | cell.header = self; 111 | [self configureCell:cell atIndexPath:indexPath]; 112 | return cell; 113 | } 114 | 115 | - (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath 116 | { 117 | [cell setNeedsLayout]; 118 | } 119 | 120 | - (void)scrollViewDidScroll:(UIScrollView *)scrollView 121 | { 122 | [_collectionView.visibleCells makeObjectsPerformSelector:@selector(setNeedsLayout)]; 123 | } 124 | 125 | #pragma mark - Properties 126 | 127 | - (void)setCalendar:(FSCalendar *)calendar 128 | { 129 | _calendar = calendar; 130 | [self configureAppearance]; 131 | } 132 | 133 | - (void)setScrollOffset:(CGFloat)scrollOffset 134 | { 135 | [self setScrollOffset:scrollOffset animated:NO]; 136 | } 137 | 138 | - (void)setScrollOffset:(CGFloat)scrollOffset animated:(BOOL)animated 139 | { 140 | if (_scrollOffset != scrollOffset) { 141 | _scrollOffset = scrollOffset; 142 | } 143 | [self scrollToOffset:scrollOffset animated:NO]; 144 | } 145 | 146 | - (void)scrollToOffset:(CGFloat)scrollOffset animated:(BOOL)animated 147 | { 148 | if (self.scrollDirection == UICollectionViewScrollDirectionHorizontal) { 149 | CGFloat step = self.collectionView.fs_width*((self.scrollDirection==UICollectionViewScrollDirectionHorizontal)?0.5:1); 150 | [_collectionView setContentOffset:CGPointMake((scrollOffset+0.5)*step, 0) animated:animated]; 151 | } else { 152 | CGFloat step = self.collectionView.fs_height; 153 | [_collectionView setContentOffset:CGPointMake(0, scrollOffset*step) animated:animated]; 154 | } 155 | } 156 | 157 | - (void)setScrollDirection:(UICollectionViewScrollDirection)scrollDirection 158 | { 159 | if (_scrollDirection != scrollDirection) { 160 | _scrollDirection = scrollDirection; 161 | _collectionViewLayout.scrollDirection = scrollDirection; 162 | _needsAdjustingMonthPosition = YES; 163 | [self setNeedsLayout]; 164 | } 165 | } 166 | 167 | - (void)setScrollEnabled:(BOOL)scrollEnabled 168 | { 169 | if (_scrollEnabled != scrollEnabled) { 170 | _scrollEnabled = scrollEnabled; 171 | [_collectionView.visibleCells makeObjectsPerformSelector:@selector(setNeedsLayout)]; 172 | } 173 | } 174 | 175 | #pragma mark - Public 176 | 177 | - (void)reloadData 178 | { 179 | [_collectionView reloadData]; 180 | } 181 | 182 | - (void)configureCell:(FSCalendarHeaderCell *)cell atIndexPath:(NSIndexPath *)indexPath 183 | { 184 | FSCalendarAppearance *appearance = self.calendar.appearance; 185 | cell.titleLabel.font = appearance.headerTitleFont; 186 | cell.titleLabel.textColor = appearance.headerTitleColor; 187 | _calendar.formatter.dateFormat = appearance.headerDateFormat; 188 | BOOL usesUpperCase = (appearance.caseOptions & 15) == FSCalendarCaseOptionsHeaderUsesUpperCase; 189 | NSString *text = nil; 190 | switch (self.calendar.transitionCoordinator.representingScope) { 191 | case FSCalendarScopeMonth: { 192 | if (_scrollDirection == UICollectionViewScrollDirectionHorizontal) { 193 | // 多出的两项需要制空 194 | if ((indexPath.item == 0 || indexPath.item == [self.collectionView numberOfItemsInSection:0] - 1)) { 195 | text = nil; 196 | } else { 197 | NSDate *date = [self.calendar.gregorian dateByAddingUnit:NSCalendarUnitMonth value:indexPath.item-1 toDate:self.calendar.minimumDate options:0]; 198 | text = [_calendar.formatter stringFromDate:date]; 199 | } 200 | } else { 201 | NSDate *date = [self.calendar.gregorian dateByAddingUnit:NSCalendarUnitMonth value:indexPath.item toDate:self.calendar.minimumDate options:0]; 202 | text = [_calendar.formatter stringFromDate:date]; 203 | } 204 | break; 205 | } 206 | case FSCalendarScopeWeek: { 207 | if ((indexPath.item == 0 || indexPath.item == [self.collectionView numberOfItemsInSection:0] - 1)) { 208 | text = nil; 209 | } else { 210 | NSDate *firstPage = [self.calendar.gregorian fs_middleDayOfWeek:self.calendar.minimumDate]; 211 | NSDate *date = [self.calendar.gregorian dateByAddingUnit:NSCalendarUnitWeekOfYear value:indexPath.item-1 toDate:firstPage options:0]; 212 | text = [_calendar.formatter stringFromDate:date]; 213 | } 214 | break; 215 | } 216 | default: { 217 | break; 218 | } 219 | } 220 | text = usesUpperCase ? text.uppercaseString : text; 221 | cell.titleLabel.text = text; 222 | [cell setNeedsLayout]; 223 | } 224 | 225 | - (void)configureAppearance 226 | { 227 | [self.collectionView.visibleCells enumerateObjectsUsingBlock:^(__kindof FSCalendarHeaderCell * _Nonnull cell, NSUInteger idx, BOOL * _Nonnull stop) { 228 | [self configureCell:cell atIndexPath:[self.collectionView indexPathForCell:cell]]; 229 | }]; 230 | } 231 | 232 | @end 233 | 234 | 235 | @implementation FSCalendarHeaderCell 236 | 237 | - (instancetype)initWithFrame:(CGRect)frame 238 | { 239 | self = [super initWithFrame:frame]; 240 | if (self) { 241 | UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; 242 | titleLabel.textAlignment = NSTextAlignmentCenter; 243 | titleLabel.lineBreakMode = NSLineBreakByWordWrapping; 244 | titleLabel.numberOfLines = 0; 245 | [self.contentView addSubview:titleLabel]; 246 | self.titleLabel = titleLabel; 247 | } 248 | return self; 249 | } 250 | 251 | - (void)setBounds:(CGRect)bounds 252 | { 253 | [super setBounds:bounds]; 254 | _titleLabel.frame = bounds; 255 | } 256 | 257 | - (void)layoutSubviews 258 | { 259 | [super layoutSubviews]; 260 | 261 | self.titleLabel.frame = self.contentView.bounds; 262 | 263 | if (self.header.scrollDirection == UICollectionViewScrollDirectionHorizontal) { 264 | CGFloat position = [self.contentView convertPoint:CGPointMake(CGRectGetMidX(self.contentView.bounds), CGRectGetMidY(self.contentView.bounds)) toView:self.header].x; 265 | CGFloat center = CGRectGetMidX(self.header.bounds); 266 | if (self.header.scrollEnabled) { 267 | self.contentView.alpha = 1.0 - (1.0-self.header.calendar.appearance.headerMinimumDissolvedAlpha)*ABS(center-position)/self.fs_width; 268 | } else { 269 | self.contentView.alpha = (position > self.header.fs_width*0.25 && position < self.header.fs_width*0.75); 270 | } 271 | } else if (self.header.scrollDirection == UICollectionViewScrollDirectionVertical) { 272 | CGFloat position = [self.contentView convertPoint:CGPointMake(CGRectGetMidX(self.contentView.bounds), CGRectGetMidY(self.contentView.bounds)) toView:self.header].y; 273 | CGFloat center = CGRectGetMidY(self.header.bounds); 274 | self.contentView.alpha = 1.0 - (1.0-self.header.calendar.appearance.headerMinimumDissolvedAlpha)*ABS(center-position)/self.fs_height; 275 | } 276 | 277 | } 278 | 279 | @end 280 | 281 | 282 | @implementation FSCalendarHeaderLayout 283 | 284 | - (instancetype)init 285 | { 286 | self = [super init]; 287 | if (self) { 288 | self.scrollDirection = UICollectionViewScrollDirectionHorizontal; 289 | self.minimumInteritemSpacing = 0; 290 | self.minimumLineSpacing = 0; 291 | self.sectionInset = UIEdgeInsetsZero; 292 | self.itemSize = CGSizeMake(1, 1); 293 | } 294 | return self; 295 | } 296 | 297 | - (void)prepareLayout 298 | { 299 | [super prepareLayout]; 300 | 301 | self.itemSize = CGSizeMake( 302 | self.collectionView.fs_width*((self.scrollDirection==UICollectionViewScrollDirectionHorizontal)?0.5:1), 303 | self.collectionView.fs_height 304 | ); 305 | 306 | } 307 | 308 | @end 309 | 310 | @implementation FSCalendarHeaderTouchDeliver 311 | 312 | - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event 313 | { 314 | UIView *hitView = [super hitTest:point withEvent:event]; 315 | if (hitView == self) { 316 | return _calendar.collectionView ?: hitView; 317 | } 318 | return hitView; 319 | } 320 | 321 | @end 322 | 323 | 324 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarCalculator.m: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarCalculator.m 3 | // FSCalendar 4 | // 5 | // Created by dingwenchao on 30/10/2016. 6 | // Copyright © 2016 Wenchao Ding. All rights reserved. 7 | // 8 | 9 | #import "FSCalendar.h" 10 | #import "FSCalendarCalculator.h" 11 | #import "FSCalendarDynamicHeader.h" 12 | #import "FSCalendarExtensions.h" 13 | 14 | @interface FSCalendarCalculator () 15 | 16 | @property (assign, nonatomic) NSInteger numberOfMonths; 17 | @property (strong, nonatomic) NSMutableDictionary *months; 18 | @property (strong, nonatomic) NSMutableDictionary *monthHeads; 19 | 20 | @property (assign, nonatomic) NSInteger numberOfWeeks; 21 | @property (strong, nonatomic) NSMutableDictionary *weeks; 22 | @property (strong, nonatomic) NSMutableDictionary *rowCounts; 23 | 24 | @property (readonly, nonatomic) NSCalendar *gregorian; 25 | @property (readonly, nonatomic) NSDate *minimumDate; 26 | @property (readonly, nonatomic) NSDate *maximumDate; 27 | 28 | - (void)didReceiveNotifications:(NSNotification *)notification; 29 | 30 | @end 31 | 32 | @implementation FSCalendarCalculator 33 | 34 | @dynamic gregorian,minimumDate,maximumDate; 35 | 36 | - (instancetype)initWithCalendar:(FSCalendar *)calendar 37 | { 38 | self = [super init]; 39 | if (self) { 40 | self.calendar = calendar; 41 | 42 | self.months = [NSMutableDictionary dictionary]; 43 | self.monthHeads = [NSMutableDictionary dictionary]; 44 | self.weeks = [NSMutableDictionary dictionary]; 45 | self.rowCounts = [NSMutableDictionary dictionary]; 46 | 47 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveNotifications:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; 48 | } 49 | return self; 50 | } 51 | 52 | - (void)dealloc 53 | { 54 | [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; 55 | } 56 | 57 | - (id)forwardingTargetForSelector:(SEL)selector 58 | { 59 | if ([self.calendar respondsToSelector:selector]) { 60 | return self.calendar; 61 | } 62 | return [super forwardingTargetForSelector:selector]; 63 | } 64 | 65 | #pragma mark - Public functions 66 | 67 | - (NSDate *)safeDateForDate:(NSDate *)date 68 | { 69 | if ([self.gregorian compareDate:date toDate:self.minimumDate toUnitGranularity:NSCalendarUnitDay] == NSOrderedAscending) { 70 | date = self.minimumDate; 71 | } else if ([self.gregorian compareDate:date toDate:self.maximumDate toUnitGranularity:NSCalendarUnitDay] == NSOrderedDescending) { 72 | date = self.maximumDate; 73 | } 74 | return date; 75 | } 76 | 77 | - (NSDate *)dateForIndexPath:(NSIndexPath *)indexPath scope:(FSCalendarScope)scope 78 | { 79 | if (!indexPath) return nil; 80 | switch (scope) { 81 | case FSCalendarScopeMonth: { 82 | NSDate *head = [self monthHeadForSection:indexPath.section]; 83 | NSUInteger daysOffset = indexPath.item; 84 | NSDate *date = [self.gregorian dateByAddingUnit:NSCalendarUnitDay value:daysOffset toDate:head options:0]; 85 | return date; 86 | break; 87 | } 88 | case FSCalendarScopeWeek: { 89 | NSDate *currentPage = [self weekForSection:indexPath.section]; 90 | NSDate *date = [self.gregorian dateByAddingUnit:NSCalendarUnitDay value:indexPath.item toDate:currentPage options:0]; 91 | return date; 92 | } 93 | } 94 | return nil; 95 | } 96 | 97 | - (NSDate *)dateForIndexPath:(NSIndexPath *)indexPath 98 | { 99 | if (!indexPath) return nil; 100 | return [self dateForIndexPath:indexPath scope:self.calendar.transitionCoordinator.representingScope]; 101 | } 102 | 103 | - (NSIndexPath *)indexPathForDate:(NSDate *)date 104 | { 105 | return [self indexPathForDate:date atMonthPosition:FSCalendarMonthPositionCurrent scope:self.calendar.transitionCoordinator.representingScope]; 106 | } 107 | 108 | - (NSIndexPath *)indexPathForDate:(NSDate *)date scope:(FSCalendarScope)scope 109 | { 110 | return [self indexPathForDate:date atMonthPosition:FSCalendarMonthPositionCurrent scope:scope]; 111 | } 112 | 113 | - (NSIndexPath *)indexPathForDate:(NSDate *)date atMonthPosition:(FSCalendarMonthPosition)position scope:(FSCalendarScope)scope 114 | { 115 | if (!date) return nil; 116 | NSInteger item = 0; 117 | NSInteger section = 0; 118 | switch (scope) { 119 | case FSCalendarScopeMonth: { 120 | section = [self.gregorian components:NSCalendarUnitMonth fromDate:[self.gregorian fs_firstDayOfMonth:self.minimumDate] toDate:[self.gregorian fs_firstDayOfMonth:date] options:0].month; 121 | if (position == FSCalendarMonthPositionPrevious) { 122 | section++; 123 | } else if (position == FSCalendarMonthPositionNext) { 124 | section--; 125 | } 126 | NSDate *head = [self monthHeadForSection:section]; 127 | item = [self.gregorian components:NSCalendarUnitDay fromDate:head toDate:date options:0].day; 128 | break; 129 | } 130 | case FSCalendarScopeWeek: { 131 | section = [self.gregorian components:NSCalendarUnitWeekOfYear fromDate:[self.gregorian fs_firstDayOfWeek:self.minimumDate] toDate:[self.gregorian fs_firstDayOfWeek:date] options:0].weekOfYear; 132 | item = (([self.gregorian component:NSCalendarUnitWeekday fromDate:date] - self.gregorian.firstWeekday) + 7) % 7; 133 | break; 134 | } 135 | } 136 | if (item < 0 || section < 0) { 137 | return nil; 138 | } 139 | NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:section]; 140 | return indexPath; 141 | } 142 | 143 | - (NSIndexPath *)indexPathForDate:(NSDate *)date atMonthPosition:(FSCalendarMonthPosition)position 144 | { 145 | return [self indexPathForDate:date atMonthPosition:position scope:self.calendar.transitionCoordinator.representingScope]; 146 | } 147 | 148 | - (NSDate *)pageForSection:(NSInteger)section 149 | { 150 | switch (self.calendar.transitionCoordinator.representingScope) { 151 | case FSCalendarScopeWeek: 152 | return [self.gregorian fs_middleDayOfWeek:[self weekForSection:section]]; 153 | case FSCalendarScopeMonth: 154 | return [self monthForSection:section]; 155 | default: 156 | break; 157 | } 158 | } 159 | 160 | - (NSDate *)monthForSection:(NSInteger)section 161 | { 162 | NSNumber *key = @(section); 163 | NSDate *month = self.months[key]; 164 | if (!month) { 165 | month = [self.gregorian dateByAddingUnit:NSCalendarUnitMonth value:section toDate:[self.gregorian fs_firstDayOfMonth:self.minimumDate] options:0]; 166 | NSInteger numberOfHeadPlaceholders = [self numberOfHeadPlaceholdersForMonth:month]; 167 | NSDate *monthHead = [self.gregorian dateByAddingUnit:NSCalendarUnitDay value:-numberOfHeadPlaceholders toDate:month options:0]; 168 | self.months[key] = month; 169 | self.monthHeads[key] = monthHead; 170 | } 171 | return month; 172 | } 173 | 174 | - (NSDate *)monthHeadForSection:(NSInteger)section 175 | { 176 | NSNumber *key = @(section); 177 | NSDate *monthHead = self.monthHeads[key]; 178 | if (!monthHead) { 179 | NSDate *month = [self.gregorian dateByAddingUnit:NSCalendarUnitMonth value:section toDate:[self.gregorian fs_firstDayOfMonth:self.minimumDate] options:0]; 180 | NSInteger numberOfHeadPlaceholders = [self numberOfHeadPlaceholdersForMonth:month]; 181 | monthHead = [self.gregorian dateByAddingUnit:NSCalendarUnitDay value:-numberOfHeadPlaceholders toDate:month options:0]; 182 | self.months[key] = month; 183 | self.monthHeads[key] = monthHead; 184 | } 185 | return monthHead; 186 | } 187 | 188 | - (NSDate *)weekForSection:(NSInteger)section 189 | { 190 | NSNumber *key = @(section); 191 | NSDate *week = self.weeks[key]; 192 | if (!week) { 193 | week = [self.gregorian dateByAddingUnit:NSCalendarUnitWeekOfYear value:section toDate:[self.gregorian fs_firstDayOfWeek:self.minimumDate] options:0]; 194 | self.weeks[key] = week; 195 | } 196 | return week; 197 | } 198 | 199 | - (NSInteger)numberOfSections 200 | { 201 | if (self.calendar.transitionCoordinator.transition == FSCalendarTransitionWeekToMonth) { 202 | return self.numberOfMonths; 203 | } else { 204 | switch (self.calendar.transitionCoordinator.representingScope) { 205 | case FSCalendarScopeMonth: { 206 | return self.numberOfMonths; 207 | } 208 | case FSCalendarScopeWeek: { 209 | return self.numberOfWeeks; 210 | } 211 | } 212 | } 213 | } 214 | 215 | - (NSInteger)numberOfHeadPlaceholdersForMonth:(NSDate *)month 216 | { 217 | NSInteger currentWeekday = [self.gregorian component:NSCalendarUnitWeekday fromDate:month]; 218 | NSInteger number = ((currentWeekday- self.gregorian.firstWeekday) + 7) % 7 ?: (7 * (!self.calendar.floatingMode&&(self.calendar.placeholderType == FSCalendarPlaceholderTypeFillSixRows))); 219 | return number; 220 | } 221 | 222 | - (NSInteger)numberOfRowsInMonth:(NSDate *)month 223 | { 224 | if (!month) return 0; 225 | if (self.calendar.placeholderType == FSCalendarPlaceholderTypeFillSixRows) return 6; 226 | 227 | NSNumber *rowCount = self.rowCounts[month]; 228 | if (!rowCount) { 229 | NSDate *firstDayOfMonth = [self.gregorian fs_firstDayOfMonth:month]; 230 | NSInteger weekdayOfFirstDay = [self.gregorian component:NSCalendarUnitWeekday fromDate:firstDayOfMonth]; 231 | NSInteger numberOfDaysInMonth = [self.gregorian fs_numberOfDaysInMonth:month]; 232 | NSInteger numberOfPlaceholdersForPrev = ((weekdayOfFirstDay - self.gregorian.firstWeekday) + 7) % 7; 233 | NSInteger headDayCount = numberOfDaysInMonth + numberOfPlaceholdersForPrev; 234 | NSInteger numberOfRows = (headDayCount/7) + (headDayCount%7>0); 235 | rowCount = @(numberOfRows); 236 | self.rowCounts[month] = rowCount; 237 | } 238 | return rowCount.integerValue; 239 | } 240 | 241 | - (NSInteger)numberOfRowsInSection:(NSInteger)section 242 | { 243 | if (self.calendar.transitionCoordinator.representingScope == FSCalendarScopeWeek) return 1; 244 | NSDate *month = [self monthForSection:section]; 245 | return [self numberOfRowsInMonth:month]; 246 | } 247 | 248 | - (FSCalendarMonthPosition)monthPositionForIndexPath:(NSIndexPath *)indexPath 249 | { 250 | if (!indexPath) return FSCalendarMonthPositionNotFound; 251 | if (self.calendar.transitionCoordinator.representingScope == FSCalendarScopeWeek) { 252 | return FSCalendarMonthPositionCurrent; 253 | } 254 | NSDate *date = [self dateForIndexPath:indexPath]; 255 | NSDate *page = [self pageForSection:indexPath.section]; 256 | NSComparisonResult comparison = [self.gregorian compareDate:date toDate:page toUnitGranularity:NSCalendarUnitMonth]; 257 | switch (comparison) { 258 | case NSOrderedAscending: 259 | return FSCalendarMonthPositionPrevious; 260 | case NSOrderedSame: 261 | return FSCalendarMonthPositionCurrent; 262 | case NSOrderedDescending: 263 | return FSCalendarMonthPositionNext; 264 | } 265 | } 266 | 267 | - (FSCalendarCoordinate)coordinateForIndexPath:(NSIndexPath *)indexPath 268 | { 269 | FSCalendarCoordinate coordinate; 270 | coordinate.row = indexPath.item / 7; 271 | coordinate.column = indexPath.item % 7; 272 | return coordinate; 273 | } 274 | 275 | - (void)reloadSections 276 | { 277 | self.numberOfMonths = [self.gregorian components:NSCalendarUnitMonth fromDate:[self.gregorian fs_firstDayOfMonth:self.minimumDate] toDate:self.maximumDate options:0].month+1; 278 | self.numberOfWeeks = [self.gregorian components:NSCalendarUnitWeekOfYear fromDate:[self.gregorian fs_firstDayOfWeek:self.minimumDate] toDate:self.maximumDate options:0].weekOfYear+1; 279 | [self clearCaches]; 280 | } 281 | 282 | - (void)clearCaches 283 | { 284 | [self.months removeAllObjects]; 285 | [self.monthHeads removeAllObjects]; 286 | [self.weeks removeAllObjects]; 287 | [self.rowCounts removeAllObjects]; 288 | } 289 | 290 | #pragma mark - Private functinos 291 | 292 | - (void)didReceiveNotifications:(NSNotification *)notification 293 | { 294 | if ([notification.name isEqualToString:UIApplicationDidReceiveMemoryWarningNotification]) { 295 | [self clearCaches]; 296 | } 297 | } 298 | 299 | @end 300 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/README.md: -------------------------------------------------------------------------------- 1 | 2 | ![logo](https://cloud.githubusercontent.com/assets/5186464/16540124/efc51f72-408b-11e6-934a-4e750b8b55bb.png) 3 |

4 | [![Apps Using](https://img.shields.io/badge/Apps%20Using-%3E%2010,000-00BFFF.svg?style=plastic)](https://cocoapods.org/pods/FSCalendar) 5 | [![Total Downloads](https://img.shields.io/badge/Total%20Downloads-%3E%20500,000-00BFFF.svg?style=plastic)](https://cocoapods.org/pods/FSCalendar) 6 |
7 | [![Travis](https://travis-ci.org/WenchaoD/FSCalendar.svg?branch=master)](https://travis-ci.org/WenchaoD/FSCalendar) 8 | [![Version](https://img.shields.io/cocoapods/v/FSCalendar.svg?style=flat)](http://cocoadocs.org/docsets/FSCalendar) 9 | [![Platform](https://img.shields.io/badge/platform-iOS%207%2B-blue.svg?style=flat)](http://cocoadocs.org/docsets/FSCalendar) 10 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 11 |
12 | [![Languages](https://img.shields.io/badge/language-objc%20|%20swift-FF69B4.svg?style=plastic)](#) 13 | 14 | # Table of contents 15 | * [Screenshots](#screenshots) 16 | * [Installation](#installation) 17 | * [Pre-knowledge](#pre-knowledge) 18 | * [Support](#support) 19 | * [Contact](#contact) 20 | 21 | ## Screenshots 22 | 23 | ### iPhone 24 | ![fscalendar](https://cloud.githubusercontent.com/assets/5186464/10262249/4fabae40-69f2-11e5-97ab-afbacd0a3da2.jpg) 25 | 26 | ### iPad 27 | ![fscalendar-ipad](https://cloud.githubusercontent.com/assets/5186464/10927681/d2448cb6-82dc-11e5-9d11-f664a06698a7.jpg) 28 | 29 | ### Safe Orientation 30 | ![fscalendar-scope-orientation-autolayout](https://cloud.githubusercontent.com/assets/5186464/20325758/ea125e1e-abc0-11e6-9e29-491acbcb0d07.gif) 31 | 32 | ### Today Extension 33 | | iOS8/9 | iOS10 | 34 | |--------------|-------------| 35 | |![today1](https://cloud.githubusercontent.com/assets/5186464/20288375/ed3fba0e-ab0d-11e6-8b15-43d3dc656f22.gif)|![today2](https://cloud.githubusercontent.com/assets/5186464/20288378/f11e318c-ab0d-11e6-8d1d-9d89b563e9d7.gif)| 36 | 37 | ### Interactive Scope Gesture 38 | | ![1](https://cloud.githubusercontent.com/assets/5186464/21559640/e92a9ccc-ce8a-11e6-8c60-e52204f33249.gif) | 39 | | ---- | 40 | 41 | ### DIY support 42 | | ![1](https://cloud.githubusercontent.com/assets/5186464/20026983/22354a0e-a342-11e6-8ae6-0614ea7f35ae.gif) | 43 | | ------------- | 44 | > To customize your own cell, view DIY Example in `Example-Swift` or `Example-Objc` 45 | 46 | 47 | ### Swipe-To-Choose 48 | 49 | |Single-Selection
Swipe-To-Choose|Multiple-Selection
Swipe-To-Choose|DIY
Swipe-To-Choose| 50 | |----------|--------|--------| 51 | |![1](https://cloud.githubusercontent.com/assets/5186464/20257768/cb1905d4-aa86-11e6-9ef7-af76f9caa024.gif)|![2](https://cloud.githubusercontent.com/assets/5186464/20257826/254070ec-aa87-11e6-81b1-1815453fd464.gif)|![3](https://cloud.githubusercontent.com/assets/5186464/20257836/2ffa3252-aa87-11e6-8ff9-3b40f5b2307b.gif)| 52 | 53 | ## Achievement of Users 54 | 55 | | ![1](https://cloud.githubusercontent.com/assets/5186464/21747193/3111e4ee-d59a-11e6-8e4d-ca695b53e421.png) | ![2](https://cloud.githubusercontent.com/assets/5186464/21747393/42a753fa-d5a0-11e6-9cb2-de7cc642e69e.png) | ![3](https://cloud.githubusercontent.com/assets/5186464/21897255/ff78fcdc-d923-11e6-9d59-62119bc4343f.png) | ![4](https://cloud.githubusercontent.com/assets/5186464/21747192/3111cacc-d59a-11e6-8626-44cd75ebd794.png) | 56 | | ------------- | ------------- | ------------- | ------------- | 57 | 58 | #### [***More Achievements***](https://github.com/WenchaoD/FSCalendar/wiki/) are available in [***FSCalendar Gallery***](https://github.com/WenchaoD/FSCalendar/wiki/) 59 | 60 | === 61 | 62 | # Installation 63 | 64 | ## CocoaPods: 65 | 66 | * For iOS8+: 👍 67 | 68 | ```ruby 69 | use_frameworks! 70 | target '' do 71 | pod 'FSCalendar' 72 | end 73 | ``` 74 | 75 | * For iOS7+: 76 | 77 | ```ruby 78 | target '' do 79 | pod 'FSCalendar' 80 | end 81 | ``` 82 | 83 | > [NSCalendarExtension](https://github.com/WenchaoD/NSCalendarExtension) is required to get iOS7 compatibility. 84 | 85 | ## Carthage: 86 | * For iOS8+ 87 | 88 | ```ruby 89 | github "WenchaoD/FSCalendar" 90 | ``` 91 | 92 | ## Manually: 93 | * Drag all files under `FSCalendar` folder into your project. 👍 94 | 95 | > Alternatively to give it a test run, simply press `command+u` in `Example-Objc` or `Example-Swift` and launch the ***UITest Target***.
96 | > Only the methods marked "👍" support IBInspectable / IBDesignable feature. [Have fun with Interface builder](#roll_with_interface_builder) 97 | 98 | 99 | # Setup 100 | 101 | ## Use Interface Builder 102 | 103 | 1、 Drag an UIView object to ViewController Scene 104 | 2、 Change the `Custom Class` to `FSCalendar`
105 | 3、 Link `dataSource` and `delegate` to the ViewController
106 | 107 | ![fscalendar-ib](https://cloud.githubusercontent.com/assets/5186464/9488580/a360297e-4c0d-11e5-8548-ee9274e7c4af.jpg) 108 | 109 | 4、 Finally, implement `FSCalendarDataSource` and `FSCalendarDelegate` in your `ViewController` 110 | 111 | ## Or use code 112 | 113 | ```objc 114 | @property (weak , nonatomic) FSCalendar *calendar; 115 | ``` 116 | ```objc 117 | // In loadView(Recommended) or viewDidLoad 118 | FSCalendar *calendar = [[FSCalendar alloc] initWithFrame:CGRectMake(0, 0, 320, 300)]; 119 | calendar.dataSource = self; 120 | calendar.delegate = self; 121 | [self.view addSubview:calendar]; 122 | self.calendar = calendar; 123 | ``` 124 |
125 | 126 | ## Or swift 127 | 128 | * To use `FSCalendar` in swift, you need to [Create Bridge Header](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html) first. 129 | 130 | 131 | ```swift 132 | fileprivate weak var calendar: FSCalendar! 133 | ``` 134 | ```swift 135 | // In loadView or viewDidLoad 136 | let calendar = FSCalendar(frame: CGRect(x: 0, y: 0, width: 320, height: 300)) 137 | calendar.dataSource = self 138 | calendar.delegate = self 139 | view.addSubview(calendar) 140 | self.calendar = calendar 141 | ``` 142 | 143 | > To use **FSCalendar** in Swift3, see `Example-Swift` for details. 144 | 145 | 146 | ## Warning 147 | `FSCalendar` ***doesn't*** update frame by itself, Please implement 148 | 149 | * For ***AutoLayout*** 150 | 151 | ```objc 152 | - (void)calendar:(FSCalendar *)calendar boundingRectWillChange:(CGRect)bounds animated:(BOOL)animated 153 | { 154 | self.calendarHeightConstraint.constant = CGRectGetHeight(bounds); 155 | // Do other updates here 156 | [self.view layoutIfNeeded]; 157 | } 158 | ``` 159 | 160 | * For ***Manual Layout*** 161 | 162 | ```objc 163 | - (void)calendar:(FSCalendar *)calendar boundingRectWillChange:(CGRect)bounds animated:(BOOL)animated 164 | { 165 | calendar.frame = (CGRect){calendar.frame.origin,bounds.size}; 166 | // Do other updates here 167 | } 168 | ``` 169 | 170 | * If you are using ***Masonry*** 171 | 172 | ```objc 173 | - (void)calendar:(FSCalendar *)calendar boundingRectWillChange:(CGRect)bounds animated:(BOOL)animated 174 | { 175 | [calendar mas_updateConstraints:^(MASConstraintMaker *make) { 176 | make.height.equalTo(@(bounds.size.height)); 177 | // Do other updates 178 | }]; 179 | [self.view layoutIfNeeded]; 180 | } 181 | ``` 182 | 183 | * If you are using ***SnapKit*** 184 | 185 | ```swift 186 | func calendar(_ calendar: FSCalendar, boundingRectWillChange bounds: CGRect, animated: Bool) { 187 | calendar.snp.updateConstraints { (make) in 188 | make.height.equalTo(bounds.height) 189 | // Do other updates 190 | } 191 | self.view.layoutIfNeeded() 192 | } 193 | ``` 194 | 195 | ### Roll with Interface Builder 196 | ![fscalendar - ibdesignable](https://cloud.githubusercontent.com/assets/5186464/9301716/2e76a2ca-4503-11e5-8450-1fa7aa93e9fd.gif) 197 | 198 | # Pre-knowledge 199 | 200 | > In `Swift3`, `NSDate` and `NSDateFormatter` have been renamed to ***Date*** and ***DateFormatter*** , see `Example-Swift` for details. 201 | 202 | ## How to create NSDate object 203 | 204 | * By **NSCalendar**. 205 | 206 | ```objc 207 | self.gregorian = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian]; 208 | ``` 209 | 210 | Then: 211 | 212 | ```objc 213 | NSDate *date = [gregorian dateWithEra:1 year:2016 month:9 day:10 hour:0 minute:0 second:0 nanosecond:0]; 214 | // 2016-09-10 00:00:00 215 | ``` 216 | 217 | 218 | * Or by **NSDateFormatter** 219 | 220 | ```objc 221 | self.formatter = [[NSDateFormatter alloc] init]; 222 | self.formatter.dateFormat = @"yyyy-MM-dd"; 223 | ``` 224 | 225 | Then: 226 | 227 | ```objc 228 | NSDate *date = [self.formatter dateFromString:@"2016-09-10"]; 229 | ``` 230 | 231 | ## How to print out NSDate object 232 | 233 | * Use **NSDateFormatter** 234 | 235 | ```objc 236 | self.formatter = [[NSDateFormatter alloc] init]; 237 | self.formatter.dateFormat = @"yyyy/MM/dd"; 238 | ``` 239 | 240 | ```objc 241 | NSString *string = [self.formatter stringFromDate:date]; 242 | NSLog(@"Date is %@", string); 243 | ``` 244 | 245 | ## How to manipulate NSDate with NSCalendar 246 | 247 | ```objc 248 | self.gregorian = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian]; 249 | ``` 250 | * Get component of NSDate 251 | 252 | ```objc 253 | NSInteger era = [self.gregorian component:NSCalendarUnitEra fromDate:date]; 254 | NSInteger year = [self.gregorian component:NSCalendarUnitYear fromDate:date]; 255 | NSInteger month = [self.gregorian component:NSCalendarUnitMonth fromDate:date]; 256 | NSInteger day = [self.gregorian component:NSCalendarUnitDay fromDate:date]; 257 | NSInteger hour = [self.gregorian component:NSCalendarUnitHour fromDate:date]; 258 | NSInteger minute = [self.gregorian component:NSCalendarUnitMinute fromDate:date]; 259 | ... 260 | 261 | ``` 262 | 263 | * Get next **month** 264 | 265 | ```objc 266 | NSDate *nextMonth = [self.gregorain dateByAddingUnit:NSCalendarUnitMonth value:1 toDate:date options:0]; 267 | ``` 268 | 269 | * Get next **day** 270 | 271 | ```objc 272 | NSDate *nextDay = [self.gregorain dateByAddingUnit:NSCalendarUnitDay value:1 toDate:date options:0]; 273 | ``` 274 | 275 | * Is date in today/tomorrow/yesterday/weekend 276 | 277 | ```objc 278 | BOOL isToday = [self.gregorian isDateInToday:date]; 279 | BOOL isYesterday = [self.gregorian isDateInYesterday:date]; 280 | BOOL isTomorrow = [self.gregorian isDateInTomorrow:date]; 281 | BOOL isWeekend = [self.gregorian isDateInWeekend:date]; 282 | ``` 283 | 284 | * Compare two dates 285 | 286 | ```objc 287 | 288 | BOOL sameDay = [self.gregorian isDate:date1 inSameDayAsDate:date2]; 289 | // Yes if the date1 and date2 are in same day 290 | 291 | 292 | [self.gregorian compareDate:date1 toDate:date2 toUnitGranularity:unit]; 293 | // compare the era/year/month/day/hour/minute .etc ... 294 | // return NSOrderAscending/NSOrderSame/NSOrderDecending 295 | 296 | BOOL inSameUnit = [self.gregorian isDate:date1 equalToDate:date2 toUnitGranularity:unit]; 297 | // if the given unit (era/year/month/day/hour/minute .etc) are the same 298 | 299 | 300 | ``` 301 | 302 | 303 | ## Support this repo 304 | * [**★Star**](#) this repo 305 |
306 | * Support with   307 |
308 | * Support with or 309 | 310 | 311 | 312 |
313 | 314 | 315 | ## Contact 316 | * 微博: [**@WenchaoD**](http://weibo.com/WenchaoD) 317 | * Twitter:[**@WenchaoD**](https://twitter.com/WenchaoD) 318 | * QQ支持群:

319 |        320 | ![fscalendar](https://cloud.githubusercontent.com/assets/5186464/18407011/8e4b6e48-7738-11e6-9fad-0e23cc881516.JPG) 321 | 322 | > If your made a beautiful calendar with this library in your app, please take a screen shot and [@me](https://twitter.com/WenchaoD) in twitter. Your help really means a lot to me!
323 | 324 | 325 | # License 326 | FSCalendar is available under the MIT license. See the LICENSE file for more info. 327 | 328 | ### [Documentation](http://cocoadocs.org/docsets/FSCalendar/) | [More Usage](https://github.com/WenchaoD/FSCalendar/blob/master/MOREUSAGE.md) | [简书](http://www.jianshu.com/notebooks/4276521/latest) 329 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarExtensions.m: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarExtensions.m 3 | // FSCalendar 4 | // 5 | // Created by dingwenchao on 10/8/16. 6 | // Copyright © 2016 Wenchao Ding. All rights reserved. 7 | // 8 | 9 | #import "FSCalendarExtensions.h" 10 | #import 11 | 12 | @implementation UIView (FSCalendarExtensions) 13 | 14 | - (CGFloat)fs_width 15 | { 16 | return CGRectGetWidth(self.frame); 17 | } 18 | 19 | - (void)setFs_width:(CGFloat)fs_width 20 | { 21 | self.frame = CGRectMake(self.fs_left, self.fs_top, fs_width, self.fs_height); 22 | } 23 | 24 | - (CGFloat)fs_height 25 | { 26 | return CGRectGetHeight(self.frame); 27 | } 28 | 29 | - (void)setFs_height:(CGFloat)fs_height 30 | { 31 | self.frame = CGRectMake(self.fs_left, self.fs_top, self.fs_width, fs_height); 32 | } 33 | 34 | - (CGFloat)fs_top 35 | { 36 | return CGRectGetMinY(self.frame); 37 | } 38 | 39 | - (void)setFs_top:(CGFloat)fs_top 40 | { 41 | self.frame = CGRectMake(self.fs_left, fs_top, self.fs_width, self.fs_height); 42 | } 43 | 44 | - (CGFloat)fs_bottom 45 | { 46 | return CGRectGetMaxY(self.frame); 47 | } 48 | 49 | - (void)setFs_bottom:(CGFloat)fs_bottom 50 | { 51 | self.fs_top = fs_bottom - self.fs_height; 52 | } 53 | 54 | - (CGFloat)fs_left 55 | { 56 | return CGRectGetMinX(self.frame); 57 | } 58 | 59 | - (void)setFs_left:(CGFloat)fs_left 60 | { 61 | self.frame = CGRectMake(fs_left, self.fs_top, self.fs_width, self.fs_height); 62 | } 63 | 64 | - (CGFloat)fs_right 65 | { 66 | return CGRectGetMaxX(self.frame); 67 | } 68 | 69 | - (void)setFs_right:(CGFloat)fs_right 70 | { 71 | self.fs_left = self.fs_right - self.fs_width; 72 | } 73 | 74 | @end 75 | 76 | 77 | @implementation CALayer (FSCalendarExtensions) 78 | 79 | - (CGFloat)fs_width 80 | { 81 | return CGRectGetWidth(self.frame); 82 | } 83 | 84 | - (void)setFs_width:(CGFloat)fs_width 85 | { 86 | self.frame = CGRectMake(self.fs_left, self.fs_top, fs_width, self.fs_height); 87 | } 88 | 89 | - (CGFloat)fs_height 90 | { 91 | return CGRectGetHeight(self.frame); 92 | } 93 | 94 | - (void)setFs_height:(CGFloat)fs_height 95 | { 96 | self.frame = CGRectMake(self.fs_left, self.fs_top, self.fs_width, fs_height); 97 | } 98 | 99 | - (CGFloat)fs_top 100 | { 101 | return CGRectGetMinY(self.frame); 102 | } 103 | 104 | - (void)setFs_top:(CGFloat)fs_top 105 | { 106 | self.frame = CGRectMake(self.fs_left, fs_top, self.fs_width, self.fs_height); 107 | } 108 | 109 | - (CGFloat)fs_bottom 110 | { 111 | return CGRectGetMaxY(self.frame); 112 | } 113 | 114 | - (void)setFs_bottom:(CGFloat)fs_bottom 115 | { 116 | self.fs_top = fs_bottom - self.fs_height; 117 | } 118 | 119 | - (CGFloat)fs_left 120 | { 121 | return CGRectGetMinX(self.frame); 122 | } 123 | 124 | - (void)setFs_left:(CGFloat)fs_left 125 | { 126 | self.frame = CGRectMake(fs_left, self.fs_top, self.fs_width, self.fs_height); 127 | } 128 | 129 | - (CGFloat)fs_right 130 | { 131 | return CGRectGetMaxX(self.frame); 132 | } 133 | 134 | - (void)setFs_right:(CGFloat)fs_right 135 | { 136 | self.fs_left = self.fs_right - self.fs_width; 137 | } 138 | 139 | @end 140 | 141 | @interface NSCalendar (FSCalendarExtensionsPrivate) 142 | 143 | @property (readonly, nonatomic) NSDateComponents *fs_privateComponents; 144 | 145 | @end 146 | 147 | @implementation NSCalendar (FSCalendarExtensions) 148 | 149 | - (nullable NSDate *)fs_firstDayOfMonth:(NSDate *)month 150 | { 151 | if (!month) return nil; 152 | NSDateComponents *components = [self components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour fromDate:month]; 153 | components.day = 1; 154 | return [self dateFromComponents:components]; 155 | } 156 | 157 | - (nullable NSDate *)fs_lastDayOfMonth:(NSDate *)month 158 | { 159 | if (!month) return nil; 160 | NSDateComponents *components = [self components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour fromDate:month]; 161 | components.month++; 162 | components.day = 0; 163 | return [self dateFromComponents:components]; 164 | } 165 | 166 | - (nullable NSDate *)fs_firstDayOfWeek:(NSDate *)week 167 | { 168 | if (!week) return nil; 169 | NSDateComponents *weekdayComponents = [self components:NSCalendarUnitWeekday fromDate:week]; 170 | NSDateComponents *components = self.fs_privateComponents; 171 | components.day = - (weekdayComponents.weekday - self.firstWeekday); 172 | components.day = (components.day-7) % 7; 173 | NSDate *firstDayOfWeek = [self dateByAddingComponents:components toDate:week options:0]; 174 | firstDayOfWeek = [self dateBySettingHour:0 minute:0 second:0 ofDate:firstDayOfWeek options:0]; 175 | components.day = NSIntegerMax; 176 | return firstDayOfWeek; 177 | } 178 | 179 | - (nullable NSDate *)fs_lastDayOfWeek:(NSDate *)week 180 | { 181 | if (!week) return nil; 182 | NSDateComponents *weekdayComponents = [self components:NSCalendarUnitWeekday fromDate:week]; 183 | NSDateComponents *components = self.fs_privateComponents; 184 | components.day = - (weekdayComponents.weekday - self.firstWeekday); 185 | components.day = (components.day-7) % 7 + 6; 186 | NSDate *lastDayOfWeek = [self dateByAddingComponents:components toDate:week options:0]; 187 | lastDayOfWeek = [self dateBySettingHour:0 minute:0 second:0 ofDate:lastDayOfWeek options:0]; 188 | components.day = NSIntegerMax; 189 | return lastDayOfWeek; 190 | } 191 | 192 | - (nullable NSDate *)fs_middleDayOfWeek:(NSDate *)week 193 | { 194 | if (!week) return nil; 195 | NSDateComponents *weekdayComponents = [self components:NSCalendarUnitWeekday fromDate:week]; 196 | NSDateComponents *componentsToSubtract = self.fs_privateComponents; 197 | componentsToSubtract.day = - (weekdayComponents.weekday - self.firstWeekday) + 3; 198 | NSDate *middleDayOfWeek = [self dateByAddingComponents:componentsToSubtract toDate:week options:0]; 199 | NSDateComponents *components = [self components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour fromDate:middleDayOfWeek]; 200 | middleDayOfWeek = [self dateFromComponents:components]; 201 | componentsToSubtract.day = NSIntegerMax; 202 | return middleDayOfWeek; 203 | } 204 | 205 | - (NSInteger)fs_numberOfDaysInMonth:(NSDate *)month 206 | { 207 | if (!month) return 0; 208 | NSRange days = [self rangeOfUnit:NSCalendarUnitDay 209 | inUnit:NSCalendarUnitMonth 210 | forDate:month]; 211 | return days.length; 212 | } 213 | 214 | - (NSDateComponents *)fs_privateComponents 215 | { 216 | NSDateComponents *components = objc_getAssociatedObject(self, _cmd); 217 | if (!components) { 218 | components = [[NSDateComponents alloc] init]; 219 | objc_setAssociatedObject(self, _cmd, components, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 220 | } 221 | return components; 222 | } 223 | 224 | @end 225 | 226 | @implementation NSMapTable (FSCalendarExtensions) 227 | 228 | - (void)setObject:(nullable id)obj forKeyedSubscript:(id)key 229 | { 230 | if (!key) return; 231 | 232 | if (obj) { 233 | [self setObject:obj forKey:key]; 234 | } else { 235 | [self removeObjectForKey:key]; 236 | } 237 | } 238 | 239 | - (id)objectForKeyedSubscript:(id)key 240 | { 241 | return [self objectForKey:key]; 242 | } 243 | 244 | @end 245 | 246 | @implementation NSCache (FSCalendarExtensions) 247 | 248 | - (void)setObject:(nullable id)obj forKeyedSubscript:(id)key 249 | { 250 | if (!key) return; 251 | 252 | if (obj) { 253 | [self setObject:obj forKey:key]; 254 | } else { 255 | [self removeObjectForKey:key]; 256 | } 257 | } 258 | 259 | - (id)objectForKeyedSubscript:(id)key 260 | { 261 | return [self objectForKey:key]; 262 | } 263 | 264 | @end 265 | 266 | @implementation NSObject (FSCalendarExtensions) 267 | 268 | #define IVAR_IMP(SET,GET,TYPE) \ 269 | - (void)fs_set##SET##Variable:(TYPE)value forKey:(NSString *)key \ 270 | { \ 271 | Ivar ivar = class_getInstanceVariable([self class], key.UTF8String); \ 272 | ((void (*)(id, Ivar, TYPE))object_setIvar)(self, ivar, value); \ 273 | } \ 274 | - (TYPE)fs_##GET##VariableForKey:(NSString *)key \ 275 | { \ 276 | Ivar ivar = class_getInstanceVariable([self class], key.UTF8String); \ 277 | ptrdiff_t offset = ivar_getOffset(ivar); \ 278 | unsigned char *bytes = (unsigned char *)(__bridge void *)self; \ 279 | TYPE value = *((TYPE *)(bytes+offset)); \ 280 | return value; \ 281 | } 282 | IVAR_IMP(Bool,bool,BOOL) 283 | IVAR_IMP(Float,float,CGFloat) 284 | IVAR_IMP(Integer,integer,NSInteger) 285 | IVAR_IMP(UnsignedInteger,unsignedInteger,NSUInteger) 286 | #undef IVAR_IMP 287 | 288 | - (void)fs_setVariable:(id)variable forKey:(NSString *)key 289 | { 290 | Ivar ivar = class_getInstanceVariable(self.class, key.UTF8String); 291 | object_setIvar(self, ivar, variable); 292 | } 293 | 294 | - (id)fs_variableForKey:(NSString *)key 295 | { 296 | Ivar ivar = class_getInstanceVariable(self.class, key.UTF8String); 297 | id variable = object_getIvar(self, ivar); 298 | return variable; 299 | } 300 | 301 | - (id)fs_performSelector:(SEL)selector withObjects:(nullable id)firstObject, ... 302 | { 303 | if (!selector) return nil; 304 | NSMethodSignature *signature = [self methodSignatureForSelector:selector]; 305 | if (!signature) return nil; 306 | NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; 307 | if (!invocation) return nil; 308 | invocation.target = self; 309 | invocation.selector = selector; 310 | 311 | // Parameters 312 | if (firstObject) { 313 | int index = 2; 314 | va_list args; 315 | va_start(args, firstObject); 316 | if (firstObject) { 317 | id obj = firstObject; 318 | do { 319 | const char *argType = [signature getArgumentTypeAtIndex:index]; 320 | if(!strcmp(argType, @encode(id))){ 321 | // object 322 | [invocation setArgument:&obj atIndex:index++]; 323 | } else { 324 | NSString *argTypeString = [NSString stringWithUTF8String:argType]; 325 | if ([argTypeString hasPrefix:@"{"] && [argTypeString hasSuffix:@"}"]) { 326 | // struct 327 | #define PARAM_STRUCT_TYPES(_type,_getter,_default) \ 328 | if (!strcmp(argType, @encode(_type))) { \ 329 | _type value = [obj respondsToSelector:@selector(_getter)]?[obj _getter]:_default; \ 330 | [invocation setArgument:&value atIndex:index]; \ 331 | } 332 | PARAM_STRUCT_TYPES(CGPoint, CGPointValue, CGPointZero) 333 | PARAM_STRUCT_TYPES(CGSize, CGSizeValue, CGSizeZero) 334 | PARAM_STRUCT_TYPES(CGRect, CGRectValue, CGRectZero) 335 | PARAM_STRUCT_TYPES(CGAffineTransform, CGAffineTransformValue, CGAffineTransformIdentity) 336 | PARAM_STRUCT_TYPES(CATransform3D, CATransform3DValue, CATransform3DIdentity) 337 | PARAM_STRUCT_TYPES(CGVector, CGVectorValue, CGVectorMake(0, 0)) 338 | PARAM_STRUCT_TYPES(UIEdgeInsets, UIEdgeInsetsValue, UIEdgeInsetsZero) 339 | PARAM_STRUCT_TYPES(UIOffset, UIOffsetValue, UIOffsetZero) 340 | PARAM_STRUCT_TYPES(NSRange, rangeValue, NSMakeRange(NSNotFound, 0)) 341 | 342 | #undef PARAM_STRUCT_TYPES 343 | index++; 344 | } else { 345 | // basic type 346 | #define PARAM_BASIC_TYPES(_type,_getter) \ 347 | if (!strcmp(argType, @encode(_type))) { \ 348 | _type value = [obj respondsToSelector:@selector(_getter)]?[obj _getter]:0; \ 349 | [invocation setArgument:&value atIndex:index]; \ 350 | } 351 | PARAM_BASIC_TYPES(BOOL, boolValue) 352 | PARAM_BASIC_TYPES(int, intValue) 353 | PARAM_BASIC_TYPES(unsigned int, unsignedIntValue) 354 | PARAM_BASIC_TYPES(char, charValue) 355 | PARAM_BASIC_TYPES(unsigned char, unsignedCharValue) 356 | PARAM_BASIC_TYPES(long, longValue) 357 | PARAM_BASIC_TYPES(unsigned long, unsignedLongValue) 358 | PARAM_BASIC_TYPES(long long, longLongValue) 359 | PARAM_BASIC_TYPES(unsigned long long, unsignedLongLongValue) 360 | PARAM_BASIC_TYPES(float, floatValue) 361 | PARAM_BASIC_TYPES(double, doubleValue) 362 | 363 | #undef PARAM_BASIC_TYPES 364 | index++; 365 | } 366 | } 367 | } while((obj = va_arg(args, id))); 368 | 369 | } 370 | va_end(args); 371 | [invocation retainArguments]; 372 | } 373 | 374 | // Execute 375 | [invocation invoke]; 376 | 377 | // Return 378 | const char *returnType = signature.methodReturnType; 379 | NSUInteger length = [signature methodReturnLength]; 380 | id returnValue; 381 | if (!strcmp(returnType, @encode(void))){ 382 | // void 383 | returnValue = nil; 384 | } else if(!strcmp(returnType, @encode(id))){ 385 | // id 386 | void *value; 387 | [invocation getReturnValue:&value]; 388 | returnValue = (__bridge id)(value); 389 | return returnValue; 390 | } else { 391 | NSString *returnTypeString = [NSString stringWithUTF8String:returnType]; 392 | if ([returnTypeString hasPrefix:@"{"] && [returnTypeString hasSuffix:@"}"]) { 393 | // struct 394 | #define RETURN_STRUCT_TYPES(_type) \ 395 | if (!strcmp(returnType, @encode(_type))) { \ 396 | _type value; \ 397 | [invocation getReturnValue:&value]; \ 398 | returnValue = [NSValue value:&value withObjCType:@encode(_type)]; \ 399 | } 400 | RETURN_STRUCT_TYPES(CGPoint) 401 | RETURN_STRUCT_TYPES(CGSize) 402 | RETURN_STRUCT_TYPES(CGRect) 403 | RETURN_STRUCT_TYPES(CGAffineTransform) 404 | RETURN_STRUCT_TYPES(CATransform3D) 405 | RETURN_STRUCT_TYPES(CGVector) 406 | RETURN_STRUCT_TYPES(UIEdgeInsets) 407 | RETURN_STRUCT_TYPES(UIOffset) 408 | RETURN_STRUCT_TYPES(NSRange) 409 | 410 | #undef RETURN_STRUCT_TYPES 411 | } else { 412 | // basic 413 | void *buffer = (void *)malloc(length); 414 | [invocation getReturnValue:buffer]; 415 | #define RETURN_BASIC_TYPES(_type) \ 416 | if (!strcmp(returnType, @encode(_type))) { \ 417 | returnValue = @(*((_type*)buffer)); \ 418 | } 419 | RETURN_BASIC_TYPES(BOOL) 420 | RETURN_BASIC_TYPES(int) 421 | RETURN_BASIC_TYPES(unsigned int) 422 | RETURN_BASIC_TYPES(char) 423 | RETURN_BASIC_TYPES(unsigned char) 424 | RETURN_BASIC_TYPES(long) 425 | RETURN_BASIC_TYPES(unsigned long) 426 | RETURN_BASIC_TYPES(long long) 427 | RETURN_BASIC_TYPES(unsigned long long) 428 | RETURN_BASIC_TYPES(float) 429 | RETURN_BASIC_TYPES(double) 430 | 431 | #undef RETURN_BASIC_TYPES 432 | free(buffer); 433 | } 434 | } 435 | return returnValue; 436 | } 437 | 438 | @end 439 | 440 | 441 | -------------------------------------------------------------------------------- /Demo/Pods/FSCalendar/FSCalendar/FSCalendarAppearance.m: -------------------------------------------------------------------------------- 1 | // 2 | // FSCalendarAppearance.m 3 | // Pods 4 | // 5 | // Created by DingWenchao on 6/29/15. 6 | // Copyright © 2016 Wenchao Ding. All rights reserved. 7 | // 8 | // https://github.com/WenchaoD 9 | // 10 | 11 | #import "FSCalendarAppearance.h" 12 | #import "FSCalendarDynamicHeader.h" 13 | #import "FSCalendarExtensions.h" 14 | 15 | @interface FSCalendarAppearance () 16 | 17 | @property (weak , nonatomic) FSCalendar *calendar; 18 | 19 | @property (strong, nonatomic) NSMutableDictionary *backgroundColors; 20 | @property (strong, nonatomic) NSMutableDictionary *titleColors; 21 | @property (strong, nonatomic) NSMutableDictionary *subtitleColors; 22 | @property (strong, nonatomic) NSMutableDictionary *borderColors; 23 | 24 | @end 25 | 26 | @implementation FSCalendarAppearance 27 | 28 | - (instancetype)init 29 | { 30 | self = [super init]; 31 | if (self) { 32 | 33 | _titleFont = [UIFont systemFontOfSize:FSCalendarStandardTitleTextSize]; 34 | _subtitleFont = [UIFont systemFontOfSize:FSCalendarStandardSubtitleTextSize]; 35 | _weekdayFont = [UIFont systemFontOfSize:FSCalendarStandardWeekdayTextSize]; 36 | _headerTitleFont = [UIFont systemFontOfSize:FSCalendarStandardHeaderTextSize]; 37 | 38 | _headerTitleColor = FSCalendarStandardTitleTextColor; 39 | _headerDateFormat = @"MMMM yyyy"; 40 | _headerMinimumDissolvedAlpha = 0.2; 41 | _weekdayTextColor = FSCalendarStandardTitleTextColor; 42 | _caseOptions = FSCalendarCaseOptionsHeaderUsesDefaultCase|FSCalendarCaseOptionsWeekdayUsesDefaultCase; 43 | 44 | _backgroundColors = [NSMutableDictionary dictionaryWithCapacity:5]; 45 | _backgroundColors[@(FSCalendarCellStateNormal)] = [UIColor clearColor]; 46 | _backgroundColors[@(FSCalendarCellStateSelected)] = FSCalendarStandardSelectionColor; 47 | _backgroundColors[@(FSCalendarCellStateDisabled)] = [UIColor clearColor]; 48 | _backgroundColors[@(FSCalendarCellStatePlaceholder)] = [UIColor clearColor]; 49 | _backgroundColors[@(FSCalendarCellStateToday)] = FSCalendarStandardTodayColor; 50 | 51 | _titleColors = [NSMutableDictionary dictionaryWithCapacity:5]; 52 | _titleColors[@(FSCalendarCellStateNormal)] = [UIColor blackColor]; 53 | _titleColors[@(FSCalendarCellStateSelected)] = [UIColor whiteColor]; 54 | _titleColors[@(FSCalendarCellStateDisabled)] = [UIColor grayColor]; 55 | _titleColors[@(FSCalendarCellStatePlaceholder)] = [UIColor lightGrayColor]; 56 | _titleColors[@(FSCalendarCellStateToday)] = [UIColor whiteColor]; 57 | 58 | _subtitleColors = [NSMutableDictionary dictionaryWithCapacity:5]; 59 | _subtitleColors[@(FSCalendarCellStateNormal)] = [UIColor darkGrayColor]; 60 | _subtitleColors[@(FSCalendarCellStateSelected)] = [UIColor whiteColor]; 61 | _subtitleColors[@(FSCalendarCellStateDisabled)] = [UIColor lightGrayColor]; 62 | _subtitleColors[@(FSCalendarCellStatePlaceholder)] = [UIColor lightGrayColor]; 63 | _subtitleColors[@(FSCalendarCellStateToday)] = [UIColor whiteColor]; 64 | 65 | _borderColors[@(FSCalendarCellStateSelected)] = [UIColor clearColor]; 66 | _borderColors[@(FSCalendarCellStateNormal)] = [UIColor clearColor]; 67 | 68 | _borderRadius = 1.0; 69 | _eventDefaultColor = FSCalendarStandardEventDotColor; 70 | _eventSelectionColor = FSCalendarStandardEventDotColor; 71 | 72 | _borderColors = [NSMutableDictionary dictionaryWithCapacity:2]; 73 | 74 | #if TARGET_INTERFACE_BUILDER 75 | _fakeEventDots = YES; 76 | #endif 77 | 78 | } 79 | return self; 80 | } 81 | 82 | - (void)setTitleFont:(UIFont *)titleFont 83 | { 84 | if (![_titleFont isEqual:titleFont]) { 85 | _titleFont = titleFont; 86 | [self.calendar configureAppearance]; 87 | } 88 | } 89 | 90 | - (void)setSubtitleFont:(UIFont *)subtitleFont 91 | { 92 | if (![_subtitleFont isEqual:subtitleFont]) { 93 | _subtitleFont = subtitleFont; 94 | [self.calendar configureAppearance]; 95 | } 96 | } 97 | 98 | - (void)setWeekdayFont:(UIFont *)weekdayFont 99 | { 100 | if (![_weekdayFont isEqual:weekdayFont]) { 101 | _weekdayFont = weekdayFont; 102 | [self.calendar configureAppearance]; 103 | } 104 | } 105 | 106 | - (void)setHeaderTitleFont:(UIFont *)headerTitleFont 107 | { 108 | if (![_headerTitleFont isEqual:headerTitleFont]) { 109 | _headerTitleFont = headerTitleFont; 110 | [self.calendar configureAppearance]; 111 | } 112 | } 113 | 114 | - (void)setTitleOffset:(CGPoint)titleOffset 115 | { 116 | if (!CGPointEqualToPoint(_titleOffset, titleOffset)) { 117 | _titleOffset = titleOffset; 118 | [_calendar.visibleCells makeObjectsPerformSelector:@selector(setNeedsLayout)]; 119 | } 120 | } 121 | 122 | - (void)setSubtitleOffset:(CGPoint)subtitleOffset 123 | { 124 | if (!CGPointEqualToPoint(_subtitleOffset, subtitleOffset)) { 125 | _subtitleOffset = subtitleOffset; 126 | [_calendar.visibleCells makeObjectsPerformSelector:@selector(setNeedsLayout)]; 127 | } 128 | } 129 | 130 | - (void)setImageOffset:(CGPoint)imageOffset 131 | { 132 | if (!CGPointEqualToPoint(_imageOffset, imageOffset)) { 133 | _imageOffset = imageOffset; 134 | [_calendar.visibleCells makeObjectsPerformSelector:@selector(setNeedsLayout)]; 135 | } 136 | } 137 | 138 | - (void)setEventOffset:(CGPoint)eventOffset 139 | { 140 | if (!CGPointEqualToPoint(_eventOffset, eventOffset)) { 141 | _eventOffset = eventOffset; 142 | [_calendar.visibleCells makeObjectsPerformSelector:@selector(setNeedsLayout)]; 143 | } 144 | } 145 | 146 | - (void)setTitleDefaultColor:(UIColor *)color 147 | { 148 | if (color) { 149 | _titleColors[@(FSCalendarCellStateNormal)] = color; 150 | } else { 151 | [_titleColors removeObjectForKey:@(FSCalendarCellStateNormal)]; 152 | } 153 | [self.calendar configureAppearance]; 154 | } 155 | 156 | - (UIColor *)titleDefaultColor 157 | { 158 | return _titleColors[@(FSCalendarCellStateNormal)]; 159 | } 160 | 161 | - (void)setTitleSelectionColor:(UIColor *)color 162 | { 163 | if (color) { 164 | _titleColors[@(FSCalendarCellStateSelected)] = color; 165 | } else { 166 | [_titleColors removeObjectForKey:@(FSCalendarCellStateSelected)]; 167 | } 168 | [self.calendar configureAppearance]; 169 | } 170 | 171 | - (UIColor *)titleSelectionColor 172 | { 173 | return _titleColors[@(FSCalendarCellStateSelected)]; 174 | } 175 | 176 | - (void)setTitleTodayColor:(UIColor *)color 177 | { 178 | if (color) { 179 | _titleColors[@(FSCalendarCellStateToday)] = color; 180 | } else { 181 | [_titleColors removeObjectForKey:@(FSCalendarCellStateToday)]; 182 | } 183 | [self.calendar configureAppearance]; 184 | } 185 | 186 | - (UIColor *)titleTodayColor 187 | { 188 | return _titleColors[@(FSCalendarCellStateToday)]; 189 | } 190 | 191 | - (void)setTitlePlaceholderColor:(UIColor *)color 192 | { 193 | if (color) { 194 | _titleColors[@(FSCalendarCellStatePlaceholder)] = color; 195 | } else { 196 | [_titleColors removeObjectForKey:@(FSCalendarCellStatePlaceholder)]; 197 | } 198 | [self.calendar configureAppearance]; 199 | } 200 | 201 | - (UIColor *)titlePlaceholderColor 202 | { 203 | return _titleColors[@(FSCalendarCellStatePlaceholder)]; 204 | } 205 | 206 | - (void)setTitleWeekendColor:(UIColor *)color 207 | { 208 | if (color) { 209 | _titleColors[@(FSCalendarCellStateWeekend)] = color; 210 | } else { 211 | [_titleColors removeObjectForKey:@(FSCalendarCellStateWeekend)]; 212 | } 213 | [self.calendar configureAppearance]; 214 | } 215 | 216 | - (UIColor *)titleWeekendColor 217 | { 218 | return _titleColors[@(FSCalendarCellStateWeekend)]; 219 | } 220 | 221 | - (void)setSubtitleDefaultColor:(UIColor *)color 222 | { 223 | if (color) { 224 | _subtitleColors[@(FSCalendarCellStateNormal)] = color; 225 | } else { 226 | [_subtitleColors removeObjectForKey:@(FSCalendarCellStateNormal)]; 227 | } 228 | [self.calendar configureAppearance]; 229 | } 230 | 231 | -(UIColor *)subtitleDefaultColor 232 | { 233 | return _subtitleColors[@(FSCalendarCellStateNormal)]; 234 | } 235 | 236 | - (void)setSubtitleSelectionColor:(UIColor *)color 237 | { 238 | if (color) { 239 | _subtitleColors[@(FSCalendarCellStateSelected)] = color; 240 | } else { 241 | [_subtitleColors removeObjectForKey:@(FSCalendarCellStateSelected)]; 242 | } 243 | [self.calendar configureAppearance]; 244 | } 245 | 246 | - (UIColor *)subtitleSelectionColor 247 | { 248 | return _subtitleColors[@(FSCalendarCellStateSelected)]; 249 | } 250 | 251 | - (void)setSubtitleTodayColor:(UIColor *)color 252 | { 253 | if (color) { 254 | _subtitleColors[@(FSCalendarCellStateToday)] = color; 255 | } else { 256 | [_subtitleColors removeObjectForKey:@(FSCalendarCellStateToday)]; 257 | } 258 | [self.calendar configureAppearance]; 259 | } 260 | 261 | - (UIColor *)subtitleTodayColor 262 | { 263 | return _subtitleColors[@(FSCalendarCellStateToday)]; 264 | } 265 | 266 | - (void)setSubtitlePlaceholderColor:(UIColor *)color 267 | { 268 | if (color) { 269 | _subtitleColors[@(FSCalendarCellStatePlaceholder)] = color; 270 | } else { 271 | [_subtitleColors removeObjectForKey:@(FSCalendarCellStatePlaceholder)]; 272 | } 273 | [self.calendar configureAppearance]; 274 | } 275 | 276 | - (UIColor *)subtitlePlaceholderColor 277 | { 278 | return _subtitleColors[@(FSCalendarCellStatePlaceholder)]; 279 | } 280 | 281 | - (void)setSubtitleWeekendColor:(UIColor *)color 282 | { 283 | if (color) { 284 | _subtitleColors[@(FSCalendarCellStateWeekend)] = color; 285 | } else { 286 | [_subtitleColors removeObjectForKey:@(FSCalendarCellStateWeekend)]; 287 | } 288 | [self.calendar configureAppearance]; 289 | } 290 | 291 | - (UIColor *)subtitleWeekendColor 292 | { 293 | return _subtitleColors[@(FSCalendarCellStateWeekend)]; 294 | } 295 | 296 | - (void)setSelectionColor:(UIColor *)color 297 | { 298 | if (color) { 299 | _backgroundColors[@(FSCalendarCellStateSelected)] = color; 300 | } else { 301 | [_backgroundColors removeObjectForKey:@(FSCalendarCellStateSelected)]; 302 | } 303 | [self.calendar configureAppearance]; 304 | } 305 | 306 | - (UIColor *)selectionColor 307 | { 308 | return _backgroundColors[@(FSCalendarCellStateSelected)]; 309 | } 310 | 311 | - (void)setTodayColor:(UIColor *)todayColor 312 | { 313 | if (todayColor) { 314 | _backgroundColors[@(FSCalendarCellStateToday)] = todayColor; 315 | } else { 316 | [_backgroundColors removeObjectForKey:@(FSCalendarCellStateToday)]; 317 | } 318 | [self.calendar configureAppearance]; 319 | } 320 | 321 | - (UIColor *)todayColor 322 | { 323 | return _backgroundColors[@(FSCalendarCellStateToday)]; 324 | } 325 | 326 | - (void)setTodaySelectionColor:(UIColor *)todaySelectionColor 327 | { 328 | if (todaySelectionColor) { 329 | _backgroundColors[@(FSCalendarCellStateToday|FSCalendarCellStateSelected)] = todaySelectionColor; 330 | } else { 331 | [_backgroundColors removeObjectForKey:@(FSCalendarCellStateToday|FSCalendarCellStateSelected)]; 332 | } 333 | [self.calendar configureAppearance]; 334 | } 335 | 336 | - (UIColor *)todaySelectionColor 337 | { 338 | return _backgroundColors[@(FSCalendarCellStateToday|FSCalendarCellStateSelected)]; 339 | } 340 | 341 | - (void)setEventDefaultColor:(UIColor *)eventDefaultColor 342 | { 343 | if (![_eventDefaultColor isEqual:eventDefaultColor]) { 344 | _eventDefaultColor = eventDefaultColor; 345 | [self.calendar configureAppearance]; 346 | } 347 | } 348 | 349 | - (void)setBorderDefaultColor:(UIColor *)color 350 | { 351 | if (color) { 352 | _borderColors[@(FSCalendarCellStateNormal)] = color; 353 | } else { 354 | [_borderColors removeObjectForKey:@(FSCalendarCellStateNormal)]; 355 | } 356 | [self.calendar configureAppearance]; 357 | } 358 | 359 | - (UIColor *)borderDefaultColor 360 | { 361 | return _borderColors[@(FSCalendarCellStateNormal)]; 362 | } 363 | 364 | - (void)setBorderSelectionColor:(UIColor *)color 365 | { 366 | if (color) { 367 | _borderColors[@(FSCalendarCellStateSelected)] = color; 368 | } else { 369 | [_borderColors removeObjectForKey:@(FSCalendarCellStateSelected)]; 370 | } 371 | [self.calendar configureAppearance]; 372 | } 373 | 374 | - (UIColor *)borderSelectionColor 375 | { 376 | return _borderColors[@(FSCalendarCellStateSelected)]; 377 | } 378 | 379 | - (void)setBorderRadius:(CGFloat)borderRadius 380 | { 381 | borderRadius = MAX(0.0, borderRadius); 382 | borderRadius = MIN(1.0, borderRadius); 383 | if (_borderRadius != borderRadius) { 384 | _borderRadius = borderRadius; 385 | [self.calendar configureAppearance]; 386 | } 387 | } 388 | 389 | - (void)setWeekdayTextColor:(UIColor *)weekdayTextColor 390 | { 391 | if (![_weekdayTextColor isEqual:weekdayTextColor]) { 392 | _weekdayTextColor = weekdayTextColor; 393 | [self.calendar configureAppearance]; 394 | } 395 | } 396 | 397 | - (void)setHeaderTitleColor:(UIColor *)color 398 | { 399 | if (![_headerTitleColor isEqual:color]) { 400 | _headerTitleColor = color; 401 | [self.calendar configureAppearance]; 402 | } 403 | } 404 | 405 | - (void)setHeaderMinimumDissolvedAlpha:(CGFloat)headerMinimumDissolvedAlpha 406 | { 407 | if (_headerMinimumDissolvedAlpha != headerMinimumDissolvedAlpha) { 408 | _headerMinimumDissolvedAlpha = headerMinimumDissolvedAlpha; 409 | [self.calendar configureAppearance]; 410 | } 411 | } 412 | 413 | - (void)setHeaderDateFormat:(NSString *)headerDateFormat 414 | { 415 | if (![_headerDateFormat isEqual:headerDateFormat]) { 416 | _headerDateFormat = headerDateFormat; 417 | [self.calendar configureAppearance]; 418 | } 419 | } 420 | 421 | - (void)setCaseOptions:(FSCalendarCaseOptions)caseOptions 422 | { 423 | if (_caseOptions != caseOptions) { 424 | _caseOptions = caseOptions; 425 | [self.calendar configureAppearance]; 426 | } 427 | } 428 | 429 | - (void)setSeparators:(FSCalendarSeparators)separators 430 | { 431 | if (_separators != separators) { 432 | _separators = separators; 433 | [_calendar.collectionView.collectionViewLayout invalidateLayout]; 434 | } 435 | } 436 | 437 | @end 438 | 439 | 440 | @implementation FSCalendarAppearance (Deprecated) 441 | 442 | - (void)setUseVeryShortWeekdaySymbols:(BOOL)useVeryShortWeekdaySymbols 443 | { 444 | _caseOptions &= 15; 445 | self.caseOptions |= (useVeryShortWeekdaySymbols*FSCalendarCaseOptionsWeekdayUsesSingleUpperCase); 446 | } 447 | 448 | - (BOOL)useVeryShortWeekdaySymbols 449 | { 450 | return (_caseOptions & (15<<4) ) == FSCalendarCaseOptionsWeekdayUsesSingleUpperCase; 451 | } 452 | 453 | - (void)setTitleVerticalOffset:(CGFloat)titleVerticalOffset 454 | { 455 | self.titleOffset = CGPointMake(0, titleVerticalOffset); 456 | } 457 | 458 | - (CGFloat)titleVerticalOffset 459 | { 460 | return self.titleOffset.y; 461 | } 462 | 463 | - (void)setSubtitleVerticalOffset:(CGFloat)subtitleVerticalOffset 464 | { 465 | self.subtitleOffset = CGPointMake(0, subtitleVerticalOffset); 466 | } 467 | 468 | - (CGFloat)subtitleVerticalOffset 469 | { 470 | return self.subtitleOffset.y; 471 | } 472 | 473 | - (void)setEventColor:(UIColor *)eventColor 474 | { 475 | self.eventDefaultColor = eventColor; 476 | } 477 | 478 | - (UIColor *)eventColor 479 | { 480 | return self.eventDefaultColor; 481 | } 482 | 483 | - (void)setCellShape:(FSCalendarCellShape)cellShape 484 | { 485 | self.borderRadius = 1-cellShape; 486 | } 487 | 488 | - (FSCalendarCellShape)cellShape 489 | { 490 | return self.borderRadius==1.0?FSCalendarCellShapeCircle:FSCalendarCellShapeRectangle; 491 | } 492 | 493 | - (void)setTitleTextSize:(CGFloat)titleTextSize 494 | { 495 | self.titleFont = [UIFont fontWithName:self.titleFont.fontName size:titleTextSize]; 496 | } 497 | 498 | - (void)setSubtitleTextSize:(CGFloat)subtitleTextSize 499 | { 500 | self.subtitleFont = [UIFont fontWithName:self.subtitleFont.fontName size:subtitleTextSize]; 501 | } 502 | 503 | - (void)setWeekdayTextSize:(CGFloat)weekdayTextSize 504 | { 505 | self.weekdayFont = [UIFont fontWithName:self.weekdayFont.fontName size:weekdayTextSize]; 506 | } 507 | 508 | - (void)setHeaderTitleTextSize:(CGFloat)headerTitleTextSize 509 | { 510 | self.headerTitleFont = [UIFont fontWithName:self.headerTitleFont.fontName size:headerTitleTextSize]; 511 | } 512 | 513 | - (void)invalidateAppearance 514 | { 515 | [self.calendar configureAppearance]; 516 | } 517 | 518 | - (void)setAdjustsFontSizeToFitContentSize:(BOOL)adjustsFontSizeToFitContentSize {} 519 | - (BOOL)adjustsFontSizeToFitContentSize { return YES; } 520 | 521 | @end 522 | 523 | 524 | --------------------------------------------------------------------------------