diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..430da44 Binary files /dev/null and b/.DS_Store differ diff --git a/.gitignore b/.gitignore index 894a44c..8b460f2 100644 --- a/.gitignore +++ b/.gitignore @@ -102,3 +102,8 @@ venv.bak/ # mypy .mypy_cache/ + +myvenv +db.sqlite3 +/static +.DS_Store diff --git a/Podfile b/Podfile new file mode 100644 index 0000000..6f7399a --- /dev/null +++ b/Podfile @@ -0,0 +1,21 @@ +project 'pro-service.xcodeproj' + +platform :ios, '10.0' +use_frameworks! + +target 'pro-service' do + + pod 'FSCalendar+Persian' + pod 'SPStorkController' + + target 'pro-serviceTests' do + inherit! :search_paths + # Pods for testing + end + + target 'pro-serviceUITests' do + inherit! :search_paths + # Pods for testing + end + +end diff --git a/Podfile.lock b/Podfile.lock new file mode 100644 index 0000000..e38b46d --- /dev/null +++ b/Podfile.lock @@ -0,0 +1,20 @@ +PODS: + - "FSCalendar+Persian (2.9.2)" + - SPStorkController (1.6.5) + +DEPENDENCIES: + - "FSCalendar+Persian" + - SPStorkController + +SPEC REPOS: + https://github.com/cocoapods/specs.git: + - "FSCalendar+Persian" + - SPStorkController + +SPEC CHECKSUMS: + "FSCalendar+Persian": fc5b323015db8a93c48c61b9c0c59f3a705d8297 + SPStorkController: f74a60dbcd3c35180c996688873f6eadac839642 + +PODFILE CHECKSUM: 388c0f1a2c275c2cee70116388b673441083cdae + +COCOAPODS: 1.5.2 diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendar+Deprecated.m b/Pods/FSCalendar+Persian/FSCalendar/FSCalendar+Deprecated.m new file mode 100644 index 0000000..96df1e1 --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendar+Deprecated.m @@ -0,0 +1,252 @@ +// +// FSCalendar+Deprecated.m +// FSCalendar +// +// Created by dingwenchao on 4/29/16. +// Copyright © 2016 Wenchao Ding. All rights reserved. +// + +#import "FSCalendar.h" +#import "NSString+Category.h" +#import "FSCalendarExtensions.h" +#import "FSCalendarDynamicHeader.h" + +#pragma mark - Deprecate + +@implementation FSCalendar (Deprecated) + +// identifier, lineHeightMultiplier; + +- (void)setShowsPlaceholders:(BOOL)showsPlaceholders +{ + self.placeholderType = showsPlaceholders ? FSCalendarPlaceholderTypeFillSixRows : FSCalendarPlaceholderTypeNone; +} + +- (BOOL)showsPlaceholders +{ + return self.placeholderType == FSCalendarPlaceholderTypeFillSixRows; +} + +#pragma mark - Public methods + +- (NSInteger)yearOfDate:(NSDate *)date +{ + if (!date) return NSNotFound; + NSDateComponents *component = [self.gregorian components:NSCalendarUnitYear fromDate:date]; + return component.year; +} + +- (NSInteger)monthOfDate:(NSDate *)date +{ + if (!date) return NSNotFound; + NSDateComponents *component = [self.gregorian components:NSCalendarUnitMonth + fromDate:date]; + return component.month; +} + +- (NSInteger)dayOfDate:(NSDate *)date +{ + if (!date) return NSNotFound; + NSDateComponents *component = [self.gregorian components:NSCalendarUnitDay + fromDate:date]; + return component.day; +} + +- (NSInteger)weekdayOfDate:(NSDate *)date +{ + if (!date) return NSNotFound; + NSDateComponents *component = [self.gregorian components:NSCalendarUnitWeekday fromDate:date]; + return component.weekday; +} + +- (NSInteger)weekOfDate:(NSDate *)date +{ + if (!date) return NSNotFound; + NSDateComponents *component = [self.gregorian components:NSCalendarUnitWeekOfYear fromDate:date]; + return component.weekOfYear; +} + +- (NSDate *)dateByIgnoringTimeComponentsOfDate:(NSDate *)date +{ + if (!date) return nil; + NSDateComponents *components = [self.gregorian components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:date]; + return [self.gregorian dateFromComponents:components]; +} + +- (NSDate *)tomorrowOfDate:(NSDate *)date +{ + if (!date) return nil; + NSDateComponents *components = [self.gregorian components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour fromDate:date]; + components.day++; + components.hour = FSCalendarDefaultHourComponent; + return [self.gregorian dateFromComponents:components]; +} + +- (NSDate *)yesterdayOfDate:(NSDate *)date +{ + if (!date) return nil; + NSDateComponents *components = [self.gregorian components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour fromDate:date]; + components.day--; + components.hour = FSCalendarDefaultHourComponent; + return [self.gregorian dateFromComponents:components]; +} + +- (NSDate *)dateWithYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day +{ + NSDateComponents *components = self.components; + components.year = year; + components.month = month; + components.day = day; + components.hour = FSCalendarDefaultHourComponent; + NSDate *date = [self.gregorian dateFromComponents:components]; + components.year = NSIntegerMax; + components.month = NSIntegerMax; + components.day = NSIntegerMax; + components.hour = NSIntegerMax; + return date; +} + +- (NSDate *)dateByAddingYears:(NSInteger)years toDate:(NSDate *)date +{ + if (!date) return nil; + NSDateComponents *components = self.components; + components.year = years; + NSDate *d = [self.gregorian dateByAddingComponents:components toDate:date options:0]; + components.year = NSIntegerMax; + return d; +} + +- (NSDate *)dateBySubstractingYears:(NSInteger)years fromDate:(NSDate *)date +{ + if (!date) return nil; + return [self dateByAddingYears:-years toDate:date]; +} + +- (NSDate *)dateByAddingMonths:(NSInteger)months toDate:(NSDate *)date +{ + if (!date) return nil; + NSDateComponents *components = self.components; + components.month = months; + NSDate *d = [self.gregorian dateByAddingComponents:components toDate:date options:0]; + components.month = NSIntegerMax; + return d; +} + +- (NSDate *)dateBySubstractingMonths:(NSInteger)months fromDate:(NSDate *)date +{ + return [self dateByAddingMonths:-months toDate:date]; +} + +- (NSDate *)dateByAddingWeeks:(NSInteger)weeks toDate:(NSDate *)date +{ + if (!date) return nil; + NSDateComponents *components = self.components; + components.weekOfYear = weeks; + NSDate *d = [self.gregorian dateByAddingComponents:components toDate:date options:0]; + components.weekOfYear = NSIntegerMax; + return d; +} + +- (NSDate *)dateBySubstractingWeeks:(NSInteger)weeks fromDate:(NSDate *)date +{ + return [self dateByAddingWeeks:-weeks toDate:date]; +} + +- (NSDate *)dateByAddingDays:(NSInteger)days toDate:(NSDate *)date +{ + if (!date) return nil; + NSDateComponents *components = self.components; + components.day = days; + NSDate *d = [self.gregorian dateByAddingComponents:components toDate:date options:0]; + components.day = NSIntegerMax; + return d; +} + +- (NSDate *)dateBySubstractingDays:(NSInteger)days fromDate:(NSDate *)date +{ + return [self dateByAddingDays:-days toDate:date]; +} + +- (NSInteger)yearsFromDate:(NSDate *)fromDate toDate:(NSDate *)toDate +{ + NSDateComponents *components = [self.gregorian components:NSCalendarUnitYear + fromDate:fromDate + toDate:toDate + options:0]; + return components.year; +} + +- (NSInteger)monthsFromDate:(NSDate *)fromDate toDate:(NSDate *)toDate +{ + NSDateComponents *components = [self.gregorian components:NSCalendarUnitMonth + fromDate:fromDate + toDate:toDate + options:0]; + return components.month; +} + +- (NSInteger)weeksFromDate:(NSDate *)fromDate toDate:(NSDate *)toDate +{ + NSDateComponents *components = [self.gregorian components:NSCalendarUnitWeekOfYear + fromDate:fromDate + toDate:toDate + options:0]; + return components.weekOfYear; +} + +- (NSInteger)daysFromDate:(NSDate *)fromDate toDate:(NSDate *)toDate +{ + NSDateComponents *components = [self.gregorian components:NSCalendarUnitDay + fromDate:fromDate + toDate:toDate + options:0]; + return components.day; +} + +- (BOOL)isDate:(NSDate *)date1 equalToDate:(NSDate *)date2 toCalendarUnit:(FSCalendarUnit)unit +{ + switch (unit) { + case FSCalendarUnitMonth: + return [self.gregorian isDate:date1 equalToDate:date2 toUnitGranularity:NSCalendarUnitMonth]; + case FSCalendarUnitWeekOfYear: + return [self.gregorian isDate:date1 equalToDate:date2 toUnitGranularity:NSCalendarUnitYear]; + case FSCalendarUnitDay: + return [self.gregorian isDate:date1 inSameDayAsDate:date2]; + } + return NO; +} + +- (BOOL)isDateInToday:(NSDate *)date +{ + return [self isDate:date equalToDate:[NSDate date] toCalendarUnit:FSCalendarUnitDay]; +} + +- (void)setIdentifier:(NSString *)identifier +{ + NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:identifier]; + [self setValue:gregorian forKey:@"gregorian"]; + [self fs_performSelector:NSSelectorFromString(@"invalidateDateTools") withObjects:nil, nil]; + + if ([[self valueForKey:@"hasValidateVisibleLayout"] boolValue]) { + [self reloadData]; + } + [self fs_setVariable:[self.gregorian dateBySettingHour:0 minute:0 second:0 ofDate:self.minimumDate options:0] forKey:@"_minimumDate"]; + [self fs_setVariable:[self.gregorian dateBySettingHour:0 minute:0 second:0 ofDate:self.currentPage options:0] forKey:@"_currentPage"]; + [self fs_performSelector:NSSelectorFromString(@"scrollToPageForDate:animated") withObjects:self.today, @NO, nil]; + if ([identifier isRTLCalendar]) { + //TODO: Totall view did change the direction. + [self setTransform:CGAffineTransformMakeScale(-1, 1)]; + } +} + +- (NSString *)identifier +{ + return self.gregorian.calendarIdentifier; +} + +- (void)setLineHeightMultiplier:(CGFloat)lineHeightMultiplier +{ + self.rowHeight = FSCalendarStandardRowHeight*MAX(1, FSCalendarDeviceIsIPad*1.5); +} + +@end diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendar.h b/Pods/FSCalendar+Persian/FSCalendar/FSCalendar.h new file mode 100644 index 0000000..4d7d7d9 --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendar.h @@ -0,0 +1,604 @@ +// +// FSCalendar.h +// FSCalendar +// +// Created by Wenchao Ding on 29/1/15. +// Copyright © 2016 Wenchao Ding. All rights reserved. +// +// https://github.com/Husseinhj +// +// FSCalendar is a superior awesome calendar control with high performance, high customizablility and very simple usage. +// +// @see FSCalendarDataSource +// @see FSCalendarDelegate +// @see FSCalendarDelegateAppearance +// @see FSCalendarAppearance +// + +#import +#import "FSCalendarAppearance.h" +#import "FSCalendarConstants.h" +#import "FSCalendarCell.h" +#import "FSCalendarWeekdayView.h" +#import "FSCalendarHeaderView.h" + +//! Project version number for FSCalendar. +FOUNDATION_EXPORT double FSCalendarVersionNumber; + +//! Project version string for FSCalendar. +FOUNDATION_EXPORT const unsigned char FSCalendarVersionString[]; + +typedef NS_ENUM(NSUInteger, FSCalendarScope) { + FSCalendarScopeMonth, + FSCalendarScopeWeek +}; + +typedef NS_ENUM(NSUInteger, FSCalendarScrollDirection) { + FSCalendarScrollDirectionVertical, + FSCalendarScrollDirectionHorizontal +}; + +typedef NS_ENUM(NSUInteger, FSCalendarPlaceholderType) { + FSCalendarPlaceholderTypeNone = 0, + FSCalendarPlaceholderTypeFillHeadTail = 1, + FSCalendarPlaceholderTypeFillSixRows = 2 +}; + +typedef NS_ENUM(NSUInteger, FSCalendarMonthPosition) { + FSCalendarMonthPositionPrevious, + FSCalendarMonthPositionCurrent, + FSCalendarMonthPositionNext, + + FSCalendarMonthPositionNotFound = NSNotFound +}; + +NS_ASSUME_NONNULL_BEGIN + +@class FSCalendar; + +/** + * FSCalendarDataSource is a source set of FSCalendar. The basic role is to provide event、subtitle and min/max day to display, or customized day cell for the calendar. + */ +@protocol FSCalendarDataSource + +@optional + +/** + * Asks the dataSource for a title for the specific date as a replacement of the day text + */ +- (nullable NSString *)calendar:(FSCalendar *)calendar titleForDate:(NSDate *)date; + +/** + * Asks the dataSource for a subtitle for the specific date under the day text. + */ +- (nullable NSString *)calendar:(FSCalendar *)calendar subtitleForDate:(NSDate *)date; + +/** + * Asks the dataSource for an image for the specific date. + */ +- (nullable UIImage *)calendar:(FSCalendar *)calendar imageForDate:(NSDate *)date; + +/** + * Asks the dataSource the minimum date to display. + */ +- (NSDate *)minimumDateForCalendar:(FSCalendar *)calendar; + +/** + * Asks the dataSource the maximum date to display. + */ +- (NSDate *)maximumDateForCalendar:(FSCalendar *)calendar; + +/** + * Asks the data source for a cell to insert in a particular data of the calendar. + */ +- (__kindof FSCalendarCell *)calendar:(FSCalendar *)calendar cellForDate:(NSDate *)date atMonthPosition:(FSCalendarMonthPosition)position; + +/** + * Asks the dataSource the number of event dots for a specific date. + * + * @see + * - (UIColor *)calendar:(FSCalendar *)calendar appearance:(FSCalendarAppearance *)appearance eventColorForDate:(NSDate *)date; + * - (NSArray *)calendar:(FSCalendar *)calendar appearance:(FSCalendarAppearance *)appearance eventColorsForDate:(NSDate *)date; + */ +- (NSInteger)calendar:(FSCalendar *)calendar numberOfEventsForDate:(NSDate *)date; + +/** + * This function is deprecated + */ +- (BOOL)calendar:(FSCalendar *)calendar hasEventForDate:(NSDate *)date FSCalendarDeprecated(-calendar:numberOfEventsForDate:); + +@end + + +/** + * The delegate of a FSCalendar object must adopt the FSCalendarDelegate protocol. The optional methods of FSCalendarDelegate manage selections、 user events and help to manager the frame of the calendar. + */ +@protocol FSCalendarDelegate + +@optional + +/** + Asks the delegate whether the specific date is allowed to be selected by tapping. + */ +- (BOOL)calendar:(FSCalendar *)calendar shouldSelectDate:(NSDate *)date atMonthPosition:(FSCalendarMonthPosition)monthPosition; + +/** + Tells the delegate a date in the calendar is selected by tapping. + */ +- (void)calendar:(FSCalendar *)calendar didSelectDate:(NSDate *)date atMonthPosition:(FSCalendarMonthPosition)monthPosition; + +/** + Asks the delegate whether the specific date is allowed to be deselected by tapping. + */ +- (BOOL)calendar:(FSCalendar *)calendar shouldDeselectDate:(NSDate *)date atMonthPosition:(FSCalendarMonthPosition)monthPosition; + +/** + Tells the delegate a date in the calendar is deselected by tapping. + */ +- (void)calendar:(FSCalendar *)calendar didDeselectDate:(NSDate *)date atMonthPosition:(FSCalendarMonthPosition)monthPosition; + + +/** + Tells the delegate the calendar is about to change the bounding rect. + */ +- (void)calendar:(FSCalendar *)calendar boundingRectWillChange:(CGRect)bounds animated:(BOOL)animated; + +/** + Tells the delegate that the specified cell is about to be displayed in the calendar. + */ +- (void)calendar:(FSCalendar *)calendar willDisplayCell:(FSCalendarCell *)cell forDate:(NSDate *)date atMonthPosition:(FSCalendarMonthPosition)monthPosition; + +/** + Tells the delegate the calendar is about to change the current page. + */ +- (void)calendarCurrentPageDidChange:(FSCalendar *)calendar; + +/** + These functions are deprecated + */ +- (void)calendarCurrentScopeWillChange:(FSCalendar *)calendar animated:(BOOL)animated FSCalendarDeprecated(-calendar:boundingRectWillChange:animated:); +- (void)calendarCurrentMonthDidChange:(FSCalendar *)calendar FSCalendarDeprecated(-calendarCurrentPageDidChange:); +- (BOOL)calendar:(FSCalendar *)calendar shouldSelectDate:(NSDate *)date FSCalendarDeprecated(-calendar:shouldSelectDate:atMonthPosition:);- (void)calendar:(FSCalendar *)calendar didSelectDate:(NSDate *)date FSCalendarDeprecated(-calendar:didSelectDate:atMonthPosition:); +- (BOOL)calendar:(FSCalendar *)calendar shouldDeselectDate:(NSDate *)date FSCalendarDeprecated(-calendar:shouldDeselectDate:atMonthPosition:); +- (void)calendar:(FSCalendar *)calendar didDeselectDate:(NSDate *)date FSCalendarDeprecated(-calendar:didDeselectDate:atMonthPosition:); + +@end + +/** + * FSCalendarDelegateAppearance determines the fonts and colors of components in the calendar, but more specificly. Basically, if you need to make a global customization of appearance of the calendar, use FSCalendarAppearance. But if you need different appearance for different days, use FSCalendarDelegateAppearance. + * + * @see FSCalendarAppearance + */ +@protocol FSCalendarDelegateAppearance + +@optional + +/** + * Asks the delegate for a fill color in unselected state for the specific date. + */ +- (nullable UIColor *)calendar:(FSCalendar *)calendar appearance:(FSCalendarAppearance *)appearance fillDefaultColorForDate:(NSDate *)date; + +/** + * Asks the delegate for a fill color in selected state for the specific date. + */ +- (nullable UIColor *)calendar:(FSCalendar *)calendar appearance:(FSCalendarAppearance *)appearance fillSelectionColorForDate:(NSDate *)date; + +/** + * Asks the delegate for day text color in unselected state for the specific date. + */ +- (nullable UIColor *)calendar:(FSCalendar *)calendar appearance:(FSCalendarAppearance *)appearance titleDefaultColorForDate:(NSDate *)date; + +/** + * Asks the delegate for day text color in selected state for the specific date. + */ +- (nullable UIColor *)calendar:(FSCalendar *)calendar appearance:(FSCalendarAppearance *)appearance titleSelectionColorForDate:(NSDate *)date; + +/** + * Asks the delegate for subtitle text color in unselected state for the specific date. + */ +- (nullable UIColor *)calendar:(FSCalendar *)calendar appearance:(FSCalendarAppearance *)appearance subtitleDefaultColorForDate:(NSDate *)date; + +/** + * Asks the delegate for subtitle text color in selected state for the specific date. + */ +- (nullable UIColor *)calendar:(FSCalendar *)calendar appearance:(FSCalendarAppearance *)appearance subtitleSelectionColorForDate:(NSDate *)date; + +/** + * Asks the delegate for event colors for the specific date. + */ +- (nullable NSArray *)calendar:(FSCalendar *)calendar appearance:(FSCalendarAppearance *)appearance eventDefaultColorsForDate:(NSDate *)date; + +/** + * Asks the delegate for multiple event colors in selected state for the specific date. + */ +- (nullable NSArray *)calendar:(FSCalendar *)calendar appearance:(FSCalendarAppearance *)appearance eventSelectionColorsForDate:(NSDate *)date; + +/** + * Asks the delegate for a border color in unselected state for the specific date. + */ +- (nullable UIColor *)calendar:(FSCalendar *)calendar appearance:(FSCalendarAppearance *)appearance borderDefaultColorForDate:(NSDate *)date; + +/** + * Asks the delegate for a border color in selected state for the specific date. + */ +- (nullable UIColor *)calendar:(FSCalendar *)calendar appearance:(FSCalendarAppearance *)appearance borderSelectionColorForDate:(NSDate *)date; + +/** + * Asks the delegate for an offset for day text for the specific date. + */ +- (CGPoint)calendar:(FSCalendar *)calendar appearance:(FSCalendarAppearance *)appearance titleOffsetForDate:(NSDate *)date; + +/** + * Asks the delegate for an offset for subtitle for the specific date. + */ +- (CGPoint)calendar:(FSCalendar *)calendar appearance:(FSCalendarAppearance *)appearance subtitleOffsetForDate:(NSDate *)date; + +/** + * Asks the delegate for an offset for image for the specific date. + */ +- (CGPoint)calendar:(FSCalendar *)calendar appearance:(FSCalendarAppearance *)appearance imageOffsetForDate:(NSDate *)date; + +/** + * Asks the delegate for an offset for event dots for the specific date. + */ +- (CGPoint)calendar:(FSCalendar *)calendar appearance:(FSCalendarAppearance *)appearance eventOffsetForDate:(NSDate *)date; + + +/** + * Asks the delegate for a border radius for the specific date. + */ +- (CGFloat)calendar:(FSCalendar *)calendar appearance:(FSCalendarAppearance *)appearance borderRadiusForDate:(NSDate *)date; + +/** + * These functions are deprecated + */ +- (nullable UIColor *)calendar:(FSCalendar *)calendar appearance:(FSCalendarAppearance *)appearance fillColorForDate:(NSDate *)date FSCalendarDeprecated(-calendar:appearance:fillDefaultColorForDate:); +- (nullable UIColor *)calendar:(FSCalendar *)calendar appearance:(FSCalendarAppearance *)appearance selectionColorForDate:(NSDate *)date FSCalendarDeprecated(-calendar:appearance:fillSelectionColorForDate:); +- (nullable UIColor *)calendar:(FSCalendar *)calendar appearance:(FSCalendarAppearance *)appearance eventColorForDate:(NSDate *)date FSCalendarDeprecated(-calendar:appearance:eventDefaultColorsForDate:); +- (nullable NSArray *)calendar:(FSCalendar *)calendar appearance:(FSCalendarAppearance *)appearance eventColorsForDate:(NSDate *)date FSCalendarDeprecated(-calendar:appearance:eventDefaultColorsForDate:); +- (FSCalendarCellShape)calendar:(FSCalendar *)calendar appearance:(FSCalendarAppearance *)appearance cellShapeForDate:(NSDate *)date FSCalendarDeprecated(-calendar:appearance:borderRadiusForDate:); +@end + +#pragma mark - Primary + +IB_DESIGNABLE +@interface FSCalendar : UIView + +/** + * The object that acts as the delegate of the calendar. + */ +@property (weak, nonatomic) IBOutlet id delegate; + +/** + * The object that acts as the data source of the calendar. + */ +@property (weak, nonatomic) IBOutlet id dataSource; + +/** + * A special mark will be put on 'today' of the calendar. + */ +@property (nullable, strong, nonatomic) NSDate *today; + +/** + * The current page of calendar + * + * @desc In week mode, current page represents the current visible week; In month mode, it means current visible month. + */ +@property (strong, nonatomic) NSDate *currentPage; + +/** + * The locale of month and weekday symbols. Change it to display them in your own language. + * + * e.g. To display them in Chinese: + * + * calendar.locale = [NSLocale localeWithLocaleIdentifier:@"zh-CN"]; + */ +@property (copy, nonatomic) NSLocale *locale; + +@property (strong, nonatomic) NSString *calendarIdentifier; + +/** + * The scroll direction of FSCalendar. + * + * e.g. To make the calendar scroll vertically + * + * calendar.scrollDirection = FSCalendarScrollDirectionVertical; + */ +@property (assign, nonatomic) FSCalendarScrollDirection scrollDirection; + +/** + * The scope of calendar, change scope will trigger an inner frame change, make sure the frame has been correctly adjusted in + * + * - (void)calendar:(FSCalendar *)calendar boundingRectWillChange:(CGRect)bounds animated:(BOOL)animated; + */ +@property (assign, nonatomic) FSCalendarScope scope; + +/** + A UIPanGestureRecognizer instance which enables the control of scope on the whole day-area. Not available if the scrollDirection is vertical. + + @deprecated Use -handleScopeGesture: instead + + e.g. + + UIPanGestureRecognizer *scopeGesture = [[UIPanGestureRecognizer alloc] initWithTarget:calendar action:@selector(handleScopeGesture:)]; + [calendar addGestureRecognizer:scopeGesture]; + + @see DIYExample + @see FSCalendarScopeExample + */ +@property (readonly, nonatomic) UIPanGestureRecognizer *scopeGesture FSCalendarDeprecated(handleScopeGesture:); + +/** + * A UILongPressGestureRecognizer instance which enables the swipe-to-choose feature of the calendar. + * + * e.g. + * + * calendar.swipeToChooseGesture.enabled = YES; + */ +@property (readonly, nonatomic) UILongPressGestureRecognizer *swipeToChooseGesture; + +/** + * The placeholder type of FSCalendar. Default is FSCalendarPlaceholderTypeFillSixRows. + * + * e.g. To hide all placeholder of the calendar + * + * calendar.placeholderType = FSCalendarPlaceholderTypeNone; + */ +#if TARGET_INTERFACE_BUILDER +@property (assign, nonatomic) IBInspectable NSUInteger placeholderType; +#else +@property (assign, nonatomic) FSCalendarPlaceholderType placeholderType; +#endif + +/** + The index of the first weekday of the calendar. Give a '2' to make Monday in the first column. + */ +@property (assign, nonatomic) IBInspectable NSUInteger firstWeekday; + +/** + The height of month header of the calendar. Give a '0' to remove the header. + */ +@property (assign, nonatomic) IBInspectable CGFloat headerHeight; + +/** + The height of weekday header of the calendar. + */ +@property (assign, nonatomic) IBInspectable CGFloat weekdayHeight; + +/** + The weekday view of the calendar + */ +@property (strong, nonatomic) FSCalendarWeekdayView *calendarWeekdayView; + +/** + The header view of the calendar + */ +@property (strong, nonatomic) FSCalendarHeaderView *calendarHeaderView; + +/** + A Boolean value that determines whether users can select a date. + */ +@property (assign, nonatomic) IBInspectable BOOL allowsSelection; + +/** + A Boolean value that determines whether users can select more than one date. + */ +@property (assign, nonatomic) IBInspectable BOOL allowsMultipleSelection; + +/** + A Boolean value that determines whether paging is enabled for the calendar. + */ +@property (assign, nonatomic) IBInspectable BOOL pagingEnabled; + +/** + A Boolean value that determines whether scrolling is enabled for the calendar. + */ +@property (assign, nonatomic) IBInspectable BOOL scrollEnabled; + +/** + A Boolean value that determines whether the calendar should show a handle for control the scope. Default is NO; + + @deprecated Use -handleScopeGesture: instead + + e.g. + + UIPanGestureRecognizer *scopeGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self.calendar action:@selector(handleScopeGesture:)]; + scopeGesture.delegate = ... + [anyOtherView addGestureRecognizer:scopeGesture]; + + @see FSCalendarScopeExample + + */ +@property (assign, nonatomic) IBInspectable BOOL showsScopeHandle FSCalendarDeprecated(handleScopeGesture:); + +/** + The row height of the calendar if paging enabled is NO.; + */ +@property (assign, nonatomic) IBInspectable CGFloat rowHeight; + +/** + The calendar appearance used to control the global fonts、colors .etc + */ +@property (readonly, nonatomic) FSCalendarAppearance *appearance; + +/** + A date object representing the minimum day enable、visible and selectable. (read-only) + */ +@property (readonly, nonatomic) NSDate *minimumDate; + +/** + A date object representing the maximum day enable、visible and selectable. (read-only) + */ +@property (readonly, nonatomic) NSDate *maximumDate; + +/** + A date object identifying the section of the selected date. (read-only) + */ +@property (nullable, readonly, nonatomic) NSDate *selectedDate; + +/** + The dates representing the selected dates. (read-only) + */ +@property (readonly, nonatomic) NSArray *selectedDates; + +/** + Reload the dates and appearance of the calendar. + */ +- (void)reloadData; + +/** + Change the scope of the calendar. Make sure `-calendar:boundingRectWillChange:animated` is correctly adopted. + + @param scope The target scope to change. + @param animated YES if you want to animate the scoping; NO if the change should be immediate. + */ +- (void)setScope:(FSCalendarScope)scope animated:(BOOL)animated; + +/** + Selects a given date in the calendar. + + @param date A date in the calendar. + */ +- (void)selectDate:(nullable NSDate *)date; + +/** + Selects a given date in the calendar, optionally scrolling the date to visible area. + + @param date A date in the calendar. + @param scrollToDate A Boolean value that determines whether the calendar should scroll to the selected date to visible area. + */ +- (void)selectDate:(nullable NSDate *)date scrollToDate:(BOOL)scrollToDate; + +/** + Deselects a given date of the calendar. + + @param date A date in the calendar. + */ +- (void)deselectDate:(NSDate *)date; + +/** + Changes the current page of the calendar. + + @param currentPage Representing weekOfYear in week mode, or month in month mode. + @param animated YES if you want to animate the change in position; NO if it should be immediate. + */ +- (void)setCurrentPage:(NSDate *)currentPage animated:(BOOL)animated; + +/** + Register a class for use in creating new calendar cells. + + @param cellClass The class of a cell that you want to use in the calendar. + @param identifier The reuse identifier to associate with the specified class. This parameter must not be nil and must not be an empty string. + */ +- (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier; + +/** + Returns a reusable calendar cell object located by its identifier. + + @param identifier The reuse identifier for the specified cell. This parameter must not be nil. + @param date The specific date of the cell. + @return A valid FSCalendarCell object. + */ +- (__kindof FSCalendarCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier forDate:(NSDate *)date atMonthPosition:(FSCalendarMonthPosition)position; + +/** + Returns the calendar cell for the specified date. + + @param date The date of the cell + @param position The month position for the cell + @return An object representing a cell of the calendar, or nil if the cell is not visible or date is out of range. + */ +- (nullable FSCalendarCell *)cellForDate:(NSDate *)date atMonthPosition:(FSCalendarMonthPosition)position; + + +/** + Returns the date of the specified cell. + + @param cell The cell object whose date you want. + @return The date of the cell or nil if the specified cell is not in the calendar. + */ +- (nullable NSDate *)dateForCell:(FSCalendarCell *)cell; + +/** + Returns the month position of the specified cell. + + @param cell The cell object whose month position you want. + @return The month position of the cell or FSCalendarMonthPositionNotFound if the specified cell is not in the calendar. + */ +- (FSCalendarMonthPosition)monthPositionForCell:(FSCalendarCell *)cell; + + +/** + Returns an array of visible cells currently displayed by the calendar. + + @return An array of FSCalendarCell objects. If no cells are visible, this method returns an empty array. + */ +- (NSArray<__kindof FSCalendarCell *> *)visibleCells; + +/** + Returns the frame for a non-placeholder cell relative to the super view of the calendar. + + @param date A date is the calendar. + */ +- (CGRect)frameForDate:(NSDate *)date; + +/** + An action selector for UIPanGestureRecognizer instance to control the scope transition + + @param sender A UIPanGestureRecognizer instance which controls the scope of the calendar + */ +- (void)handleScopeGesture:(UIPanGestureRecognizer *)sender; + +@end + + +IB_DESIGNABLE +@interface FSCalendar (IBExtension) + +#if TARGET_INTERFACE_BUILDER + +@property (assign, nonatomic) IBInspectable CGFloat titleTextSize; +@property (assign, nonatomic) IBInspectable CGFloat subtitleTextSize; +@property (assign, nonatomic) IBInspectable CGFloat weekdayTextSize; +@property (assign, nonatomic) IBInspectable CGFloat headerTitleTextSize; + +@property (strong, nonatomic) IBInspectable UIColor *eventDefaultColor; +@property (strong, nonatomic) IBInspectable UIColor *eventSelectionColor; +@property (strong, nonatomic) IBInspectable UIColor *weekdayTextColor; + +@property (strong, nonatomic) IBInspectable UIColor *headerTitleColor; +@property (strong, nonatomic) IBInspectable NSString *headerDateFormat; +@property (assign, nonatomic) IBInspectable CGFloat headerMinimumDissolvedAlpha; + +@property (strong, nonatomic) IBInspectable UIColor *titleDefaultColor; +@property (strong, nonatomic) IBInspectable UIColor *titleSelectionColor; +@property (strong, nonatomic) IBInspectable UIColor *titleTodayColor; +@property (strong, nonatomic) IBInspectable UIColor *titlePlaceholderColor; +@property (strong, nonatomic) IBInspectable UIColor *titleWeekendColor; + +@property (strong, nonatomic) IBInspectable UIColor *subtitleDefaultColor; +@property (strong, nonatomic) IBInspectable UIColor *subtitleSelectionColor; +@property (strong, nonatomic) IBInspectable UIColor *subtitleTodayColor; +@property (strong, nonatomic) IBInspectable UIColor *subtitlePlaceholderColor; +@property (strong, nonatomic) IBInspectable UIColor *subtitleWeekendColor; + +@property (strong, nonatomic) IBInspectable UIColor *selectionColor; +@property (strong, nonatomic) IBInspectable UIColor *todayColor; +@property (strong, nonatomic) IBInspectable UIColor *todaySelectionColor; + +@property (strong, nonatomic) IBInspectable UIColor *borderDefaultColor; +@property (strong, nonatomic) IBInspectable UIColor *borderSelectionColor; + +@property (assign, nonatomic) IBInspectable CGFloat borderRadius; +@property (assign, nonatomic) IBInspectable BOOL useVeryShortWeekdaySymbols; + +@property (assign, nonatomic) IBInspectable BOOL fakeSubtitles; +@property (assign, nonatomic) IBInspectable BOOL fakeEventDots; +@property (assign, nonatomic) IBInspectable NSInteger fakedSelectedDay; + +#endif + +@end + +NS_ASSUME_NONNULL_END + diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendar.m b/Pods/FSCalendar+Persian/FSCalendar/FSCalendar.m new file mode 100644 index 0000000..7002df1 --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendar.m @@ -0,0 +1,1762 @@ +// +// FSCalendar.m +// FSCalendar +// +// Created by Wenchao Ding on 29/1/15. +// Copyright © 2016 Wenchao Ding. All rights reserved. +// + +#import "FSCalendar.h" +#import "NSString+Category.h" +#import "FSCalendarHeaderView.h" +#import "FSCalendarWeekdayView.h" +#import "FSCalendarStickyHeader.h" +#import "FSCalendarCollectionViewLayout.h" +#import "FSCalendarScopeHandle.h" + +#import "FSCalendarExtensions.h" +#import "FSCalendarDynamicHeader.h" +#import "FSCalendarCollectionView.h" + +#import "FSCalendarTransitionCoordinator.h" +#import "FSCalendarCalculator.h" +#import "FSCalendarDelegationFactory.h" + +NS_ASSUME_NONNULL_BEGIN + +static inline void FSCalendarAssertDateInBounds(NSDate *date, NSCalendar *calendar, NSDate *minimumDate, NSDate *maximumDate) { + BOOL valid = YES; + NSInteger minOffset = [calendar components:NSCalendarUnitDay fromDate:minimumDate toDate:date options:0].day; + valid &= minOffset >= 0; + if (valid) { + NSInteger maxOffset = [calendar components:NSCalendarUnitDay fromDate:maximumDate toDate:date options:0].day; + valid &= maxOffset <= 0; + } + if (!valid) { + NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; + formatter.dateFormat = @"yyyy/MM/dd"; + [NSException raise:@"FSCalendar date out of bounds exception" format:@"Target date %@ beyond bounds [%@ - %@]", [formatter stringFromDate:date], [formatter stringFromDate:minimumDate], [formatter stringFromDate:maximumDate]]; + } +} + +NS_ASSUME_NONNULL_END + +typedef NS_ENUM(NSUInteger, FSCalendarOrientation) { + FSCalendarOrientationLandscape, + FSCalendarOrientationPortrait +}; + +@interface FSCalendar () +{ + NSMutableArray *_selectedDates; +} + +@property (strong, nonatomic) NSCalendar *gregorian; +@property (strong, nonatomic) NSDateFormatter *formatter; +@property (strong, nonatomic) NSDateComponents *components; +@property (strong, nonatomic) NSTimeZone *timeZone; + +@property (weak , nonatomic) UIView *contentView; +@property (weak , nonatomic) UIView *daysContainer; +@property (weak , nonatomic) UIView *topBorder; +@property (weak , nonatomic) UIView *bottomBorder; +@property (weak , nonatomic) FSCalendarScopeHandle *scopeHandle; +@property (weak , nonatomic) FSCalendarCollectionView *collectionView; +@property (weak , nonatomic) FSCalendarCollectionViewLayout *collectionViewLayout; + +@property (strong, nonatomic) FSCalendarTransitionCoordinator *transitionCoordinator; +@property (strong, nonatomic) FSCalendarCalculator *calculator; + +@property (weak , nonatomic) FSCalendarHeaderTouchDeliver *deliver; + +@property (assign, nonatomic) BOOL needsAdjustingViewFrame; +@property (assign, nonatomic) BOOL needsLayoutForWeekMode; +@property (assign, nonatomic) BOOL needsRequestingBoundingDates; +@property (assign, nonatomic) CGFloat preferredHeaderHeight; +@property (assign, nonatomic) CGFloat preferredWeekdayHeight; +@property (assign, nonatomic) CGFloat preferredRowHeight; +@property (assign, nonatomic) FSCalendarOrientation orientation; + +@property (readonly, nonatomic) BOOL floatingMode; +@property (readonly, nonatomic) BOOL hasValidateVisibleLayout; +@property (readonly, nonatomic) NSArray *visibleStickyHeaders; +@property (readonly, nonatomic) FSCalendarOrientation currentCalendarOrientation; + +@property (strong, nonatomic) FSCalendarDelegationProxy *dataSourceProxy; +@property (strong, nonatomic) FSCalendarDelegationProxy *delegateProxy; + +@property (strong, nonatomic) NSIndexPath *lastPressedIndexPath; +@property (strong, nonatomic) NSMapTable *visibleSectionHeaders; + +- (void)orientationDidChange:(NSNotification *)notification; + +- (CGSize)sizeThatFits:(CGSize)size scope:(FSCalendarScope)scope; + +- (void)scrollToDate:(NSDate *)date; +- (void)scrollToDate:(NSDate *)date animated:(BOOL)animated; +- (void)scrollToPageForDate:(NSDate *)date animated:(BOOL)animated; + +- (BOOL)isPageInRange:(NSDate *)page; +- (BOOL)isDateInRange:(NSDate *)date; +- (BOOL)isDateSelected:(NSDate *)date; +- (BOOL)isDateInDifferentPage:(NSDate *)date; + +- (void)selectDate:(NSDate *)date scrollToDate:(BOOL)scrollToDate atMonthPosition:(FSCalendarMonthPosition)monthPosition; +- (void)enqueueSelectedDate:(NSDate *)date; + +- (void)invalidateDateTools; +- (void)invalidateLayout; +- (void)invalidateHeaders; +- (void)invalidateAppearanceForCell:(FSCalendarCell *)cell forDate:(NSDate *)date; + +- (void)invalidateViewFrames; + +- (void)handleSwipeToChoose:(UILongPressGestureRecognizer *)pressGesture; + +- (void)selectCounterpartDate:(NSDate *)date; +- (void)deselectCounterpartDate:(NSDate *)date; + +- (void)reloadDataForCell:(FSCalendarCell *)cell atIndexPath:(NSIndexPath *)indexPath; + +- (void)adjustMonthPosition; +- (BOOL)requestBoundingDatesIfNecessary; +- (void)configureAppearance; + +@end + +@implementation FSCalendar + +@dynamic selectedDate; +@synthesize scopeGesture = _scopeGesture, swipeToChooseGesture = _swipeToChooseGesture; + +#pragma mark - Life Cycle && Initialize + +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + [self initialize]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)aDecoder +{ + self = [super initWithCoder:aDecoder]; + if (self) { + [self initialize]; + } + return self; +} + +- (void)initialize +{ + if (!_appearance) { + _appearance = [[FSCalendarAppearance alloc] init]; + _appearance.calendar = self; + } + + if (!_gregorian) { + _gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; + } + + if (!_components) { + _components = [[NSDateComponents alloc] init]; + } + if (!_formatter) { + _formatter = [[NSDateFormatter alloc] init]; + _formatter.dateFormat = @"yyyy-MM-dd"; + } + + if (!_locale) { + _locale = [NSLocale currentLocale]; + } + if (!_timeZone) { + _timeZone = [NSTimeZone localTimeZone]; + } + + if (!_firstWeekday || _firstWeekday == 0) { + _firstWeekday = 1; + } + [self invalidateDateTools]; + + if (!_today) { + _today = [self.gregorian dateBySettingHour:0 minute:0 second:0 ofDate:[NSDate date] options:0]; + _currentPage = [self.gregorian fs_firstDayOfMonth:_today]; + } + if (!_minimumDate) { + _minimumDate = [self.formatter dateFromString:@"1970-01-01"]; + } + + if (!_maximumDate) { + _maximumDate = [self.formatter dateFromString:@"2099-12-31"]; + } + + _headerHeight = FSCalendarAutomaticDimension; + _weekdayHeight = FSCalendarAutomaticDimension; + _rowHeight = FSCalendarStandardRowHeight*MAX(1, FSCalendarDeviceIsIPad*1.5); + + _preferredHeaderHeight = FSCalendarAutomaticDimension; + _preferredWeekdayHeight = FSCalendarAutomaticDimension; + _preferredRowHeight = FSCalendarAutomaticDimension; + + _scrollDirection = FSCalendarScrollDirectionHorizontal; + _scope = FSCalendarScopeMonth; + if (!_selectedDates) { + _selectedDates = [NSMutableArray arrayWithCapacity:1]; + } + if (!_visibleSectionHeaders) { + _visibleSectionHeaders = [NSMapTable weakToWeakObjectsMapTable]; + } + + _pagingEnabled = YES; + _scrollEnabled = YES; + _needsAdjustingViewFrame = YES; + _needsRequestingBoundingDates = YES; + _orientation = self.currentCalendarOrientation; + _placeholderType = FSCalendarPlaceholderTypeFillSixRows; + + _dataSourceProxy = [FSCalendarDelegationFactory dataSourceProxy]; + _delegateProxy = [FSCalendarDelegationFactory delegateProxy]; + + if (!self.contentView) { + UIView *contentView = [[UIView alloc] initWithFrame:CGRectZero]; + contentView.backgroundColor = [UIColor clearColor]; + [self addSubview:contentView]; + self.contentView = contentView; + + UIView *daysContainer = [[UIView alloc] initWithFrame:CGRectZero]; + daysContainer.backgroundColor = [UIColor clearColor]; + daysContainer.clipsToBounds = YES; + [contentView addSubview:daysContainer]; + self.daysContainer = daysContainer; + + if (!self.collectionViewLayout) { + FSCalendarCollectionViewLayout *collectionViewLayout = [[FSCalendarCollectionViewLayout alloc] init]; + collectionViewLayout.calendar = self; + + FSCalendarCollectionView *collectionView = [[FSCalendarCollectionView alloc] initWithFrame:CGRectZero + collectionViewLayout:collectionViewLayout]; + collectionView.dataSource = self; + collectionView.delegate = self; + collectionView.backgroundColor = [UIColor clearColor]; + collectionView.pagingEnabled = YES; + collectionView.showsHorizontalScrollIndicator = NO; + collectionView.showsVerticalScrollIndicator = NO; + collectionView.allowsMultipleSelection = NO; + collectionView.clipsToBounds = YES; + [collectionView registerClass:[FSCalendarCell class] forCellWithReuseIdentifier:FSCalendarDefaultCellReuseIdentifier]; + [collectionView registerClass:[FSCalendarBlankCell class] forCellWithReuseIdentifier:FSCalendarBlankCellReuseIdentifier]; + [collectionView registerClass:[FSCalendarStickyHeader class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header"]; + [collectionView registerClass:[UICollectionReusableView class] forSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"placeholderHeader"]; + [daysContainer addSubview:collectionView]; + self.collectionView = collectionView; + self.collectionViewLayout = collectionViewLayout; + } + } + + if (!FSCalendarInAppExtension) { + if (!self.topBorder && !self.bottomBorder) { + UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; + view.backgroundColor = FSCalendarStandardLineColor; + view.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin; // Stick to top + [self addSubview:view]; + self.topBorder = view; + + view = [[UIView alloc] initWithFrame:CGRectZero]; + view.backgroundColor = FSCalendarStandardLineColor; + view.autoresizingMask = UIViewAutoresizingFlexibleTopMargin; // Stick to bottom + [self addSubview:view]; + self.bottomBorder = view; + } + } + + [self invalidateLayout]; + + // Assistants + if (!self.transitionCoordinator) { + self.transitionCoordinator = [[FSCalendarTransitionCoordinator alloc] initWithCalendar:self]; + } + + if (!self.calculator) { + self.calculator = [[FSCalendarCalculator alloc] initWithCalendar:self]; + } + + [[NSNotificationCenter defaultCenter] removeObserver:self + name:UIDeviceOrientationDidChangeNotification + object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(orientationDidChange:) + name:UIDeviceOrientationDidChangeNotification + object:nil]; +} + +- (void)dealloc +{ + self.collectionView.delegate = nil; + self.collectionView.dataSource = nil; + + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil]; +} + +#pragma mark - Overriden methods + +- (void)setBounds:(CGRect)bounds +{ + [super setBounds:bounds]; + if (!CGRectIsEmpty(bounds) && self.transitionCoordinator.state == FSCalendarTransitionStateIdle) { + [self invalidateViewFrames]; + } +} + +- (void)setFrame:(CGRect)frame +{ + [super setFrame:frame]; + if (!CGRectIsEmpty(frame) && self.transitionCoordinator.state == FSCalendarTransitionStateIdle) { + [self invalidateViewFrames]; + } +} + +- (void)setValue:(id)value forUndefinedKey:(NSString *)key +{ +#if !TARGET_INTERFACE_BUILDER + if ([key hasPrefix:@"fake"]) { + return; + } +#endif + if (key.length) { + NSString *setter = [NSString stringWithFormat:@"set%@%@:",[key substringToIndex:1].uppercaseString,[key substringFromIndex:1]]; + SEL selector = NSSelectorFromString(setter); + if ([self.appearance respondsToSelector:selector]) { + return [self.appearance setValue:value forKey:key]; + } else if ([self.collectionViewLayout respondsToSelector:selector]) { + return [self.collectionViewLayout setValue:value forKey:key]; + } + } + + return [super setValue:value forUndefinedKey:key]; + +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + if (_needsAdjustingViewFrame) { + _needsAdjustingViewFrame = NO; + + if (CGSizeEqualToSize(_transitionCoordinator.cachedMonthSize, CGSizeZero)) { + _transitionCoordinator.cachedMonthSize = self.frame.size; + } + + BOOL needsAdjustingBoundingRect = (self.scope == FSCalendarScopeMonth) && + (self.placeholderType != FSCalendarPlaceholderTypeFillSixRows) && + !self.hasValidateVisibleLayout; + + if (_scopeHandle) { + CGFloat scopeHandleHeight = self.transitionCoordinator.cachedMonthSize.height*0.08; + _contentView.frame = CGRectMake(0, 0, self.fs_width, self.fs_height-scopeHandleHeight); + _scopeHandle.frame = CGRectMake(0, _contentView.fs_bottom, self.fs_width, scopeHandleHeight); + } else { + _contentView.frame = self.bounds; + } + + CGFloat headerHeight = self.preferredHeaderHeight; + CGFloat weekdayHeight = self.preferredWeekdayHeight; + CGFloat rowHeight = self.preferredRowHeight; + CGFloat padding = 5; + if (self.scrollDirection == UICollectionViewScrollDirectionHorizontal) { + rowHeight = FSCalendarFloor(rowHeight*2)*0.5; // Round to nearest multiple of 0.5. e.g. (16.8->16.5),(16.2->16.0) + } + + self.calendarHeaderView.frame = CGRectMake(0, 0, self.fs_width, headerHeight); + self.calendarWeekdayView.frame = CGRectMake(0, self.calendarHeaderView.fs_bottom, self.contentView.fs_width, weekdayHeight); + + _deliver.frame = CGRectMake(self.calendarHeaderView.fs_left, self.calendarHeaderView.fs_top, self.calendarHeaderView.fs_width, headerHeight+weekdayHeight); + _deliver.hidden = self.calendarHeaderView.hidden; + if (!self.floatingMode) { + switch (self.transitionCoordinator.representingScope) { + case FSCalendarScopeMonth: { + CGFloat contentHeight = rowHeight*6 + padding*2; + CGFloat currentHeight = rowHeight*[self.calculator numberOfRowsInMonth:self.currentPage] + padding*2; + _daysContainer.frame = CGRectMake(0, headerHeight+weekdayHeight, self.fs_width, currentHeight); + _collectionView.frame = CGRectMake(0, 0, _daysContainer.fs_width, contentHeight); + if (needsAdjustingBoundingRect) { + self.transitionCoordinator.state = FSCalendarTransitionStateChanging; + CGRect boundingRect = (CGRect){CGPointZero,[self sizeThatFits:self.frame.size]}; + [self.delegateProxy calendar:self boundingRectWillChange:boundingRect animated:NO]; + self.transitionCoordinator.state = FSCalendarTransitionStateIdle; + } + break; + } + case FSCalendarScopeWeek: { + CGFloat contentHeight = rowHeight + padding*2; + _daysContainer.frame = CGRectMake(0, headerHeight+weekdayHeight, self.fs_width, contentHeight); + _collectionView.frame = CGRectMake(0, 0, _daysContainer.fs_width, contentHeight); + break; + } + } + } else { + + CGFloat contentHeight = _contentView.fs_height; + _daysContainer.frame = CGRectMake(0, 0, self.fs_width, contentHeight); + _collectionView.frame = _daysContainer.bounds; + + } + _collectionView.fs_height = FSCalendarHalfFloor(_collectionView.fs_height); + _topBorder.frame = CGRectMake(0, -1, self.fs_width, 1); + _bottomBorder.frame = CGRectMake(0, self.fs_height, self.fs_width, 1); + _scopeHandle.fs_bottom = _bottomBorder.fs_top; + + } + + if (_needsLayoutForWeekMode) { + _needsLayoutForWeekMode = NO; + [self.transitionCoordinator performScopeTransitionFromScope:FSCalendarScopeMonth toScope:FSCalendarScopeWeek animated:NO]; + } + +} + +#if TARGET_INTERFACE_BUILDER +- (void)prepareForInterfaceBuilder +{ + NSDate *date = [NSDate date]; + NSDateComponents *components = [self.gregorian components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay fromDate:date]; + components.day = _appearance.fakedSelectedDay?:1; + [_selectedDates addObject:[self.gregorian dateFromComponents:components]]; + [self.collectionView reloadData]; +} +#endif + +- (CGSize)sizeThatFits:(CGSize)size +{ + switch (self.transitionCoordinator.transition) { + case FSCalendarTransitionNone: + return [self sizeThatFits:size scope:_scope]; + case FSCalendarTransitionWeekToMonth: + if (self.transitionCoordinator.state == FSCalendarTransitionStateChanging) { + return [self sizeThatFits:size scope:FSCalendarScopeMonth]; + } + case FSCalendarTransitionMonthToWeek: + break; + } + return [self sizeThatFits:size scope:FSCalendarScopeWeek]; +} + +- (CGSize)sizeThatFits:(CGSize)size scope:(FSCalendarScope)scope +{ + CGFloat headerHeight = self.preferredHeaderHeight; + CGFloat weekdayHeight = self.preferredWeekdayHeight; + CGFloat rowHeight = self.preferredRowHeight; + CGFloat paddings = self.collectionViewLayout.sectionInsets.top + self.collectionViewLayout.sectionInsets.bottom; + + if (!self.floatingMode) { + switch (scope) { + case FSCalendarScopeMonth: { + CGFloat height = weekdayHeight + headerHeight + [self.calculator numberOfRowsInMonth:_currentPage]*rowHeight + paddings; + height += _scopeHandle.fs_height; + return CGSizeMake(size.width, height); + } + case FSCalendarScopeWeek: { + CGFloat height = weekdayHeight + headerHeight + rowHeight + paddings; + height += _scopeHandle.fs_height; + return CGSizeMake(size.width, height); + } + } + } else { + return CGSizeMake(size.width, self.fs_height); + } + return size; +} + +#pragma mark - + +- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView +{ + [self requestBoundingDatesIfNecessary]; + return self.calculator.numberOfSections; +} + +- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section +{ + if (self.floatingMode) { + NSInteger numberOfRows = [self.calculator numberOfRowsInSection:section]; + return numberOfRows * 7; + } + switch (self.transitionCoordinator.representingScope) { + case FSCalendarScopeMonth: { + return 42; + } + case FSCalendarScopeWeek: { + return 7; + } + } + return 7; +} + +- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath +{ + FSCalendarMonthPosition monthPosition = [self.calculator monthPositionForIndexPath:indexPath]; + + switch (self.placeholderType) { + case FSCalendarPlaceholderTypeNone: { + if (self.transitionCoordinator.representingScope == FSCalendarScopeMonth && monthPosition != FSCalendarMonthPositionCurrent) { + UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:FSCalendarBlankCellReuseIdentifier forIndexPath:indexPath]; + [cell setTransform:CGAffineTransformMakeScale(-1,1)]; + return cell; + } + break; + } + case FSCalendarPlaceholderTypeFillHeadTail: { + if (self.transitionCoordinator.representingScope == FSCalendarScopeMonth) { + if (indexPath.item >= 7 * [self.calculator numberOfRowsInSection:indexPath.section]) { + UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:FSCalendarBlankCellReuseIdentifier forIndexPath:indexPath]; + [cell setTransform:CGAffineTransformMakeScale(-1,1)]; + return cell; + } + } + break; + } + case FSCalendarPlaceholderTypeFillSixRows: { + break; + } + } + + NSDate *date = [self.calculator dateForIndexPath:indexPath]; + FSCalendarCell *cell = [self.dataSourceProxy calendar:self cellForDate:date atMonthPosition:monthPosition]; + if (!cell) { + cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:FSCalendarDefaultCellReuseIdentifier forIndexPath:indexPath]; + } + [self reloadDataForCell:cell atIndexPath:indexPath]; + if ([self isPersianCalender]) { + [cell setTransform:CGAffineTransformMakeScale(-1, 1)]; + cell.titleLabel.text = [self convertEnNumberToFarsi:cell.titleLabel.text]; + } + return cell; +} + +- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath +{ + if (self.floatingMode) { + if ([kind isEqualToString:UICollectionElementKindSectionHeader]) { + FSCalendarStickyHeader *stickyHeader = [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"header" forIndexPath:indexPath]; + if ([self isPersianCalender]) { + [stickyHeader setTransform:CGAffineTransformMakeScale(-1, 1)]; + } + stickyHeader.calendar = self; + stickyHeader.month = [self.gregorian dateByAddingUnit:NSCalendarUnitMonth value:indexPath.section toDate:[self.gregorian fs_firstDayOfMonth:_minimumDate] options:0]; + self.visibleSectionHeaders[indexPath] = stickyHeader; + [stickyHeader setNeedsLayout]; + return stickyHeader; + } + } + return [collectionView dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader withReuseIdentifier:@"placeholderHeader" forIndexPath:indexPath]; +} + +- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingSupplementaryView:(UICollectionReusableView *)view forElementOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath +{ + if (self.floatingMode) { + if ([elementKind isEqualToString:UICollectionElementKindSectionHeader]) { + self.visibleSectionHeaders[indexPath] = nil; + } + } +} + +#pragma mark - + +- (BOOL)collectionView:(UICollectionView *)collectionView shouldSelectItemAtIndexPath:(NSIndexPath *)indexPath +{ + FSCalendarMonthPosition monthPosition = [self.calculator monthPositionForIndexPath:indexPath]; + if (self.placeholderType == FSCalendarPlaceholderTypeNone && monthPosition != FSCalendarMonthPositionCurrent) { + return NO; + } + NSDate *date = [self.calculator dateForIndexPath:indexPath]; + return [self isDateInRange:date] && (![self.delegateProxy respondsToSelector:@selector(calendar:shouldSelectDate:atMonthPosition:)] || [self.delegateProxy calendar:self shouldSelectDate:date atMonthPosition:monthPosition]); +} + +- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath +{ + NSDate *selectedDate = [self.calculator dateForIndexPath:indexPath]; + FSCalendarMonthPosition monthPosition = [self.calculator monthPositionForIndexPath:indexPath]; + FSCalendarCell *cell; + if (monthPosition == FSCalendarMonthPositionCurrent) { + cell = (FSCalendarCell *)[collectionView cellForItemAtIndexPath:indexPath]; + } else { + cell = [self cellForDate:selectedDate atMonthPosition:FSCalendarMonthPositionCurrent]; + NSIndexPath *indexPath = [collectionView indexPathForCell:cell]; + if (indexPath) { + [collectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:UICollectionViewScrollPositionNone]; + } + } + if (![_selectedDates containsObject:selectedDate]) { + cell.selected = YES; + [cell performSelecting]; + } + [self enqueueSelectedDate:selectedDate]; + [self.delegateProxy calendar:self didSelectDate:selectedDate atMonthPosition:monthPosition]; + [self selectCounterpartDate:selectedDate]; +} + +- (BOOL)collectionView:(UICollectionView *)collectionView shouldDeselectItemAtIndexPath:(NSIndexPath *)indexPath +{ + FSCalendarMonthPosition monthPosition = [self.calculator monthPositionForIndexPath:indexPath]; + if (self.placeholderType == FSCalendarPlaceholderTypeNone && monthPosition != FSCalendarMonthPositionCurrent) { + return NO; + } + NSDate *date = [self.calculator dateForIndexPath:indexPath]; + return [self isDateInRange:date] && (![self.delegateProxy respondsToSelector:@selector(calendar:shouldDeselectDate:atMonthPosition:)]||[self.delegateProxy calendar:self shouldDeselectDate:date atMonthPosition:monthPosition]); +} + +- (void)collectionView:(UICollectionView *)collectionView didDeselectItemAtIndexPath:(NSIndexPath *)indexPath +{ + NSDate *selectedDate = [self.calculator dateForIndexPath:indexPath]; + FSCalendarMonthPosition monthPosition = [self.calculator monthPositionForIndexPath:indexPath]; + FSCalendarCell *cell; + if (monthPosition == FSCalendarMonthPositionCurrent) { + cell = (FSCalendarCell *)[collectionView cellForItemAtIndexPath:indexPath]; + } else { + cell = [self cellForDate:selectedDate atMonthPosition:FSCalendarMonthPositionCurrent]; + NSIndexPath *indexPath = [collectionView indexPathForCell:cell]; + if (indexPath) { + [collectionView deselectItemAtIndexPath:indexPath animated:NO]; + } + } + cell.selected = NO; + [cell configureAppearance]; + + [_selectedDates removeObject:selectedDate]; + [self.delegateProxy calendar:self didDeselectDate:selectedDate atMonthPosition:monthPosition]; + [self deselectCounterpartDate:selectedDate]; + +} + +- (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath +{ + if (![cell isKindOfClass:[FSCalendarCell class]]) { + return; + } + NSDate *date = [self.calculator dateForIndexPath:indexPath]; + FSCalendarMonthPosition monthPosition = [self.calculator monthPositionForIndexPath:indexPath]; + [self.delegateProxy calendar:self willDisplayCell:(FSCalendarCell *)cell forDate:date atMonthPosition:monthPosition]; +} + +#pragma mark - + +- (void)scrollViewDidScroll:(UIScrollView *)scrollView +{ + if (!self.window) return; + if (self.floatingMode && _collectionView.indexPathsForVisibleItems.count) { + // Do nothing on bouncing + if (_collectionView.contentOffset.y < 0 || _collectionView.contentOffset.y > _collectionView.contentSize.height-_collectionView.fs_height) { + return; + } + NSDate *currentPage = _currentPage; + CGPoint significantPoint = CGPointMake(_collectionView.fs_width*0.5,MIN(self.collectionViewLayout.estimatedItemSize.height*2.75, _collectionView.fs_height*0.5)+_collectionView.contentOffset.y); + NSIndexPath *significantIndexPath = [_collectionView indexPathForItemAtPoint:significantPoint]; + if (significantIndexPath) { + currentPage = [self.gregorian dateByAddingUnit:NSCalendarUnitMonth value:significantIndexPath.section toDate:[self.gregorian fs_firstDayOfMonth:_minimumDate] options:0]; + } else { + FSCalendarStickyHeader *significantHeader = [self.visibleStickyHeaders filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(FSCalendarStickyHeader * _Nonnull evaluatedObject, NSDictionary * _Nullable bindings) { + return CGRectContainsPoint(evaluatedObject.frame, significantPoint); + }]].firstObject; + if (significantHeader) { + currentPage = significantHeader.month; + } + } + + if (![self.gregorian isDate:currentPage equalToDate:_currentPage toUnitGranularity:NSCalendarUnitMonth]) { + [self willChangeValueForKey:@"currentPage"]; + _currentPage = currentPage; + [self.delegateProxy calendarCurrentPageDidChange:self]; + [self didChangeValueForKey:@"currentPage"]; + } + + } else if (self.hasValidateVisibleLayout) { + CGFloat scrollOffset = 0; + switch (_collectionViewLayout.scrollDirection) { + case UICollectionViewScrollDirectionHorizontal: { + scrollOffset = scrollView.contentOffset.x/scrollView.fs_width; + break; + } + case UICollectionViewScrollDirectionVertical: { + scrollOffset = scrollView.contentOffset.y/scrollView.fs_height; + break; + } + } + _calendarHeaderView.scrollOffset = scrollOffset; + } +} + +- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset +{ + if (!_pagingEnabled || !_scrollEnabled) { + return; + } + CGFloat targetOffset = 0, contentSize = 0; + switch (_collectionViewLayout.scrollDirection) { + case UICollectionViewScrollDirectionHorizontal: { + targetOffset = targetContentOffset->x; + contentSize = scrollView.fs_width; + break; + } + case UICollectionViewScrollDirectionVertical: { + targetOffset = targetContentOffset->y; + contentSize = scrollView.fs_height; + break; + } + } + + NSInteger sections = lrint(targetOffset/contentSize); + NSDate *targetPage = nil; + switch (_scope) { + case FSCalendarScopeMonth: { + NSDate *minimumPage = [self.gregorian fs_firstDayOfMonth:_minimumDate]; + targetPage = [self.gregorian dateByAddingUnit:NSCalendarUnitMonth value:sections toDate:minimumPage options:0]; + break; + } + case FSCalendarScopeWeek: { + NSDate *minimumPage = [self.gregorian fs_firstDayOfWeek:_minimumDate]; + targetPage = [self.gregorian dateByAddingUnit:NSCalendarUnitWeekOfYear value:sections toDate:minimumPage options:0]; + break; + } + } + BOOL shouldTriggerPageChange = [self isDateInDifferentPage:targetPage]; + if (shouldTriggerPageChange) { + NSDate *lastPage = _currentPage; + [self willChangeValueForKey:@"currentPage"]; + _currentPage = targetPage; + [self.delegateProxy calendarCurrentPageDidChange:self]; + if (_placeholderType != FSCalendarPlaceholderTypeFillSixRows) { + [self.transitionCoordinator performBoundingRectTransitionFromMonth:lastPage toMonth:_currentPage duration:0.25]; + } + [self didChangeValueForKey:@"currentPage"]; + } + + // Disable all inner gestures to avoid missing event + [scrollView.gestureRecognizers enumerateObjectsUsingBlock:^(__kindof UIGestureRecognizer * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + if (obj != scrollView.panGestureRecognizer) { + obj.enabled = NO; + } + }]; + +} + +- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView +{ + // Recover all disabled gestures + [scrollView.gestureRecognizers enumerateObjectsUsingBlock:^(__kindof UIGestureRecognizer * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + if (obj != scrollView.panGestureRecognizer) { + obj.enabled = YES; + } + }]; +} + +#pragma mark - + +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer +{ + return YES; +} + +#pragma mark - Notification + +- (void)orientationDidChange:(NSNotification *)notification +{ + self.orientation = self.currentCalendarOrientation; +} + +#pragma mark - Properties + +- (void)setCalendarIdentifier:(NSString *)identifier{ + self.gregorian = [NSCalendar calendarWithIdentifier:identifier]; + if ([identifier isRTLCalendar]) { + //TODO: Totall view did change the direction. + [self setTransform:CGAffineTransformMakeScale(-1, 1)]; + } + _today = [self.gregorian dateBySettingHour:0 minute:0 second:0 ofDate:[NSDate date] options:0]; + _currentPage = [self.gregorian fs_firstDayOfMonth:_today]; + + [self invalidateDateTools]; + [self configureAppearance]; + if (self.hasValidateVisibleLayout) { + [self invalidateHeaders]; + } +} + +- (NSString *)calendarIdentifier{ + return self.gregorian.calendarIdentifier; +} + +- (void)setScrollDirection:(FSCalendarScrollDirection)scrollDirection +{ + if (_scrollDirection != scrollDirection) { + _scrollDirection = scrollDirection; + + if (self.floatingMode) return; + + switch (_scope) { + case FSCalendarScopeMonth: { + _collectionViewLayout.scrollDirection = (UICollectionViewScrollDirection)scrollDirection; + _calendarHeaderView.scrollDirection = _collectionViewLayout.scrollDirection; + if (self.hasValidateVisibleLayout) { + [_collectionView reloadData]; + [_calendarHeaderView reloadData]; + } + _needsAdjustingViewFrame = YES; + [self setNeedsLayout]; + break; + } + case FSCalendarScopeWeek: { + break; + } + } + } +} + ++ (BOOL)automaticallyNotifiesObserversOfScope +{ + return NO; +} + +- (void)setScope:(FSCalendarScope)scope +{ + [self setScope:scope animated:NO]; +} + +- (void)setFirstWeekday:(NSUInteger)firstWeekday +{ + if (_firstWeekday != firstWeekday) { + _firstWeekday = firstWeekday; + _needsRequestingBoundingDates = YES; + [self invalidateDateTools]; + [self invalidateHeaders]; + [self.collectionView reloadData]; + [self configureAppearance]; + + [self invalidateLayout]; + } +} + +- (void)setToday:(NSDate *)today +{ + if (!today) { + _today = nil; + } else { + FSCalendarAssertDateInBounds(today,self.gregorian,self.minimumDate,self.maximumDate); + _today = [self.gregorian dateBySettingHour:0 minute:0 second:0 ofDate:today options:0]; + } + if (self.hasValidateVisibleLayout) { + [self.visibleCells makeObjectsPerformSelector:@selector(setDateIsToday:) withObject:nil]; + if (today) [[_collectionView cellForItemAtIndexPath:[self.calculator indexPathForDate:today]] setValue:@YES forKey:@"dateIsToday"]; + [self.visibleCells makeObjectsPerformSelector:@selector(configureAppearance)]; + } +} + +- (void)setCurrentPage:(NSDate *)currentPage +{ + [self setCurrentPage:currentPage animated:NO]; +} + +- (void)setCurrentPage:(NSDate *)currentPage animated:(BOOL)animated +{ + [self requestBoundingDatesIfNecessary]; + if (self.floatingMode || [self isDateInDifferentPage:currentPage]) { + currentPage = [self.gregorian dateBySettingHour:0 minute:0 second:0 ofDate:currentPage options:0]; + if ([self isPageInRange:currentPage]) { + [self scrollToPageForDate:currentPage animated:animated]; + } + } +} + +- (void)registerClass:(Class)cellClass forCellReuseIdentifier:(NSString *)identifier +{ + if (!identifier.length) { + [NSException raise:FSCalendarInvalidArgumentsExceptionName format:@"This identifier must not be nil and must not be an empty string."]; + } + if (![cellClass isSubclassOfClass:[FSCalendarCell class]]) { + [NSException raise:@"The cell class must be a subclass of FSCalendarCell." format:@""]; + } + if ([identifier isEqualToString:FSCalendarBlankCellReuseIdentifier]) { + [NSException raise:FSCalendarInvalidArgumentsExceptionName format:@"Do not use %@ as the cell reuse identifier.", identifier]; + } + [self.collectionView registerClass:cellClass forCellWithReuseIdentifier:identifier]; + +} + +- (FSCalendarCell *)dequeueReusableCellWithIdentifier:(NSString *)identifier forDate:(NSDate *)date atMonthPosition:(FSCalendarMonthPosition)position; +{ + if (!identifier.length) { + [NSException raise:FSCalendarInvalidArgumentsExceptionName format:@"This identifier must not be nil and must not be an empty string."]; + } + NSIndexPath *indexPath = [self.calculator indexPathForDate:date atMonthPosition:position]; + if (!indexPath) { + [NSException raise:FSCalendarInvalidArgumentsExceptionName format:@"Attempting to dequeue a cell with invalid date."]; + } + FSCalendarCell *cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath]; + return cell; +} + +- (nullable FSCalendarCell *)cellForDate:(NSDate *)date atMonthPosition:(FSCalendarMonthPosition)position +{ + NSIndexPath *indexPath = [self.calculator indexPathForDate:date atMonthPosition:position]; + return (FSCalendarCell *)[self.collectionView cellForItemAtIndexPath:indexPath]; +} + +- (NSDate *)dateForCell:(FSCalendarCell *)cell +{ + NSIndexPath *indexPath = [self.collectionView indexPathForCell:cell]; + return [self.calculator dateForIndexPath:indexPath]; +} + +- (FSCalendarMonthPosition)monthPositionForCell:(FSCalendarCell *)cell +{ + NSIndexPath *indexPath = [self.collectionView indexPathForCell:cell]; + return [self.calculator monthPositionForIndexPath:indexPath]; +} + +- (NSArray *)visibleCells +{ + return [self.collectionView.visibleCells filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id _Nullable evaluatedObject, NSDictionary * _Nullable bindings) { + return [evaluatedObject isKindOfClass:[FSCalendarCell class]]; + }]]; +} + +- (CGRect)frameForDate:(NSDate *)date +{ + if (!self.superview) { + return CGRectZero; + } + CGRect frame = [_collectionViewLayout layoutAttributesForItemAtIndexPath:[self.calculator indexPathForDate:date]].frame; + frame = [self.superview convertRect:frame fromView:_collectionView]; + return frame; +} + +- (void)setHeaderHeight:(CGFloat)headerHeight +{ + if (_headerHeight != headerHeight) { + _headerHeight = headerHeight; + _needsAdjustingViewFrame = YES; + [self setNeedsLayout]; + } +} + +- (void)setWeekdayHeight:(CGFloat)weekdayHeight +{ + if (_weekdayHeight != weekdayHeight) { + _weekdayHeight = weekdayHeight; + _needsAdjustingViewFrame = YES; + [self setNeedsLayout]; + } +} + +- (void)setLocale:(NSLocale *)locale +{ + if (![_locale isEqual:locale]) { + _locale = locale.copy; + [self invalidateDateTools]; + [self configureAppearance]; + if (self.hasValidateVisibleLayout) { + [self invalidateHeaders]; + } + } +} + +- (void)setAllowsMultipleSelection:(BOOL)allowsMultipleSelection +{ + _collectionView.allowsMultipleSelection = allowsMultipleSelection; +} + +- (BOOL)allowsMultipleSelection +{ + return _collectionView.allowsMultipleSelection; +} + +- (void)setAllowsSelection:(BOOL)allowsSelection +{ + _collectionView.allowsSelection = allowsSelection; +} + +- (BOOL)allowsSelection +{ + return _collectionView.allowsSelection; +} + +- (void)setPagingEnabled:(BOOL)pagingEnabled +{ + if (_pagingEnabled != pagingEnabled) { + _pagingEnabled = pagingEnabled; + + [self invalidateLayout]; + } +} + +- (void)setScrollEnabled:(BOOL)scrollEnabled +{ + if (_scrollEnabled != scrollEnabled) { + _scrollEnabled = scrollEnabled; + + _collectionView.scrollEnabled = scrollEnabled; + _calendarHeaderView.scrollEnabled = scrollEnabled; + + [self invalidateLayout]; + } +} + +- (void)setOrientation:(FSCalendarOrientation)orientation +{ + if (_orientation != orientation) { + _orientation = orientation; + + _needsAdjustingViewFrame = YES; + _preferredWeekdayHeight = FSCalendarAutomaticDimension; + _preferredRowHeight = FSCalendarAutomaticDimension; + _preferredHeaderHeight = FSCalendarAutomaticDimension; + _calendarHeaderView.needsAdjustingMonthPosition = YES; + _calendarHeaderView.needsAdjustingViewFrame = YES; + [self setNeedsLayout]; + } +} + +- (NSDate *)selectedDate +{ + return _selectedDates.lastObject; +} + +- (NSArray *)selectedDates +{ + return [NSArray arrayWithArray:_selectedDates]; +} + +- (CGFloat)preferredHeaderHeight +{ + if (_headerHeight == FSCalendarAutomaticDimension) { + if (_preferredWeekdayHeight == FSCalendarAutomaticDimension) { + if (!self.floatingMode) { + CGFloat DIYider = FSCalendarStandardMonthlyPageHeight; + CGFloat contentHeight = self.transitionCoordinator.cachedMonthSize.height*(1-_showsScopeHandle*0.08); + _preferredHeaderHeight = (FSCalendarStandardHeaderHeight/DIYider)*contentHeight; + _preferredHeaderHeight -= (_preferredHeaderHeight-FSCalendarStandardHeaderHeight)*0.5; + } else { + _preferredHeaderHeight = FSCalendarStandardHeaderHeight*MAX(1, FSCalendarDeviceIsIPad*1.5); + } + } + return _preferredHeaderHeight; + } + return _headerHeight; +} + +- (CGFloat)preferredWeekdayHeight +{ + if (_weekdayHeight == FSCalendarAutomaticDimension) { + if (_preferredWeekdayHeight == FSCalendarAutomaticDimension) { + if (!self.floatingMode) { + CGFloat DIYider = FSCalendarStandardMonthlyPageHeight; + CGFloat contentHeight = self.transitionCoordinator.cachedMonthSize.height*(1-_showsScopeHandle*0.08); + _preferredWeekdayHeight = (FSCalendarStandardWeekdayHeight/DIYider)*contentHeight; + } else { + _preferredWeekdayHeight = FSCalendarStandardWeekdayHeight*MAX(1, FSCalendarDeviceIsIPad*1.5); + } + } + return _preferredWeekdayHeight; + } + return _weekdayHeight; +} + +- (CGFloat)preferredRowHeight +{ + if (_preferredRowHeight == FSCalendarAutomaticDimension) { + CGFloat headerHeight = self.preferredHeaderHeight; + CGFloat weekdayHeight = self.preferredWeekdayHeight; + CGFloat contentHeight = self.transitionCoordinator.cachedMonthSize.height-headerHeight-weekdayHeight-_scopeHandle.fs_height; + CGFloat padding = 5; + if (!self.floatingMode) { + _preferredRowHeight = (contentHeight-padding*2)/6.0; + } else { + _preferredRowHeight = _rowHeight; + } + } + return _preferredRowHeight; +} + +- (BOOL)floatingMode +{ + return _scope == FSCalendarScopeMonth && _scrollEnabled && !_pagingEnabled; +} + +- (void)setShowsScopeHandle:(BOOL)showsScopeHandle +{ + if (_showsScopeHandle != showsScopeHandle) { + _showsScopeHandle = showsScopeHandle; + [self invalidateLayout]; + } +} + +- (UIPanGestureRecognizer *)scopeGesture +{ + if (!_scopeGesture) { + UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self.transitionCoordinator action:@selector(handleScopeGesture:)]; + panGesture.delegate = self.transitionCoordinator; + panGesture.minimumNumberOfTouches = 1; + panGesture.maximumNumberOfTouches = 2; + panGesture.enabled = NO; + [self.daysContainer addGestureRecognizer:panGesture]; + _scopeGesture = panGesture; + } + return _scopeGesture; +} + +- (UILongPressGestureRecognizer *)swipeToChooseGesture +{ + if (!_swipeToChooseGesture) { + UILongPressGestureRecognizer *pressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleSwipeToChoose:)]; + pressGesture.enabled = NO; + pressGesture.numberOfTapsRequired = 0; + pressGesture.numberOfTouchesRequired = 1; + pressGesture.minimumPressDuration = 0.7; + [self.daysContainer addGestureRecognizer:pressGesture]; + [self.collectionView.panGestureRecognizer requireGestureRecognizerToFail:pressGesture]; + _swipeToChooseGesture = pressGesture; + } + return _swipeToChooseGesture; +} + +- (void)setDataSource:(id)dataSource +{ + self.dataSourceProxy.delegation = dataSource; +} + +- (id)dataSource +{ + return self.dataSourceProxy.delegation; +} + +- (void)setDelegate:(id)delegate +{ + self.delegateProxy.delegation = delegate; +} + +- (id)delegate +{ + return self.delegateProxy.delegation; +} + +#pragma mark - Public methods + +- (void)reloadData +{ + _needsRequestingBoundingDates = YES; + if ([self requestBoundingDatesIfNecessary] || !self.collectionView.indexPathsForVisibleItems.count) { + [self invalidateHeaders]; + } + [self.collectionView reloadData]; +} + +- (void)setScope:(FSCalendarScope)scope animated:(BOOL)animated +{ + if (self.floatingMode) return; + if (self.transitionCoordinator.state != FSCalendarTransitionStateIdle) return; + + FSCalendarScope prevScope = _scope; + [self willChangeValueForKey:@"scope"]; + _scope = scope; + [self didChangeValueForKey:@"scope"]; + + if (prevScope == scope) return; + + if (!self.hasValidateVisibleLayout && prevScope == FSCalendarScopeMonth && scope == FSCalendarScopeWeek) { + _needsLayoutForWeekMode = YES; + [self setNeedsLayout]; + } else if (self.transitionCoordinator.state == FSCalendarTransitionStateIdle) { + [self.transitionCoordinator performScopeTransitionFromScope:prevScope toScope:scope animated:animated]; + } + +} + +- (void)setPlaceholderType:(FSCalendarPlaceholderType)placeholderType +{ + if (_placeholderType != placeholderType) { + _placeholderType = placeholderType; + if (self.hasValidateVisibleLayout) { + _preferredRowHeight = FSCalendarAutomaticDimension; + [_collectionView reloadData]; + } + } +} + +- (void)selectDate:(NSDate *)date +{ + [self selectDate:date scrollToDate:YES]; +} + +- (void)selectDate:(NSDate *)date scrollToDate:(BOOL)scrollToDate +{ + [self selectDate:date scrollToDate:scrollToDate atMonthPosition:FSCalendarMonthPositionCurrent]; +} + +- (void)deselectDate:(NSDate *)date +{ + date = [self.gregorian dateBySettingHour:0 minute:0 second:0 ofDate:date options:0]; + if (![_selectedDates containsObject:date]) { + return; + } + [_selectedDates removeObject:date]; + [self deselectCounterpartDate:date]; + NSIndexPath *indexPath = [self.calculator indexPathForDate:date]; + if ([_collectionView.indexPathsForSelectedItems containsObject:indexPath]) { + [_collectionView deselectItemAtIndexPath:indexPath animated:YES]; + FSCalendarCell *cell = (FSCalendarCell *)[_collectionView cellForItemAtIndexPath:indexPath]; + cell.selected = NO; + [cell configureAppearance]; + } +} + +- (void)selectDate:(NSDate *)date scrollToDate:(BOOL)scrollToDate atMonthPosition:(FSCalendarMonthPosition)monthPosition +{ + if (!self.allowsSelection || !date) return; + + [self requestBoundingDatesIfNecessary]; + + FSCalendarAssertDateInBounds(date,self.gregorian,self.minimumDate,self.maximumDate); + + NSDate *targetDate = [self.gregorian dateBySettingHour:0 minute:0 second:0 ofDate:date options:0]; + NSIndexPath *targetIndexPath = [self.calculator indexPathForDate:targetDate]; + + BOOL shouldSelect = YES; + // 跨月份点击 + if (monthPosition==FSCalendarMonthPositionPrevious||monthPosition==FSCalendarMonthPositionNext) { + if (self.allowsMultipleSelection) { + if ([self isDateSelected:targetDate]) { + BOOL shouldDeselect = ![self.delegateProxy respondsToSelector:@selector(calendar:shouldDeselectDate:atMonthPosition:)] || [self.delegateProxy calendar:self shouldDeselectDate:targetDate atMonthPosition:monthPosition]; + if (!shouldDeselect) { + return; + } + } else { + shouldSelect &= (![self.delegateProxy respondsToSelector:@selector(calendar:shouldSelectDate:atMonthPosition:)] || [self.delegateProxy calendar:self shouldSelectDate:targetDate atMonthPosition:monthPosition]); + if (!shouldSelect) { + return; + } + [_collectionView selectItemAtIndexPath:targetIndexPath animated:YES scrollPosition:UICollectionViewScrollPositionNone]; + [self collectionView:_collectionView didSelectItemAtIndexPath:targetIndexPath]; + } + } else { + shouldSelect &= (![self.delegateProxy respondsToSelector:@selector(calendar:shouldSelectDate:atMonthPosition:)] || [self.delegateProxy calendar:self shouldSelectDate:targetDate atMonthPosition:monthPosition]); + if (shouldSelect) { + if ([self isDateSelected:targetDate]) { + [self.delegateProxy calendar:self didSelectDate:targetDate atMonthPosition:monthPosition]; + } else { + NSDate *selectedDate = self.selectedDate; + if (selectedDate) { + [self deselectDate:selectedDate]; + } + [_collectionView selectItemAtIndexPath:targetIndexPath animated:YES scrollPosition:UICollectionViewScrollPositionNone]; + [self collectionView:_collectionView didSelectItemAtIndexPath:targetIndexPath]; + } + } else { + return; + } + } + + } else if (![self isDateSelected:targetDate]){ + if (self.selectedDate && !self.allowsMultipleSelection) { + [self deselectDate:self.selectedDate]; + } + [_collectionView selectItemAtIndexPath:targetIndexPath animated:NO scrollPosition:UICollectionViewScrollPositionNone]; + FSCalendarCell *cell = (FSCalendarCell *)[_collectionView cellForItemAtIndexPath:targetIndexPath]; + [cell performSelecting]; + [self enqueueSelectedDate:targetDate]; + [self selectCounterpartDate:targetDate]; + + } else if (![_collectionView.indexPathsForSelectedItems containsObject:targetIndexPath]) { + [_collectionView selectItemAtIndexPath:targetIndexPath animated:NO scrollPosition:UICollectionViewScrollPositionNone]; + } + + if (scrollToDate) { + if (!shouldSelect) { + return; + } + [self scrollToPageForDate:targetDate animated:YES]; + } +} + +- (void)handleScopeGesture:(UIPanGestureRecognizer *)sender +{ + if (self.floatingMode) return; + [self.transitionCoordinator handleScopeGesture:sender]; +} + +#pragma mark - Private methods + +- (void)scrollToDate:(NSDate *)date +{ + [self scrollToDate:date animated:NO]; +} + +- (void)scrollToDate:(NSDate *)date animated:(BOOL)animated +{ + if (!_minimumDate || !_maximumDate) { + return; + } + animated &= _scrollEnabled; // No animation if _scrollEnabled == NO; + + date = [self.calculator safeDateForDate:date]; + NSInteger scrollOffset = [self.calculator indexPathForDate:date atMonthPosition:FSCalendarMonthPositionCurrent].section; + + if (!self.floatingMode) { + switch (_collectionViewLayout.scrollDirection) { + case UICollectionViewScrollDirectionVertical: { + [_collectionView setContentOffset:CGPointMake(0, scrollOffset * _collectionView.fs_height) animated:animated]; + break; + } + case UICollectionViewScrollDirectionHorizontal: { + [_collectionView setContentOffset:CGPointMake(scrollOffset * _collectionView.fs_width, 0) animated:animated]; + break; + } + } + + } else if (self.hasValidateVisibleLayout) { + [_collectionViewLayout layoutAttributesForElementsInRect:_collectionView.bounds]; + CGRect headerFrame = [_collectionViewLayout layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:[NSIndexPath indexPathForItem:0 inSection:scrollOffset]].frame; + CGPoint targetOffset = CGPointMake(0, MIN(headerFrame.origin.y,MAX(0,_collectionViewLayout.collectionViewContentSize.height-_collectionView.fs_bottom))); + [_collectionView setContentOffset:targetOffset animated:animated]; + } + if (!animated) { + self.calendarHeaderView.scrollOffset = scrollOffset; + } +} + +- (void)scrollToPageForDate:(NSDate *)date animated:(BOOL)animated +{ + if (!date) return; + if (![self isDateInRange:date]) { + date = [self.calculator safeDateForDate:date]; + if (!date) return; + } + + if (!self.floatingMode) { + if ([self isDateInDifferentPage:date]) { + [self willChangeValueForKey:@"currentPage"]; + NSDate *lastPage = _currentPage; + switch (self.transitionCoordinator.representingScope) { + case FSCalendarScopeMonth: { + _currentPage = [self.gregorian fs_firstDayOfMonth:date]; + break; + } + case FSCalendarScopeWeek: { + _currentPage = [self.gregorian fs_firstDayOfWeek:date]; + break; + } + } + if (self.hasValidateVisibleLayout) { + [self.delegateProxy calendarCurrentPageDidChange:self]; + if (_placeholderType != FSCalendarPlaceholderTypeFillSixRows && self.transitionCoordinator.state == FSCalendarTransitionStateIdle) { + [self.transitionCoordinator performBoundingRectTransitionFromMonth:lastPage toMonth:_currentPage duration:0.33]; + } + } + [self didChangeValueForKey:@"currentPage"]; + } + [self scrollToDate:_currentPage animated:animated]; + } else { + [self scrollToDate:[self.gregorian fs_firstDayOfMonth:date] animated:animated]; + } +} + + +- (BOOL)isDateInRange:(NSDate *)date +{ + BOOL flag = YES; + flag &= [self.gregorian components:NSCalendarUnitDay fromDate:date toDate:self.minimumDate options:0].day <= 0; + flag &= [self.gregorian components:NSCalendarUnitDay fromDate:date toDate:self.maximumDate options:0].day >= 0;; + return flag; +} + +- (BOOL)isPageInRange:(NSDate *)page +{ + BOOL flag = YES; + switch (self.transitionCoordinator.representingScope) { + case FSCalendarScopeMonth: { + NSDateComponents *c1 = [self.gregorian components:NSCalendarUnitDay fromDate:[self.gregorian fs_firstDayOfMonth:self.minimumDate] toDate:page options:0]; + flag &= (c1.day>=0); + if (!flag) break; + NSDateComponents *c2 = [self.gregorian components:NSCalendarUnitDay fromDate:page toDate:[self.gregorian fs_lastDayOfMonth:self.maximumDate] options:0]; + flag &= (c2.day>=0); + break; + } + case FSCalendarScopeWeek: { + NSDateComponents *c1 = [self.gregorian components:NSCalendarUnitDay fromDate:[self.gregorian fs_firstDayOfWeek:self.minimumDate] toDate:page options:0]; + flag &= (c1.day>=0); + if (!flag) break; + NSDateComponents *c2 = [self.gregorian components:NSCalendarUnitDay fromDate:page toDate:[self.gregorian fs_lastDayOfWeek:self.maximumDate] options:0]; + flag &= (c2.day>=0); + break; + } + default: + break; + } + return flag; +} + +- (BOOL)isDateSelected:(NSDate *)date +{ + return [_selectedDates containsObject:date] || [_collectionView.indexPathsForSelectedItems containsObject:[self.calculator indexPathForDate:date]]; +} + +- (BOOL)isDateInDifferentPage:(NSDate *)date +{ + if (self.floatingMode) { + return ![self.gregorian isDate:date equalToDate:_currentPage toUnitGranularity:NSCalendarUnitMonth]; + } + switch (_scope) { + case FSCalendarScopeMonth: + return ![self.gregorian isDate:date equalToDate:_currentPage toUnitGranularity:NSCalendarUnitMonth]; + case FSCalendarScopeWeek: + return ![self.gregorian isDate:date equalToDate:_currentPage toUnitGranularity:NSCalendarUnitWeekOfYear]; + } +} + +- (BOOL)hasValidateVisibleLayout +{ +#if TARGET_INTERFACE_BUILDER + return YES; +#else + return self.superview && !CGRectIsEmpty(_collectionView.frame) && !CGSizeEqualToSize(_collectionViewLayout.collectionViewContentSize, CGSizeZero); +#endif +} + +- (void)invalidateDateTools +{ + _gregorian.locale = _locale; + _gregorian.timeZone = _timeZone; + _gregorian.firstWeekday = _firstWeekday; + _components.calendar = _gregorian; + _components.timeZone = _timeZone; + _formatter.calendar = _gregorian; + _formatter.timeZone = _timeZone; + _formatter.locale = _locale; +} + +- (void)invalidateLayout +{ + if (!self.floatingMode) { + + if (!_calendarHeaderView) { + + FSCalendarHeaderView *headerView = [[FSCalendarHeaderView alloc] initWithFrame:CGRectZero]; + headerView.scrollEnabled = _scrollEnabled; + [_contentView addSubview:headerView]; + self.calendarHeaderView = headerView; + } + self.calendarHeaderView.calendar = self; + + if (!_calendarWeekdayView) { + FSCalendarWeekdayView *calendarWeekdayView = [[FSCalendarWeekdayView alloc] initWithFrame:CGRectZero]; + calendarWeekdayView.calendar = self; + [_contentView addSubview:calendarWeekdayView]; + _calendarWeekdayView = calendarWeekdayView; + } + + if (_scrollEnabled) { + if (!_deliver) { + FSCalendarHeaderTouchDeliver *deliver = [[FSCalendarHeaderTouchDeliver alloc] initWithFrame:CGRectZero]; + deliver.header = _calendarHeaderView; + deliver.calendar = self; + [_contentView addSubview:deliver]; + self.deliver = deliver; + } + } else if (_deliver) { + [_deliver removeFromSuperview]; + } + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + if (self.showsScopeHandle) { + if (!_scopeHandle) { + FSCalendarScopeHandle *handle = [[FSCalendarScopeHandle alloc] initWithFrame:CGRectZero]; + handle.calendar = self; + [self addSubview:handle]; + self.scopeHandle = handle; + _needsAdjustingViewFrame = YES; + [self setNeedsLayout]; + } + } else { + if (_scopeHandle) { + [self.scopeHandle removeFromSuperview]; + _needsAdjustingViewFrame = YES; + [self setNeedsLayout]; + } + } +#pragma GCC diagnostic pop + + _collectionView.pagingEnabled = YES; + _collectionViewLayout.scrollDirection = (UICollectionViewScrollDirection)self.scrollDirection; + + } else { + + [self.calendarHeaderView removeFromSuperview]; + [self.deliver removeFromSuperview]; + [self.calendarWeekdayView removeFromSuperview]; + [self.scopeHandle removeFromSuperview]; + + _collectionView.pagingEnabled = NO; + _collectionViewLayout.scrollDirection = UICollectionViewScrollDirectionVertical; + + } + + _preferredHeaderHeight = FSCalendarAutomaticDimension; + _preferredWeekdayHeight = FSCalendarAutomaticDimension; + _preferredRowHeight = FSCalendarAutomaticDimension; + _needsAdjustingViewFrame = YES; + [self setNeedsLayout]; +} + +- (void)invalidateHeaders +{ + [self.calendarHeaderView.collectionView reloadData]; + [self.visibleStickyHeaders makeObjectsPerformSelector:@selector(configureAppearance)]; +} + +- (void)invalidateAppearanceForCell:(FSCalendarCell *)cell forDate:(NSDate *)date +{ +#define FSCalendarInvalidateCellAppearance(SEL1,SEL2) \ + cell.SEL1 = [self.delegateProxy calendar:self appearance:self.appearance SEL2:date]; + +#define FSCalendarInvalidateCellAppearanceWithDefault(SEL1,SEL2,DEFAULT) \ + if ([self.delegateProxy respondsToSelector:@selector(calendar:appearance:SEL2:)]) { \ + cell.SEL1 = [self.delegateProxy calendar:self appearance:self.appearance SEL2:date]; \ + } else { \ + cell.SEL1 = DEFAULT; \ + } + + FSCalendarInvalidateCellAppearance(preferredFillDefaultColor,fillDefaultColorForDate); + FSCalendarInvalidateCellAppearance(preferredFillSelectionColor,fillSelectionColorForDate); + FSCalendarInvalidateCellAppearance(preferredTitleDefaultColor,titleDefaultColorForDate); + FSCalendarInvalidateCellAppearance(preferredTitleSelectionColor,titleSelectionColorForDate); + + FSCalendarInvalidateCellAppearanceWithDefault(preferredTitleOffset,titleOffsetForDate,CGPointInfinity); + if (cell.subtitle) { + FSCalendarInvalidateCellAppearance(preferredSubtitleDefaultColor,subtitleDefaultColorForDate); + FSCalendarInvalidateCellAppearance(preferredSubtitleSelectionColor,subtitleSelectionColorForDate); + FSCalendarInvalidateCellAppearanceWithDefault(preferredSubtitleOffset,subtitleOffsetForDate,CGPointInfinity); + } + if (cell.numberOfEvents) { + FSCalendarInvalidateCellAppearance(preferredEventDefaultColors,eventDefaultColorsForDate); + FSCalendarInvalidateCellAppearance(preferredEventSelectionColors,eventSelectionColorsForDate); + FSCalendarInvalidateCellAppearanceWithDefault(preferredEventOffset,eventOffsetForDate,CGPointInfinity); + } + FSCalendarInvalidateCellAppearance(preferredBorderDefaultColor,borderDefaultColorForDate); + FSCalendarInvalidateCellAppearance(preferredBorderSelectionColor,borderSelectionColorForDate); + FSCalendarInvalidateCellAppearanceWithDefault(preferredBorderRadius,borderRadiusForDate,-1); + + if (cell.image) { + FSCalendarInvalidateCellAppearanceWithDefault(preferredImageOffset,imageOffsetForDate,CGPointInfinity); + } + +#undef FSCalendarInvalidateCellAppearance +#undef FSCalendarInvalidateCellAppearanceWithDefault + +} + +- (void)reloadDataForCell:(FSCalendarCell *)cell atIndexPath:(NSIndexPath *)indexPath +{ + cell.calendar = self; + NSDate *date = [self.calculator dateForIndexPath:indexPath]; + cell.image = [self.dataSourceProxy calendar:self imageForDate:date]; + cell.numberOfEvents = [self.dataSourceProxy calendar:self numberOfEventsForDate:date]; + cell.titleLabel.text = [self.dataSourceProxy calendar:self titleForDate:date] ?: @([self.gregorian component:NSCalendarUnitDay fromDate:date]).stringValue; + cell.subtitle = [self.dataSourceProxy calendar:self subtitleForDate:date]; + cell.selected = [_selectedDates containsObject:date]; + cell.dateIsToday = self.today?[self.gregorian isDate:date inSameDayAsDate:self.today]:NO; + cell.weekend = [self.gregorian isDateInWeekend:date]; + cell.monthPosition = [self.calculator monthPositionForIndexPath:indexPath]; + switch (self.transitionCoordinator.representingScope) { + case FSCalendarScopeMonth: { + cell.placeholder = (cell.monthPosition == FSCalendarMonthPositionPrevious || cell.monthPosition == FSCalendarMonthPositionNext) || ![self isDateInRange:date]; + if (cell.placeholder) { + cell.selected &= _pagingEnabled; + cell.dateIsToday &= _pagingEnabled; + } + break; + } + case FSCalendarScopeWeek: { + cell.placeholder = ![self isDateInRange:date]; + break; + } + } + // Synchronize selecion state to the collection view, otherwise delegate methods would not be triggered. + if (cell.selected) { + [self.collectionView selectItemAtIndexPath:indexPath animated:NO scrollPosition:UICollectionViewScrollPositionNone]; + } else { + [self.collectionView deselectItemAtIndexPath:indexPath animated:NO]; + } + [self invalidateAppearanceForCell:cell forDate:date]; + [cell configureAppearance]; +} + + +- (void)handleSwipeToChoose:(UILongPressGestureRecognizer *)pressGesture +{ + switch (pressGesture.state) { + case UIGestureRecognizerStateBegan: + case UIGestureRecognizerStateChanged: { + NSIndexPath *indexPath = [self.collectionView indexPathForItemAtPoint:[pressGesture locationInView:self.collectionView]]; + if (indexPath && ![indexPath isEqual:self.lastPressedIndexPath]) { + NSDate *date = [self.calculator dateForIndexPath:indexPath]; + FSCalendarMonthPosition monthPosition = [self.calculator monthPositionForIndexPath:indexPath]; + if (![self.selectedDates containsObject:date] && [self collectionView:self.collectionView shouldSelectItemAtIndexPath:indexPath]) { + [self selectDate:date scrollToDate:NO atMonthPosition:monthPosition]; + [self collectionView:self.collectionView didSelectItemAtIndexPath:indexPath]; + } else if (self.collectionView.allowsMultipleSelection && [self collectionView:self.collectionView shouldDeselectItemAtIndexPath:indexPath]) { + [self deselectDate:date]; + [self collectionView:self.collectionView didDeselectItemAtIndexPath:indexPath]; + } + } + self.lastPressedIndexPath = indexPath; + break; + } + case UIGestureRecognizerStateEnded: + case UIGestureRecognizerStateCancelled: { + self.lastPressedIndexPath = nil; + break; + } + default: + break; + } + +} + +- (void)selectCounterpartDate:(NSDate *)date +{ + if (_placeholderType == FSCalendarPlaceholderTypeNone) return; + if (self.scope == FSCalendarScopeWeek) return; + NSInteger numberOfDays = [self.gregorian fs_numberOfDaysInMonth:date]; + NSInteger day = [self.gregorian component:NSCalendarUnitDay fromDate:date]; + FSCalendarCell *cell; + if (day < numberOfDays/2+1) { + cell = [self cellForDate:date atMonthPosition:FSCalendarMonthPositionNext]; + } else { + cell = [self cellForDate:date atMonthPosition:FSCalendarMonthPositionPrevious]; + } + if (cell) { + cell.selected = YES; + if (self.collectionView.allowsMultipleSelection) { + [self.collectionView selectItemAtIndexPath:[self.collectionView indexPathForCell:cell] animated:NO scrollPosition:UICollectionViewScrollPositionNone]; + } + } + [cell configureAppearance]; +} + +- (void)deselectCounterpartDate:(NSDate *)date +{ + if (_placeholderType == FSCalendarPlaceholderTypeNone) return; + if (self.scope == FSCalendarScopeWeek) return; + NSInteger numberOfDays = [self.gregorian fs_numberOfDaysInMonth:date]; + NSInteger day = [self.gregorian component:NSCalendarUnitDay fromDate:date]; + FSCalendarCell *cell; + if (day < numberOfDays/2+1) { + cell = [self cellForDate:date atMonthPosition:FSCalendarMonthPositionNext]; + } else { + cell = [self cellForDate:date atMonthPosition:FSCalendarMonthPositionPrevious]; + } + if (cell) { + cell.selected = NO; + [self.collectionView deselectItemAtIndexPath:[self.collectionView indexPathForCell:cell] animated:NO]; + } + [cell configureAppearance]; +} + +- (void)enqueueSelectedDate:(NSDate *)date +{ + if (!self.allowsMultipleSelection) { + [_selectedDates removeAllObjects]; + } + if (![_selectedDates containsObject:date]) { + [_selectedDates addObject:date]; + } +} + +- (NSArray *)visibleStickyHeaders +{ + return [self.visibleSectionHeaders.dictionaryRepresentation allValues]; +} + +- (void)invalidateViewFrames +{ + _needsAdjustingViewFrame = YES; + + _preferredHeaderHeight = FSCalendarAutomaticDimension; + _preferredWeekdayHeight = FSCalendarAutomaticDimension; + _preferredRowHeight = FSCalendarAutomaticDimension; + + [self.calendarHeaderView setNeedsAdjustingViewFrame:YES]; + [self setNeedsLayout]; + +} + +// The best way to detect orientation +// http://stackoverflow.com/questions/25830448/what-is-the-best-way-to-detect-orientation-in-an-app-extension/26023538#26023538 +- (FSCalendarOrientation)currentCalendarOrientation +{ + CGFloat scale = [UIScreen mainScreen].scale; + CGSize nativeSize = [UIScreen mainScreen].currentMode.size; + CGSize sizeInPoints = [UIScreen mainScreen].bounds.size; + FSCalendarOrientation orientation = scale * sizeInPoints.width == nativeSize.width ? FSCalendarOrientationPortrait : FSCalendarOrientationLandscape; + return orientation; +} + +- (void)adjustMonthPosition +{ + [self requestBoundingDatesIfNecessary]; + NSDate *targetPage = self.pagingEnabled?self.currentPage:(self.currentPage?:self.selectedDate); + [self scrollToPageForDate:targetPage animated:NO]; + self.calendarHeaderView.needsAdjustingMonthPosition = YES; +} + +- (BOOL)requestBoundingDatesIfNecessary +{ + if (_needsRequestingBoundingDates) { + _needsRequestingBoundingDates = NO; + + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + dateFormatter.dateFormat = @"yyyy-MM-dd"; + + self.formatter.dateFormat = @"yyyy-MM-dd"; + NSDate *newMin = [self.dataSourceProxy minimumDateForCalendar:self]?:[dateFormatter dateFromString:@"1970-01-01"]; + newMin = [self.gregorian dateBySettingHour:0 minute:0 second:0 ofDate:newMin options:0]; + NSDate *newMax = [self.dataSourceProxy maximumDateForCalendar:self]?:[dateFormatter dateFromString:@"2099-12-31"]; + newMax = [self.gregorian dateBySettingHour:0 minute:0 second:0 ofDate:newMax options:0]; + + NSAssert([self.gregorian compareDate:newMin toDate:newMax toUnitGranularity:NSCalendarUnitDay] != NSOrderedDescending, @"The minimum date of calendar should be earlier than the maximum."); + + BOOL res = ![self.gregorian isDate:newMin inSameDayAsDate:_minimumDate] || ![self.gregorian isDate:newMax inSameDayAsDate:_maximumDate]; + _minimumDate = newMin; + _maximumDate = newMax; + [self.calculator reloadSections]; + + return res; + } + return NO; +} + +- (void)configureAppearance +{ + [self.visibleCells makeObjectsPerformSelector:@selector(configureAppearance)]; + [self.visibleStickyHeaders makeObjectsPerformSelector:@selector(configureAppearance)]; + [self.calendarHeaderView configureAppearance]; + [self.calendarWeekdayView configureAppearance]; +} + +-(NSString *)convertEnNumberToFarsi:(NSString *) number{ + NSString *text; + NSDecimalNumber *someNumber = [NSDecimalNumber decimalNumberWithString:number]; + NSNumberFormatter *formatter = [[NSNumberFormatter alloc] init]; + [formatter setLocale:self.locale]; + text = [formatter stringFromNumber:someNumber]; + return text; +} + +-(BOOL) isPersianCalender{ + return [self.calendarIdentifier isRTLCalendar]; +} + +@end + + diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarAppearance.h b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarAppearance.h new file mode 100644 index 0000000..31af862 --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarAppearance.h @@ -0,0 +1,236 @@ +// +// FSCalendarAppearance.h +// Pods +// +// Created by DingWenchao on 6/29/15. +// Copyright © 2016 Wenchao Ding. All rights reserved. +// +// https://github.com/Husseinhj +// + +#import "FSCalendarConstants.h" + +@class FSCalendar; + +typedef NS_ENUM(NSInteger, FSCalendarCellState) { + FSCalendarCellStateNormal = 0, + FSCalendarCellStateSelected = 1, + FSCalendarCellStatePlaceholder = 1 << 1, + FSCalendarCellStateDisabled = 1 << 2, + FSCalendarCellStateToday = 1 << 3, + FSCalendarCellStateWeekend = 1 << 4, + FSCalendarCellStateTodaySelected = FSCalendarCellStateToday|FSCalendarCellStateSelected +}; + +typedef NS_ENUM(NSUInteger, FSCalendarSeparators) { + FSCalendarSeparatorNone = 0, + FSCalendarSeparatorInterRows = 1 +}; + +typedef NS_OPTIONS(NSUInteger, FSCalendarCaseOptions) { + FSCalendarCaseOptionsHeaderUsesDefaultCase = 0, + FSCalendarCaseOptionsHeaderUsesUpperCase = 1, + + FSCalendarCaseOptionsWeekdayUsesDefaultCase = 0 << 4, + FSCalendarCaseOptionsWeekdayUsesUpperCase = 1 << 4, + FSCalendarCaseOptionsWeekdayUsesSingleUpperCase = 2 << 4, +}; + +/** + * FSCalendarAppearance determines the fonts and colors of components in the calendar. + * + * @see FSCalendarDelegateAppearance + */ +@interface FSCalendarAppearance : NSObject + +/** + * The font of the day text. + */ +@property (strong, nonatomic) UIFont *titleFont; + +/** + * The font of the subtitle text. + */ +@property (strong, nonatomic) UIFont *subtitleFont; + +/** + * The font of the weekday text. + */ +@property (strong, nonatomic) UIFont *weekdayFont; + +/** + * The font of the month text. + */ +@property (strong, nonatomic) UIFont *headerTitleFont; + +/** + * The offset of the day text from default position. + */ +@property (assign, nonatomic) CGPoint titleOffset; + +/** + * The offset of the day text from default position. + */ +@property (assign, nonatomic) CGPoint subtitleOffset; + +/** + * The offset of the event dots from default position. + */ +@property (assign, nonatomic) CGPoint eventOffset; + +/** + * The offset of the image from default position. + */ +@property (assign, nonatomic) CGPoint imageOffset; + +/** + * The color of event dots. + */ +@property (strong, nonatomic) UIColor *eventDefaultColor; + +/** + * The color of event dots. + */ +@property (strong, nonatomic) UIColor *eventSelectionColor; + +/** + * The color of weekday text. + */ +@property (strong, nonatomic) UIColor *weekdayTextColor; + +/** + * The color of month header text. + */ +@property (strong, nonatomic) UIColor *headerTitleColor; + +/** + * The date format of the month header. + */ +@property (strong, nonatomic) NSString *headerDateFormat; + +/** + * The alpha value of month label staying on the fringes. + */ +@property (assign, nonatomic) CGFloat headerMinimumDissolvedAlpha; + +/** + * The day text color for unselected state. + */ +@property (strong, nonatomic) UIColor *titleDefaultColor; + +/** + * The day text color for selected state. + */ +@property (strong, nonatomic) UIColor *titleSelectionColor; + +/** + * The day text color for today in the calendar. + */ +@property (strong, nonatomic) UIColor *titleTodayColor; + +/** + * The day text color for days out of current month. + */ +@property (strong, nonatomic) UIColor *titlePlaceholderColor; + +/** + * The day text color for weekend. + */ +@property (strong, nonatomic) UIColor *titleWeekendColor; + +/** + * The subtitle text color for unselected state. + */ +@property (strong, nonatomic) UIColor *subtitleDefaultColor; + +/** + * The subtitle text color for selected state. + */ +@property (strong, nonatomic) UIColor *subtitleSelectionColor; + +/** + * The subtitle text color for today in the calendar. + */ +@property (strong, nonatomic) UIColor *subtitleTodayColor; + +/** + * The subtitle text color for days out of current month. + */ +@property (strong, nonatomic) UIColor *subtitlePlaceholderColor; + +/** + * The subtitle text color for weekend. + */ +@property (strong, nonatomic) UIColor *subtitleWeekendColor; + +/** + * The fill color of the shape for selected state. + */ +@property (strong, nonatomic) UIColor *selectionColor; + +/** + * The fill color of the shape for today. + */ +@property (strong, nonatomic) UIColor *todayColor; + +/** + * The fill color of the shape for today and selected state. + */ +@property (strong, nonatomic) UIColor *todaySelectionColor; + +/** + * The border color of the shape for unselected state. + */ +@property (strong, nonatomic) UIColor *borderDefaultColor; + +/** + * The border color of the shape for selected state. + */ +@property (strong, nonatomic) UIColor *borderSelectionColor; + +/** + * The border radius, while 1 means a circle, 0 means a rectangle, and the middle value will give it a corner radius. + */ +@property (assign, nonatomic) CGFloat borderRadius; + +/** + * The case options manage the case of month label and weekday symbols. + * + * @see FSCalendarCaseOptions + */ +@property (assign, nonatomic) FSCalendarCaseOptions caseOptions; + +/** + * The line integrations for calendar. + * + */ +@property (assign, nonatomic) FSCalendarSeparators separators; + +#if TARGET_INTERFACE_BUILDER + +// For preview only +@property (assign, nonatomic) BOOL fakeSubtitles; +@property (assign, nonatomic) BOOL fakeEventDots; +@property (assign, nonatomic) NSInteger fakedSelectedDay; + +#endif + +@end + +/** + * These functions and attributes are deprecated. + */ +@interface FSCalendarAppearance (Deprecated) + +@property (assign, nonatomic) BOOL useVeryShortWeekdaySymbols FSCalendarDeprecated('caseOptions'); +@property (assign, nonatomic) CGFloat titleVerticalOffset FSCalendarDeprecated('titleOffset'); +@property (assign, nonatomic) CGFloat subtitleVerticalOffset FSCalendarDeprecated('subtitleOffset'); +@property (strong, nonatomic) UIColor *eventColor FSCalendarDeprecated('eventDefaultColor'); +@property (assign, nonatomic) FSCalendarCellShape cellShape FSCalendarDeprecated('borderRadius'); +@property (assign, nonatomic) BOOL adjustsFontSizeToFitContentSize DEPRECATED_MSG_ATTRIBUTE("The attribute \'adjustsFontSizeToFitContentSize\' is not neccesary anymore."); +- (void)invalidateAppearance FSCalendarDeprecated('FSCalendar setNeedsConfigureAppearance'); + +@end + + + diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarAppearance.m b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarAppearance.m new file mode 100644 index 0000000..b97b02e --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarAppearance.m @@ -0,0 +1,523 @@ +// +// FSCalendarAppearance.m +// Pods +// +// Created by DingWenchao on 6/29/15. +// Copyright © 2016 Wenchao Ding. All rights reserved. +// +// https://github.com/Husseinhj +// + +#import "FSCalendarAppearance.h" +#import "FSCalendarDynamicHeader.h" +#import "FSCalendarExtensions.h" + +@interface FSCalendarAppearance () + +@property (weak , nonatomic) FSCalendar *calendar; + +@property (strong, nonatomic) NSMutableDictionary *backgroundColors; +@property (strong, nonatomic) NSMutableDictionary *titleColors; +@property (strong, nonatomic) NSMutableDictionary *subtitleColors; +@property (strong, nonatomic) NSMutableDictionary *borderColors; + +@end + +@implementation FSCalendarAppearance + +- (instancetype)init +{ + self = [super init]; + if (self) { + + _titleFont = [UIFont systemFontOfSize:FSCalendarStandardTitleTextSize]; + _subtitleFont = [UIFont systemFontOfSize:FSCalendarStandardSubtitleTextSize]; + _weekdayFont = [UIFont systemFontOfSize:FSCalendarStandardWeekdayTextSize]; + _headerTitleFont = [UIFont systemFontOfSize:FSCalendarStandardHeaderTextSize]; + + _headerTitleColor = FSCalendarStandardTitleTextColor; + _headerDateFormat = @"MMMM yyyy"; + _headerMinimumDissolvedAlpha = 0.2; + _weekdayTextColor = FSCalendarStandardTitleTextColor; + _caseOptions = FSCalendarCaseOptionsHeaderUsesDefaultCase|FSCalendarCaseOptionsWeekdayUsesDefaultCase; + + _backgroundColors = [NSMutableDictionary dictionaryWithCapacity:5]; + _backgroundColors[@(FSCalendarCellStateNormal)] = [UIColor clearColor]; + _backgroundColors[@(FSCalendarCellStateSelected)] = FSCalendarStandardSelectionColor; + _backgroundColors[@(FSCalendarCellStateDisabled)] = [UIColor clearColor]; + _backgroundColors[@(FSCalendarCellStatePlaceholder)] = [UIColor clearColor]; + _backgroundColors[@(FSCalendarCellStateToday)] = FSCalendarStandardTodayColor; + + _titleColors = [NSMutableDictionary dictionaryWithCapacity:5]; + _titleColors[@(FSCalendarCellStateNormal)] = [UIColor blackColor]; + _titleColors[@(FSCalendarCellStateSelected)] = [UIColor whiteColor]; + _titleColors[@(FSCalendarCellStateDisabled)] = [UIColor grayColor]; + _titleColors[@(FSCalendarCellStatePlaceholder)] = [UIColor lightGrayColor]; + _titleColors[@(FSCalendarCellStateToday)] = [UIColor whiteColor]; + + _subtitleColors = [NSMutableDictionary dictionaryWithCapacity:5]; + _subtitleColors[@(FSCalendarCellStateNormal)] = [UIColor darkGrayColor]; + _subtitleColors[@(FSCalendarCellStateSelected)] = [UIColor whiteColor]; + _subtitleColors[@(FSCalendarCellStateDisabled)] = [UIColor lightGrayColor]; + _subtitleColors[@(FSCalendarCellStatePlaceholder)] = [UIColor lightGrayColor]; + _subtitleColors[@(FSCalendarCellStateToday)] = [UIColor whiteColor]; + + _borderColors[@(FSCalendarCellStateSelected)] = [UIColor clearColor]; + _borderColors[@(FSCalendarCellStateNormal)] = [UIColor clearColor]; + + _borderRadius = 1.0; + _eventDefaultColor = FSCalendarStandardEventDotColor; + _eventSelectionColor = FSCalendarStandardEventDotColor; + + _borderColors = [NSMutableDictionary dictionaryWithCapacity:2]; + +#if TARGET_INTERFACE_BUILDER + _fakeEventDots = YES; +#endif + + } + return self; +} + +- (void)setTitleFont:(UIFont *)titleFont +{ + if (![_titleFont isEqual:titleFont]) { + _titleFont = titleFont; + [self.calendar configureAppearance]; + } +} + +- (void)setSubtitleFont:(UIFont *)subtitleFont +{ + if (![_subtitleFont isEqual:subtitleFont]) { + _subtitleFont = subtitleFont; + [self.calendar configureAppearance]; + } +} + +- (void)setWeekdayFont:(UIFont *)weekdayFont +{ + if (![_weekdayFont isEqual:weekdayFont]) { + _weekdayFont = weekdayFont; + [self.calendar configureAppearance]; + } +} + +- (void)setHeaderTitleFont:(UIFont *)headerTitleFont +{ + if (![_headerTitleFont isEqual:headerTitleFont]) { + _headerTitleFont = headerTitleFont; + [self.calendar configureAppearance]; + } +} + +- (void)setTitleOffset:(CGPoint)titleOffset +{ + if (!CGPointEqualToPoint(_titleOffset, titleOffset)) { + _titleOffset = titleOffset; + [_calendar.visibleCells makeObjectsPerformSelector:@selector(setNeedsLayout)]; + } +} + +- (void)setSubtitleOffset:(CGPoint)subtitleOffset +{ + if (!CGPointEqualToPoint(_subtitleOffset, subtitleOffset)) { + _subtitleOffset = subtitleOffset; + [_calendar.visibleCells makeObjectsPerformSelector:@selector(setNeedsLayout)]; + } +} + +- (void)setImageOffset:(CGPoint)imageOffset +{ + if (!CGPointEqualToPoint(_imageOffset, imageOffset)) { + _imageOffset = imageOffset; + [_calendar.visibleCells makeObjectsPerformSelector:@selector(setNeedsLayout)]; + } +} + +- (void)setEventOffset:(CGPoint)eventOffset +{ + if (!CGPointEqualToPoint(_eventOffset, eventOffset)) { + _eventOffset = eventOffset; + [_calendar.visibleCells makeObjectsPerformSelector:@selector(setNeedsLayout)]; + } +} + +- (void)setTitleDefaultColor:(UIColor *)color +{ + if (color) { + _titleColors[@(FSCalendarCellStateNormal)] = color; + } else { + [_titleColors removeObjectForKey:@(FSCalendarCellStateNormal)]; + } + [self.calendar configureAppearance]; +} + +- (UIColor *)titleDefaultColor +{ + return _titleColors[@(FSCalendarCellStateNormal)]; +} + +- (void)setTitleSelectionColor:(UIColor *)color +{ + if (color) { + _titleColors[@(FSCalendarCellStateSelected)] = color; + } else { + [_titleColors removeObjectForKey:@(FSCalendarCellStateSelected)]; + } + [self.calendar configureAppearance]; +} + +- (UIColor *)titleSelectionColor +{ + return _titleColors[@(FSCalendarCellStateSelected)]; +} + +- (void)setTitleTodayColor:(UIColor *)color +{ + if (color) { + _titleColors[@(FSCalendarCellStateToday)] = color; + } else { + [_titleColors removeObjectForKey:@(FSCalendarCellStateToday)]; + } + [self.calendar configureAppearance]; +} + +- (UIColor *)titleTodayColor +{ + return _titleColors[@(FSCalendarCellStateToday)]; +} + +- (void)setTitlePlaceholderColor:(UIColor *)color +{ + if (color) { + _titleColors[@(FSCalendarCellStatePlaceholder)] = color; + } else { + [_titleColors removeObjectForKey:@(FSCalendarCellStatePlaceholder)]; + } + [self.calendar configureAppearance]; +} + +- (UIColor *)titlePlaceholderColor +{ + return _titleColors[@(FSCalendarCellStatePlaceholder)]; +} + +- (void)setTitleWeekendColor:(UIColor *)color +{ + if (color) { + _titleColors[@(FSCalendarCellStateWeekend)] = color; + } else { + [_titleColors removeObjectForKey:@(FSCalendarCellStateWeekend)]; + } + [self.calendar configureAppearance]; +} + +- (UIColor *)titleWeekendColor +{ + return _titleColors[@(FSCalendarCellStateWeekend)]; +} + +- (void)setSubtitleDefaultColor:(UIColor *)color +{ + if (color) { + _subtitleColors[@(FSCalendarCellStateNormal)] = color; + } else { + [_subtitleColors removeObjectForKey:@(FSCalendarCellStateNormal)]; + } + [self.calendar configureAppearance]; +} + +-(UIColor *)subtitleDefaultColor +{ + return _subtitleColors[@(FSCalendarCellStateNormal)]; +} + +- (void)setSubtitleSelectionColor:(UIColor *)color +{ + if (color) { + _subtitleColors[@(FSCalendarCellStateSelected)] = color; + } else { + [_subtitleColors removeObjectForKey:@(FSCalendarCellStateSelected)]; + } + [self.calendar configureAppearance]; +} + +- (UIColor *)subtitleSelectionColor +{ + return _subtitleColors[@(FSCalendarCellStateSelected)]; +} + +- (void)setSubtitleTodayColor:(UIColor *)color +{ + if (color) { + _subtitleColors[@(FSCalendarCellStateToday)] = color; + } else { + [_subtitleColors removeObjectForKey:@(FSCalendarCellStateToday)]; + } + [self.calendar configureAppearance]; +} + +- (UIColor *)subtitleTodayColor +{ + return _subtitleColors[@(FSCalendarCellStateToday)]; +} + +- (void)setSubtitlePlaceholderColor:(UIColor *)color +{ + if (color) { + _subtitleColors[@(FSCalendarCellStatePlaceholder)] = color; + } else { + [_subtitleColors removeObjectForKey:@(FSCalendarCellStatePlaceholder)]; + } + [self.calendar configureAppearance]; +} + +- (UIColor *)subtitlePlaceholderColor +{ + return _subtitleColors[@(FSCalendarCellStatePlaceholder)]; +} + +- (void)setSubtitleWeekendColor:(UIColor *)color +{ + if (color) { + _subtitleColors[@(FSCalendarCellStateWeekend)] = color; + } else { + [_subtitleColors removeObjectForKey:@(FSCalendarCellStateWeekend)]; + } + [self.calendar configureAppearance]; +} + +- (UIColor *)subtitleWeekendColor +{ + return _subtitleColors[@(FSCalendarCellStateWeekend)]; +} + +- (void)setSelectionColor:(UIColor *)color +{ + if (color) { + _backgroundColors[@(FSCalendarCellStateSelected)] = color; + } else { + [_backgroundColors removeObjectForKey:@(FSCalendarCellStateSelected)]; + } + [self.calendar configureAppearance]; +} + +- (UIColor *)selectionColor +{ + return _backgroundColors[@(FSCalendarCellStateSelected)]; +} + +- (void)setTodayColor:(UIColor *)todayColor +{ + if (todayColor) { + _backgroundColors[@(FSCalendarCellStateToday)] = todayColor; + } else { + [_backgroundColors removeObjectForKey:@(FSCalendarCellStateToday)]; + } + [self.calendar configureAppearance]; +} + +- (UIColor *)todayColor +{ + return _backgroundColors[@(FSCalendarCellStateToday)]; +} + +- (void)setTodaySelectionColor:(UIColor *)todaySelectionColor +{ + if (todaySelectionColor) { + _backgroundColors[@(FSCalendarCellStateToday|FSCalendarCellStateSelected)] = todaySelectionColor; + } else { + [_backgroundColors removeObjectForKey:@(FSCalendarCellStateToday|FSCalendarCellStateSelected)]; + } + [self.calendar configureAppearance]; +} + +- (UIColor *)todaySelectionColor +{ + return _backgroundColors[@(FSCalendarCellStateToday|FSCalendarCellStateSelected)]; +} + +- (void)setEventDefaultColor:(UIColor *)eventDefaultColor +{ + if (![_eventDefaultColor isEqual:eventDefaultColor]) { + _eventDefaultColor = eventDefaultColor; + [self.calendar configureAppearance]; + } +} + +- (void)setBorderDefaultColor:(UIColor *)color +{ + if (color) { + _borderColors[@(FSCalendarCellStateNormal)] = color; + } else { + [_borderColors removeObjectForKey:@(FSCalendarCellStateNormal)]; + } + [self.calendar configureAppearance]; +} + +- (UIColor *)borderDefaultColor +{ + return _borderColors[@(FSCalendarCellStateNormal)]; +} + +- (void)setBorderSelectionColor:(UIColor *)color +{ + if (color) { + _borderColors[@(FSCalendarCellStateSelected)] = color; + } else { + [_borderColors removeObjectForKey:@(FSCalendarCellStateSelected)]; + } + [self.calendar configureAppearance]; +} + +- (UIColor *)borderSelectionColor +{ + return _borderColors[@(FSCalendarCellStateSelected)]; +} + +- (void)setBorderRadius:(CGFloat)borderRadius +{ + borderRadius = MAX(0.0, borderRadius); + borderRadius = MIN(1.0, borderRadius); + if (_borderRadius != borderRadius) { + _borderRadius = borderRadius; + [self.calendar configureAppearance]; + } +} + +- (void)setWeekdayTextColor:(UIColor *)weekdayTextColor +{ + if (![_weekdayTextColor isEqual:weekdayTextColor]) { + _weekdayTextColor = weekdayTextColor; + [self.calendar configureAppearance]; + } +} + +- (void)setHeaderTitleColor:(UIColor *)color +{ + if (![_headerTitleColor isEqual:color]) { + _headerTitleColor = color; + [self.calendar configureAppearance]; + } +} + +- (void)setHeaderMinimumDissolvedAlpha:(CGFloat)headerMinimumDissolvedAlpha +{ + if (_headerMinimumDissolvedAlpha != headerMinimumDissolvedAlpha) { + _headerMinimumDissolvedAlpha = headerMinimumDissolvedAlpha; + [self.calendar configureAppearance]; + } +} + +- (void)setHeaderDateFormat:(NSString *)headerDateFormat +{ + if (![_headerDateFormat isEqual:headerDateFormat]) { + _headerDateFormat = headerDateFormat; + [self.calendar configureAppearance]; + } +} + +- (void)setCaseOptions:(FSCalendarCaseOptions)caseOptions +{ + if (_caseOptions != caseOptions) { + _caseOptions = caseOptions; + [self.calendar configureAppearance]; + } +} + +- (void)setSeparators:(FSCalendarSeparators)separators +{ + if (_separators != separators) { + _separators = separators; + [_calendar.collectionView.collectionViewLayout invalidateLayout]; + } +} + +@end + + +@implementation FSCalendarAppearance (Deprecated) + +- (void)setUseVeryShortWeekdaySymbols:(BOOL)useVeryShortWeekdaySymbols +{ + _caseOptions &= 15; + self.caseOptions |= (useVeryShortWeekdaySymbols*FSCalendarCaseOptionsWeekdayUsesSingleUpperCase); +} + +- (BOOL)useVeryShortWeekdaySymbols +{ + return (_caseOptions & (15<<4) ) == FSCalendarCaseOptionsWeekdayUsesSingleUpperCase; +} + +- (void)setTitleVerticalOffset:(CGFloat)titleVerticalOffset +{ + self.titleOffset = CGPointMake(0, titleVerticalOffset); +} + +- (CGFloat)titleVerticalOffset +{ + return self.titleOffset.y; +} + +- (void)setSubtitleVerticalOffset:(CGFloat)subtitleVerticalOffset +{ + self.subtitleOffset = CGPointMake(0, subtitleVerticalOffset); +} + +- (CGFloat)subtitleVerticalOffset +{ + return self.subtitleOffset.y; +} + +- (void)setEventColor:(UIColor *)eventColor +{ + self.eventDefaultColor = eventColor; +} + +- (UIColor *)eventColor +{ + return self.eventDefaultColor; +} + +- (void)setCellShape:(FSCalendarCellShape)cellShape +{ + self.borderRadius = 1-cellShape; +} + +- (FSCalendarCellShape)cellShape +{ + return self.borderRadius==1.0?FSCalendarCellShapeCircle:FSCalendarCellShapeRectangle; +} + +- (void)setTitleTextSize:(CGFloat)titleTextSize +{ + self.titleFont = [UIFont fontWithName:self.titleFont.fontName size:titleTextSize]; +} + +- (void)setSubtitleTextSize:(CGFloat)subtitleTextSize +{ + self.subtitleFont = [UIFont fontWithName:self.subtitleFont.fontName size:subtitleTextSize]; +} + +- (void)setWeekdayTextSize:(CGFloat)weekdayTextSize +{ + self.weekdayFont = [UIFont fontWithName:self.weekdayFont.fontName size:weekdayTextSize]; +} + +- (void)setHeaderTitleTextSize:(CGFloat)headerTitleTextSize +{ + self.headerTitleFont = [UIFont fontWithName:self.headerTitleFont.fontName size:headerTitleTextSize]; +} + +- (void)invalidateAppearance +{ + [self.calendar configureAppearance]; +} + +- (void)setAdjustsFontSizeToFitContentSize:(BOOL)adjustsFontSizeToFitContentSize {} +- (BOOL)adjustsFontSizeToFitContentSize { return YES; } + +@end + + diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarCalculator.h b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarCalculator.h new file mode 100644 index 0000000..7e9acf8 --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarCalculator.h @@ -0,0 +1,49 @@ +// +// FSCalendarCalculator.h +// FSCalendar +// +// Created by dingwenchao on 30/10/2016. +// Copyright © 2016 Wenchao Ding. All rights reserved. +// + +#import +#import + +struct FSCalendarCoordinate { + NSInteger row; + NSInteger column; +}; +typedef struct FSCalendarCoordinate FSCalendarCoordinate; + +@interface FSCalendarCalculator : NSObject + +@property (weak , nonatomic) FSCalendar *calendar; + +@property (readonly, nonatomic) NSInteger numberOfSections; + +- (instancetype)initWithCalendar:(FSCalendar *)calendar; + +- (NSDate *)safeDateForDate:(NSDate *)date; + +- (NSDate *)dateForIndexPath:(NSIndexPath *)indexPath; +- (NSDate *)dateForIndexPath:(NSIndexPath *)indexPath scope:(FSCalendarScope)scope; +- (NSIndexPath *)indexPathForDate:(NSDate *)date; +- (NSIndexPath *)indexPathForDate:(NSDate *)date scope:(FSCalendarScope)scope; +- (NSIndexPath *)indexPathForDate:(NSDate *)date atMonthPosition:(FSCalendarMonthPosition)position; +- (NSIndexPath *)indexPathForDate:(NSDate *)date atMonthPosition:(FSCalendarMonthPosition)position scope:(FSCalendarScope)scope; + +- (NSDate *)pageForSection:(NSInteger)section; +- (NSDate *)weekForSection:(NSInteger)section; +- (NSDate *)monthForSection:(NSInteger)section; +- (NSDate *)monthHeadForSection:(NSInteger)section; + +- (NSInteger)numberOfHeadPlaceholdersForMonth:(NSDate *)month; +- (NSInteger)numberOfRowsInMonth:(NSDate *)month; +- (NSInteger)numberOfRowsInSection:(NSInteger)section; + +- (FSCalendarMonthPosition)monthPositionForIndexPath:(NSIndexPath *)indexPath; +- (FSCalendarCoordinate)coordinateForIndexPath:(NSIndexPath *)indexPath; + +- (void)reloadSections; + +@end diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarCalculator.m b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarCalculator.m new file mode 100644 index 0000000..3b9d5b5 --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarCalculator.m @@ -0,0 +1,299 @@ +// +// FSCalendarCalculator.m +// FSCalendar +// +// Created by dingwenchao on 30/10/2016. +// Copyright © 2016 Wenchao Ding. All rights reserved. +// + +#import "FSCalendar.h" +#import "FSCalendarCalculator.h" +#import "FSCalendarDynamicHeader.h" +#import "FSCalendarExtensions.h" + +@interface FSCalendarCalculator () + +@property (assign, nonatomic) NSInteger numberOfMonths; +@property (strong, nonatomic) NSMutableDictionary *months; +@property (strong, nonatomic) NSMutableDictionary *monthHeads; + +@property (assign, nonatomic) NSInteger numberOfWeeks; +@property (strong, nonatomic) NSMutableDictionary *weeks; +@property (strong, nonatomic) NSMutableDictionary *rowCounts; + +@property (readonly, nonatomic) NSCalendar *gregorian; +@property (readonly, nonatomic) NSDate *minimumDate; +@property (readonly, nonatomic) NSDate *maximumDate; + +- (void)didReceiveNotifications:(NSNotification *)notification; + +@end + +@implementation FSCalendarCalculator + +@dynamic gregorian,minimumDate,maximumDate; + +- (instancetype)initWithCalendar:(FSCalendar *)calendar +{ + self = [super init]; + if (self) { + self.calendar = calendar; + + self.months = [NSMutableDictionary dictionary]; + self.monthHeads = [NSMutableDictionary dictionary]; + self.weeks = [NSMutableDictionary dictionary]; + self.rowCounts = [NSMutableDictionary dictionary]; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveNotifications:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; + } + return self; +} + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; +} + +- (id)forwardingTargetForSelector:(SEL)selector +{ + if ([self.calendar respondsToSelector:selector]) { + return self.calendar; + } + return [super forwardingTargetForSelector:selector]; +} + +#pragma mark - Public functions + +- (NSDate *)safeDateForDate:(NSDate *)date +{ + if ([self.gregorian compareDate:date toDate:self.minimumDate toUnitGranularity:NSCalendarUnitDay] == NSOrderedAscending) { + date = self.minimumDate; + } else if ([self.gregorian compareDate:date toDate:self.maximumDate toUnitGranularity:NSCalendarUnitDay] == NSOrderedDescending) { + date = self.maximumDate; + } + return date; +} + +- (NSDate *)dateForIndexPath:(NSIndexPath *)indexPath scope:(FSCalendarScope)scope +{ + if (!indexPath) return nil; + switch (scope) { + case FSCalendarScopeMonth: { + NSDate *head = [self monthHeadForSection:indexPath.section]; + NSUInteger daysOffset = indexPath.item; + NSDate *date = [self.gregorian dateByAddingUnit:NSCalendarUnitDay value:daysOffset toDate:head options:0]; + return date; + break; + } + case FSCalendarScopeWeek: { + NSDate *currentPage = [self weekForSection:indexPath.section]; + NSDate *date = [self.gregorian dateByAddingUnit:NSCalendarUnitDay value:indexPath.item toDate:currentPage options:0]; + return date; + } + } + return nil; +} + +- (NSDate *)dateForIndexPath:(NSIndexPath *)indexPath +{ + if (!indexPath) return nil; + return [self dateForIndexPath:indexPath scope:self.calendar.transitionCoordinator.representingScope]; +} + +- (NSIndexPath *)indexPathForDate:(NSDate *)date +{ + return [self indexPathForDate:date atMonthPosition:FSCalendarMonthPositionCurrent scope:self.calendar.transitionCoordinator.representingScope]; +} + +- (NSIndexPath *)indexPathForDate:(NSDate *)date scope:(FSCalendarScope)scope +{ + return [self indexPathForDate:date atMonthPosition:FSCalendarMonthPositionCurrent scope:scope]; +} + +- (NSIndexPath *)indexPathForDate:(NSDate *)date atMonthPosition:(FSCalendarMonthPosition)position scope:(FSCalendarScope)scope +{ + if (!date) return nil; + NSInteger item = 0; + NSInteger section = 0; + switch (scope) { + case FSCalendarScopeMonth: { + section = [self.gregorian components:NSCalendarUnitMonth fromDate:[self.gregorian fs_firstDayOfMonth:self.minimumDate] toDate:[self.gregorian fs_firstDayOfMonth:date] options:0].month; + if (position == FSCalendarMonthPositionPrevious) { + section++; + } else if (position == FSCalendarMonthPositionNext) { + section--; + } + NSDate *head = [self monthHeadForSection:section]; + item = [self.gregorian components:NSCalendarUnitDay fromDate:head toDate:date options:0].day; + break; + } + case FSCalendarScopeWeek: { + section = [self.gregorian components:NSCalendarUnitWeekOfYear fromDate:[self.gregorian fs_firstDayOfWeek:self.minimumDate] toDate:[self.gregorian fs_firstDayOfWeek:date] options:0].weekOfYear; + item = (([self.gregorian component:NSCalendarUnitWeekday fromDate:date] - self.gregorian.firstWeekday) + 7) % 7; + break; + } + } + if (item < 0 || section < 0) { + return nil; + } + NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:section]; + return indexPath; +} + +- (NSIndexPath *)indexPathForDate:(NSDate *)date atMonthPosition:(FSCalendarMonthPosition)position +{ + return [self indexPathForDate:date atMonthPosition:position scope:self.calendar.transitionCoordinator.representingScope]; +} + +- (NSDate *)pageForSection:(NSInteger)section +{ + switch (self.calendar.transitionCoordinator.representingScope) { + case FSCalendarScopeWeek: + return [self.gregorian fs_middleDayOfWeek:[self weekForSection:section]]; + case FSCalendarScopeMonth: + return [self monthForSection:section]; + default: + break; + } +} + +- (NSDate *)monthForSection:(NSInteger)section +{ + NSNumber *key = @(section); + NSDate *month = self.months[key]; + if (!month) { + month = [self.gregorian dateByAddingUnit:NSCalendarUnitMonth value:section toDate:[self.gregorian fs_firstDayOfMonth:self.minimumDate] options:0]; + NSInteger numberOfHeadPlaceholders = [self numberOfHeadPlaceholdersForMonth:month]; + NSDate *monthHead = [self.gregorian dateByAddingUnit:NSCalendarUnitDay value:-numberOfHeadPlaceholders toDate:month options:0]; + self.months[key] = month; + self.monthHeads[key] = monthHead; + } + return month; +} + +- (NSDate *)monthHeadForSection:(NSInteger)section +{ + NSNumber *key = @(section); + NSDate *monthHead = self.monthHeads[key]; + if (!monthHead) { + NSDate *month = [self.gregorian dateByAddingUnit:NSCalendarUnitMonth value:section toDate:[self.gregorian fs_firstDayOfMonth:self.minimumDate] options:0]; + NSInteger numberOfHeadPlaceholders = [self numberOfHeadPlaceholdersForMonth:month]; + monthHead = [self.gregorian dateByAddingUnit:NSCalendarUnitDay value:-numberOfHeadPlaceholders toDate:month options:0]; + self.months[key] = month; + self.monthHeads[key] = monthHead; + } + return monthHead; +} + +- (NSDate *)weekForSection:(NSInteger)section +{ + NSNumber *key = @(section); + NSDate *week = self.weeks[key]; + if (!week) { + week = [self.gregorian dateByAddingUnit:NSCalendarUnitWeekOfYear value:section toDate:[self.gregorian fs_firstDayOfWeek:self.minimumDate] options:0]; + self.weeks[key] = week; + } + return week; +} + +- (NSInteger)numberOfSections +{ + if (self.calendar.transitionCoordinator.transition == FSCalendarTransitionWeekToMonth) { + return self.numberOfMonths; + } else { + switch (self.calendar.transitionCoordinator.representingScope) { + case FSCalendarScopeMonth: { + return self.numberOfMonths; + } + case FSCalendarScopeWeek: { + return self.numberOfWeeks; + } + } + } +} + +- (NSInteger)numberOfHeadPlaceholdersForMonth:(NSDate *)month +{ + NSInteger currentWeekday = [self.gregorian component:NSCalendarUnitWeekday fromDate:month]; + NSInteger number = ((currentWeekday- self.gregorian.firstWeekday) + 7) % 7 ?: (7 * (!self.calendar.floatingMode&&(self.calendar.placeholderType == FSCalendarPlaceholderTypeFillSixRows))); + return number; +} + +- (NSInteger)numberOfRowsInMonth:(NSDate *)month +{ + if (!month) return 0; + if (self.calendar.placeholderType == FSCalendarPlaceholderTypeFillSixRows) return 6; + + NSNumber *rowCount = self.rowCounts[month]; + if (!rowCount) { + NSDate *firstDayOfMonth = [self.gregorian fs_firstDayOfMonth:month]; + NSInteger weekdayOfFirstDay = [self.gregorian component:NSCalendarUnitWeekday fromDate:firstDayOfMonth]; + NSInteger numberOfDaysInMonth = [self.gregorian fs_numberOfDaysInMonth:month]; + NSInteger numberOfPlaceholdersForPrev = ((weekdayOfFirstDay - self.gregorian.firstWeekday) + 7) % 7; + NSInteger headDayCount = numberOfDaysInMonth + numberOfPlaceholdersForPrev; + NSInteger numberOfRows = (headDayCount/7) + (headDayCount%7>0); + rowCount = @(numberOfRows); + self.rowCounts[month] = rowCount; + } + return rowCount.integerValue; +} + +- (NSInteger)numberOfRowsInSection:(NSInteger)section +{ + if (self.calendar.transitionCoordinator.representingScope == FSCalendarScopeWeek) return 1; + NSDate *month = [self monthForSection:section]; + return [self numberOfRowsInMonth:month]; +} + +- (FSCalendarMonthPosition)monthPositionForIndexPath:(NSIndexPath *)indexPath +{ + if (!indexPath) return FSCalendarMonthPositionNotFound; + if (self.calendar.transitionCoordinator.representingScope == FSCalendarScopeWeek) { + return FSCalendarMonthPositionCurrent; + } + NSDate *date = [self dateForIndexPath:indexPath]; + NSDate *page = [self pageForSection:indexPath.section]; + NSComparisonResult comparison = [self.gregorian compareDate:date toDate:page toUnitGranularity:NSCalendarUnitMonth]; + switch (comparison) { + case NSOrderedAscending: + return FSCalendarMonthPositionPrevious; + case NSOrderedSame: + return FSCalendarMonthPositionCurrent; + case NSOrderedDescending: + return FSCalendarMonthPositionNext; + } +} + +- (FSCalendarCoordinate)coordinateForIndexPath:(NSIndexPath *)indexPath +{ + FSCalendarCoordinate coordinate; + coordinate.row = indexPath.item / 7; + coordinate.column = indexPath.item % 7; + return coordinate; +} + +- (void)reloadSections +{ + self.numberOfMonths = [self.gregorian components:NSCalendarUnitMonth fromDate:[self.gregorian fs_firstDayOfMonth:self.minimumDate] toDate:self.maximumDate options:0].month+1; + self.numberOfWeeks = [self.gregorian components:NSCalendarUnitWeekOfYear fromDate:[self.gregorian fs_firstDayOfWeek:self.minimumDate] toDate:self.maximumDate options:0].weekOfYear+1; + [self clearCaches]; +} + +- (void)clearCaches +{ + [self.months removeAllObjects]; + [self.monthHeads removeAllObjects]; + [self.weeks removeAllObjects]; + [self.rowCounts removeAllObjects]; +} + +#pragma mark - Private functinos + +- (void)didReceiveNotifications:(NSNotification *)notification +{ + if ([notification.name isEqualToString:UIApplicationDidReceiveMemoryWarningNotification]) { + [self clearCaches]; + } +} + +@end diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarCell.h b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarCell.h new file mode 100644 index 0000000..f252b3b --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarCell.h @@ -0,0 +1,107 @@ +// +// FSCalendarCell.h +// Pods +// +// Created by Wenchao Ding on 12/3/15. +// +// + +#import + +@class FSCalendar, FSCalendarAppearance, FSCalendarEventIndicator; + +typedef NS_ENUM(NSUInteger, FSCalendarMonthPosition); + +@interface FSCalendarCell : UICollectionViewCell + +#pragma mark - Public properties + +/** + The day text label of the cell + */ +@property (weak, nonatomic) UILabel *titleLabel; + + +/** + The subtitle label of the cell + */ +@property (weak, nonatomic) UILabel *subtitleLabel; + + +/** + The shape layer of the cell + */ +@property (weak, nonatomic) CAShapeLayer *shapeLayer; + +/** + The imageView below shape layer of the cell + */ +@property (weak, nonatomic) UIImageView *imageView; + + +/** + The collection of event dots of the cell + */ +@property (weak, nonatomic) FSCalendarEventIndicator *eventIndicator; + +/** + A boolean value indicates that whether the cell is "placeholder". Default is NO. + */ +@property (assign, nonatomic, getter=isPlaceholder) BOOL placeholder; + +#pragma mark - Private properties + +@property (weak, nonatomic) FSCalendar *calendar; +@property (weak, nonatomic) FSCalendarAppearance *appearance; + +@property (strong, nonatomic) NSString *subtitle; +@property (strong, nonatomic) UIImage *image; +@property (assign, nonatomic) FSCalendarMonthPosition monthPosition; + +@property (assign, nonatomic) NSInteger numberOfEvents; +@property (assign, nonatomic) BOOL dateIsToday; +@property (assign, nonatomic) BOOL weekend; + +@property (strong, nonatomic) UIColor *preferredFillDefaultColor; +@property (strong, nonatomic) UIColor *preferredFillSelectionColor; +@property (strong, nonatomic) UIColor *preferredTitleDefaultColor; +@property (strong, nonatomic) UIColor *preferredTitleSelectionColor; +@property (strong, nonatomic) UIColor *preferredSubtitleDefaultColor; +@property (strong, nonatomic) UIColor *preferredSubtitleSelectionColor; +@property (strong, nonatomic) UIColor *preferredBorderDefaultColor; +@property (strong, nonatomic) UIColor *preferredBorderSelectionColor; +@property (assign, nonatomic) CGPoint preferredTitleOffset; +@property (assign, nonatomic) CGPoint preferredSubtitleOffset; +@property (assign, nonatomic) CGPoint preferredImageOffset; +@property (assign, nonatomic) CGPoint preferredEventOffset; + +@property (strong, nonatomic) NSArray *preferredEventDefaultColors; +@property (strong, nonatomic) NSArray *preferredEventSelectionColors; +@property (assign, nonatomic) CGFloat preferredBorderRadius; + +// Add subviews to self.contentView and set up constraints +- (instancetype)initWithFrame:(CGRect)frame NS_REQUIRES_SUPER; +- (instancetype)initWithCoder:(NSCoder *)aDecoder NS_REQUIRES_SUPER; + +// For DIY overridden +- (void)layoutSubviews NS_REQUIRES_SUPER; // Configure frames of subviews +- (void)configureAppearance NS_REQUIRES_SUPER; // Configure appearance for cell + +- (UIColor *)colorForCurrentStateInDictionary:(NSDictionary *)dictionary; +- (void)performSelecting; + +@end + +@interface FSCalendarEventIndicator : UIView + +@property (assign, nonatomic) NSInteger numberOfEvents; +@property (strong, nonatomic) id color; + +@end + +@interface FSCalendarBlankCell : UICollectionViewCell + +- (void)configureAppearance; + +@end + diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarCell.m b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarCell.m new file mode 100644 index 0000000..50e4bf2 --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarCell.m @@ -0,0 +1,473 @@ +// +// FSCalendarCell.m +// Pods +// +// Created by Wenchao Ding on 12/3/15. +// +// + +#import "FSCalendarCell.h" +#import "FSCalendar.h" +#import "FSCalendarExtensions.h" +#import "FSCalendarDynamicHeader.h" +#import "FSCalendarConstants.h" + +@interface FSCalendarCell () + +@property (readonly, nonatomic) UIColor *colorForCellFill; +@property (readonly, nonatomic) UIColor *colorForTitleLabel; +@property (readonly, nonatomic) UIColor *colorForSubtitleLabel; +@property (readonly, nonatomic) UIColor *colorForCellBorder; +@property (readonly, nonatomic) NSArray *colorsForEvents; +@property (readonly, nonatomic) CGFloat borderRadius; + +@end + +@implementation FSCalendarCell + +#pragma mark - Life cycle + +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + [self commonInit]; + } + return self; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder +{ + self = [super initWithCoder:aDecoder]; + if (self) { + [self commonInit]; + } + return self; +} + +- (void)commonInit +{ + UILabel *label; + CAShapeLayer *shapeLayer; + UIImageView *imageView; + FSCalendarEventIndicator *eventIndicator; + + label = [[UILabel alloc] initWithFrame:CGRectZero]; + label.textAlignment = NSTextAlignmentCenter; + label.textColor = [UIColor blackColor]; + [self.contentView addSubview:label]; + self.titleLabel = label; + + label = [[UILabel alloc] initWithFrame:CGRectZero]; + label.textAlignment = NSTextAlignmentCenter; + label.textColor = [UIColor lightGrayColor]; + [self.contentView addSubview:label]; + self.subtitleLabel = label; + + shapeLayer = [CAShapeLayer layer]; + shapeLayer.backgroundColor = [UIColor clearColor].CGColor; + shapeLayer.borderWidth = 1.0; + shapeLayer.borderColor = [UIColor clearColor].CGColor; + shapeLayer.opacity = 0; + [self.contentView.layer insertSublayer:shapeLayer below:_titleLabel.layer]; + self.shapeLayer = shapeLayer; + + eventIndicator = [[FSCalendarEventIndicator alloc] initWithFrame:CGRectZero]; + eventIndicator.backgroundColor = [UIColor clearColor]; + eventIndicator.hidden = YES; + [self.contentView addSubview:eventIndicator]; + self.eventIndicator = eventIndicator; + + imageView = [[UIImageView alloc] initWithFrame:CGRectZero]; + imageView.contentMode = UIViewContentModeBottom|UIViewContentModeCenter; + [self.contentView addSubview:imageView]; + self.imageView = imageView; + + self.clipsToBounds = NO; + self.contentView.clipsToBounds = NO; + +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + if (_subtitle) { + _subtitleLabel.text = _subtitle; + if (_subtitleLabel.hidden) { + _subtitleLabel.hidden = NO; + } + } else { + if (!_subtitleLabel.hidden) { + _subtitleLabel.hidden = YES; + } + } + + if (_subtitle) { + CGFloat titleHeight = self.titleLabel.font.lineHeight; + CGFloat subtitleHeight = self.subtitleLabel.font.lineHeight; + + CGFloat height = titleHeight + subtitleHeight; + _titleLabel.frame = CGRectMake( + self.preferredTitleOffset.x, + (self.contentView.fs_height*5.0/6.0-height)*0.5+self.preferredTitleOffset.y, + self.contentView.fs_width, + titleHeight + ); + _subtitleLabel.frame = CGRectMake( + self.preferredSubtitleOffset.x, + (_titleLabel.fs_bottom-self.preferredTitleOffset.y) - (_titleLabel.fs_height-_titleLabel.font.pointSize)+self.preferredSubtitleOffset.y, + self.contentView.fs_width, + subtitleHeight + ); + } else { + _titleLabel.frame = CGRectMake( + self.preferredTitleOffset.x, + self.preferredTitleOffset.y, + self.contentView.fs_width, + floor(self.contentView.fs_height*5.0/6.0) + ); + } + + _imageView.frame = CGRectMake(self.preferredImageOffset.x, self.preferredImageOffset.y, self.contentView.fs_width, self.contentView.fs_height); + + CGFloat titleHeight = self.bounds.size.height*5.0/6.0; + CGFloat diameter = MIN(self.bounds.size.height*5.0/6.0,self.bounds.size.width); + diameter = diameter > FSCalendarStandardCellDiameter ? (diameter - (diameter-FSCalendarStandardCellDiameter)*0.5) : diameter; + _shapeLayer.frame = CGRectMake((self.bounds.size.width-diameter)/2, + (titleHeight-diameter)/2, + diameter, + diameter); + + CGPathRef path = [UIBezierPath bezierPathWithRoundedRect:_shapeLayer.bounds + cornerRadius:CGRectGetWidth(_shapeLayer.bounds)*0.5*self.borderRadius].CGPath; + if (!CGPathEqualToPath(_shapeLayer.path,path)) { + _shapeLayer.path = path; + } + + CGFloat eventSize = _shapeLayer.frame.size.height/6.0; + _eventIndicator.frame = CGRectMake( + self.preferredEventOffset.x, + CGRectGetMaxY(_shapeLayer.frame)+eventSize*0.17+self.preferredEventOffset.y, + self.fs_width, + eventSize*0.83 + ); + +} + +- (void)prepareForReuse +{ + [super prepareForReuse]; + if (self.window) { // Avoid interrupt of navigation transition somehow + [CATransaction setDisableActions:YES]; // Avoid blink of shape layer. + } + self.shapeLayer.opacity = 0; + [self.contentView.layer removeAnimationForKey:@"opacity"]; +} + +#pragma mark - Public + +- (void)performSelecting +{ + _shapeLayer.opacity = 1; + +#define kAnimationDuration FSCalendarDefaultBounceAnimationDuration + + CAAnimationGroup *group = [CAAnimationGroup animation]; + CABasicAnimation *zoomOut = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; + zoomOut.fromValue = @0.3; + zoomOut.toValue = @1.2; + zoomOut.duration = kAnimationDuration/4*3; + CABasicAnimation *zoomIn = [CABasicAnimation animationWithKeyPath:@"transform.scale"]; + zoomIn.fromValue = @1.2; + zoomIn.toValue = @1.0; + zoomIn.beginTime = kAnimationDuration/4*3; + zoomIn.duration = kAnimationDuration/4; + group.duration = kAnimationDuration; + group.animations = @[zoomOut, zoomIn]; + [_shapeLayer addAnimation:group forKey:@"bounce"]; + [self configureAppearance]; + +#undef kAnimationDuration + +} + +#pragma mark - Private + +- (void)configureAppearance +{ + UIColor *textColor = self.colorForTitleLabel; + if (![textColor isEqual:_titleLabel.textColor]) { + _titleLabel.textColor = textColor; + } + UIFont *titleFont = self.calendar.appearance.titleFont; + if (![titleFont isEqual:_titleLabel.font]) { + _titleLabel.font = titleFont; + } + if (_subtitle) { + textColor = self.colorForSubtitleLabel; + if (![textColor isEqual:_subtitleLabel.textColor]) { + _subtitleLabel.textColor = textColor; + } + titleFont = self.calendar.appearance.subtitleFont; + if (![titleFont isEqual:_subtitleLabel.font]) { + _subtitleLabel.font = titleFont; + } + } + + UIColor *borderColor = self.colorForCellBorder; + UIColor *fillColor = self.colorForCellFill; + + BOOL shouldHideShapeLayer = !self.selected && !self.dateIsToday && !borderColor && !fillColor; + + if (_shapeLayer.opacity == shouldHideShapeLayer) { + _shapeLayer.opacity = !shouldHideShapeLayer; + } + if (!shouldHideShapeLayer) { + + CGColorRef cellFillColor = self.colorForCellFill.CGColor; + if (!CGColorEqualToColor(_shapeLayer.fillColor, cellFillColor)) { + _shapeLayer.fillColor = cellFillColor; + } + + CGColorRef cellBorderColor = self.colorForCellBorder.CGColor; + if (!CGColorEqualToColor(_shapeLayer.strokeColor, cellBorderColor)) { + _shapeLayer.strokeColor = cellBorderColor; + } + + CGPathRef path = [UIBezierPath bezierPathWithRoundedRect:_shapeLayer.bounds + cornerRadius:CGRectGetWidth(_shapeLayer.bounds)*0.5*self.borderRadius].CGPath; + if (!CGPathEqualToPath(_shapeLayer.path, path)) { + _shapeLayer.path = path; + } + + } + + if (![_image isEqual:_imageView.image]) { + _imageView.image = _image; + _imageView.hidden = !_image; + } + + if (_eventIndicator.hidden == (_numberOfEvents > 0)) { + _eventIndicator.hidden = !_numberOfEvents; + } + + _eventIndicator.numberOfEvents = self.numberOfEvents; + _eventIndicator.color = self.colorsForEvents; + +} + +- (UIColor *)colorForCurrentStateInDictionary:(NSDictionary *)dictionary +{ + if (self.isSelected) { + if (self.dateIsToday) { + return dictionary[@(FSCalendarCellStateSelected|FSCalendarCellStateToday)] ?: dictionary[@(FSCalendarCellStateSelected)]; + } + return dictionary[@(FSCalendarCellStateSelected)]; + } + if (self.dateIsToday && [[dictionary allKeys] containsObject:@(FSCalendarCellStateToday)]) { + return dictionary[@(FSCalendarCellStateToday)]; + } + if (self.placeholder && [[dictionary allKeys] containsObject:@(FSCalendarCellStatePlaceholder)]) { + return dictionary[@(FSCalendarCellStatePlaceholder)]; + } + if (self.weekend && [[dictionary allKeys] containsObject:@(FSCalendarCellStateWeekend)]) { + return dictionary[@(FSCalendarCellStateWeekend)]; + } + return dictionary[@(FSCalendarCellStateNormal)]; +} + +#pragma mark - Properties + +- (UIColor *)colorForCellFill +{ + if (self.selected) { + return self.preferredFillSelectionColor ?: [self colorForCurrentStateInDictionary:_appearance.backgroundColors]; + } + return self.preferredFillDefaultColor ?: [self colorForCurrentStateInDictionary:_appearance.backgroundColors]; +} + +- (UIColor *)colorForTitleLabel +{ + if (self.selected) { + return self.preferredTitleSelectionColor ?: [self colorForCurrentStateInDictionary:_appearance.titleColors]; + } + return self.preferredTitleDefaultColor ?: [self colorForCurrentStateInDictionary:_appearance.titleColors]; +} + +- (UIColor *)colorForSubtitleLabel +{ + if (self.selected) { + return self.preferredSubtitleSelectionColor ?: [self colorForCurrentStateInDictionary:_appearance.subtitleColors]; + } + return self.preferredSubtitleDefaultColor ?: [self colorForCurrentStateInDictionary:_appearance.subtitleColors]; +} + +- (UIColor *)colorForCellBorder +{ + if (self.selected) { + return _preferredBorderSelectionColor ?: _appearance.borderSelectionColor; + } + return _preferredBorderDefaultColor ?: _appearance.borderDefaultColor; +} + +- (NSArray *)colorsForEvents +{ + if (self.selected) { + return _preferredEventSelectionColors ?: @[_appearance.eventSelectionColor]; + } + return _preferredEventDefaultColors ?: @[_appearance.eventDefaultColor]; +} + +- (CGFloat)borderRadius +{ + return _preferredBorderRadius >= 0 ? _preferredBorderRadius : _appearance.borderRadius; +} + +#define OFFSET_PROPERTY(NAME,CAPITAL,ALTERNATIVE) \ +\ +@synthesize NAME = _##NAME; \ +\ +- (void)set##CAPITAL:(CGPoint)NAME \ +{ \ + BOOL diff = !CGPointEqualToPoint(NAME, self.NAME); \ + _##NAME = NAME; \ + if (diff) { \ + [self setNeedsLayout]; \ + } \ +} \ +\ +- (CGPoint)NAME \ +{ \ + return CGPointEqualToPoint(_##NAME, CGPointInfinity) ? ALTERNATIVE : _##NAME; \ +} + +OFFSET_PROPERTY(preferredTitleOffset, PreferredTitleOffset, _appearance.titleOffset); +OFFSET_PROPERTY(preferredSubtitleOffset, PreferredSubtitleOffset, _appearance.subtitleOffset); +OFFSET_PROPERTY(preferredImageOffset, PreferredImageOffset, _appearance.imageOffset); +OFFSET_PROPERTY(preferredEventOffset, PreferredEventOffset, _appearance.eventOffset); + +#undef OFFSET_PROPERTY + +- (void)setCalendar:(FSCalendar *)calendar +{ + if (![_calendar isEqual:calendar]) { + _calendar = calendar; + _appearance = calendar.appearance; + [self configureAppearance]; + } +} + +- (void)setSubtitle:(NSString *)subtitle +{ + if (![_subtitle isEqualToString:subtitle]) { + BOOL diff = (subtitle.length && !_subtitle.length) || (_subtitle.length && !subtitle.length); + _subtitle = subtitle; + if (diff) { + [self setNeedsLayout]; + } + } +} + +@end + + +@interface FSCalendarEventIndicator () + +@property (weak, nonatomic) UIView *contentView; + +@property (strong, nonatomic) NSPointerArray *eventLayers; + +@end + +@implementation FSCalendarEventIndicator + +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + + UIView *view = [[UIView alloc] initWithFrame:CGRectZero]; + [self addSubview:view]; + self.contentView = view; + + self.eventLayers = [NSPointerArray weakObjectsPointerArray]; + for (int i = 0; i < 3; i++) { + CALayer *layer = [CALayer layer]; + layer.backgroundColor = [UIColor clearColor].CGColor; + [self.contentView.layer addSublayer:layer]; + [self.eventLayers addPointer:(__bridge void * _Nullable)(layer)]; + } + + } + return self; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + CGFloat diameter = MIN(MIN(self.fs_width, self.fs_height),FSCalendarMaximumEventDotDiameter); + self.contentView.fs_height = self.fs_height; + self.contentView.fs_width = (self.numberOfEvents*2-1)*diameter; + self.contentView.center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds)); +} + +- (void)layoutSublayersOfLayer:(CALayer *)layer +{ + [super layoutSublayersOfLayer:layer]; + if (layer == self.layer) { + + CGFloat diameter = MIN(MIN(self.fs_width, self.fs_height),FSCalendarMaximumEventDotDiameter); + for (int i = 0; i < self.eventLayers.count; i++) { + CALayer *eventLayer = [self.eventLayers pointerAtIndex:i]; + eventLayer.hidden = i >= self.numberOfEvents; + if (!eventLayer.hidden) { + eventLayer.frame = CGRectMake(2*i*diameter, (self.fs_height-diameter)*0.5, diameter, diameter); + if (eventLayer.cornerRadius != diameter/2) { + eventLayer.cornerRadius = diameter/2; + } + } + } + } +} + +- (void)setColor:(id)color +{ + if (![_color isEqual:color]) { + _color = color; + + if ([_color isKindOfClass:[UIColor class]]) { + for (NSInteger i = 0; i < self.eventLayers.count; i++) { + CALayer *layer = [self.eventLayers pointerAtIndex:i]; + layer.backgroundColor = [_color CGColor]; + } + } else if ([_color isKindOfClass:[NSArray class]]) { + NSArray *colors = (NSArray *)_color; + for (int i = 0; i < self.eventLayers.count; i++) { + CALayer *eventLayer = [self.eventLayers pointerAtIndex:i]; + eventLayer.backgroundColor = colors[MIN(i,colors.count-1)].CGColor; + } + } + + } +} + +- (void)setNumberOfEvents:(NSInteger)numberOfEvents +{ + if (_numberOfEvents != numberOfEvents) { + _numberOfEvents = MIN(MAX(numberOfEvents,0),3); + [self setNeedsLayout]; + } +} + +@end + + +@implementation FSCalendarBlankCell + +- (void)configureAppearance {} + +@end + + + diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarCollectionView.h b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarCollectionView.h new file mode 100644 index 0000000..db38586 --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarCollectionView.h @@ -0,0 +1,18 @@ +// +// FSCalendarCollectionView.h +// FSCalendar +// +// Created by Wenchao Ding on 10/25/15. +// Copyright (c) 2015 Wenchao Ding. All rights reserved. +// + +#import + +@interface FSCalendarCollectionView : UICollectionView + +@end + + +@interface FSCalendarSeparator : UICollectionReusableView + +@end diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarCollectionView.m b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarCollectionView.m new file mode 100644 index 0000000..e1918ab --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarCollectionView.m @@ -0,0 +1,87 @@ +// +// FSCalendarCollectionView.m +// FSCalendar +// +// Created by Wenchao Ding on 10/25/15. +// Copyright (c) 2015 Wenchao Ding. All rights reserved. +// +// Reject -[UIScrollView(UIScrollViewInternal) _adjustContentOffsetIfNecessary] + + +#import "FSCalendarCollectionView.h" +#import "FSCalendarExtensions.h" +#import "FSCalendarConstants.h" + +@interface FSCalendarCollectionView () + +- (void)initialize; + +@end + +@implementation FSCalendarCollectionView + +@synthesize scrollsToTop = _scrollsToTop, contentInset = _contentInset; + +- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout +{ + self = [super initWithFrame:frame collectionViewLayout:layout]; + if (self) { + [self initialize]; + } + return self; +} + +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + [self initialize]; + } + return self; +} + +- (void)initialize +{ + self.scrollsToTop = NO; + self.contentInset = UIEdgeInsetsZero; + if (@available(iOS 9.0, *)) self.semanticContentAttribute = UISemanticContentAttributeForceLeftToRight; + if (@available(iOS 10.0, *)) self.prefetchingEnabled = NO; + if (@available(iOS 11.0, *)) self.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever; +} + +- (void)setContentInset:(UIEdgeInsets)contentInset +{ + [super setContentInset:UIEdgeInsetsZero]; + if (contentInset.top) { + self.contentOffset = CGPointMake(self.contentOffset.x, self.contentOffset.y+contentInset.top); + } +} + +- (void)setScrollsToTop:(BOOL)scrollsToTop +{ + [super setScrollsToTop:NO]; +} + +@end + + +@implementation FSCalendarSeparator + +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + self.backgroundColor = FSCalendarStandardSeparatorColor; + } + return self; +} + +- (void)applyLayoutAttributes:(UICollectionViewLayoutAttributes *)layoutAttributes +{ + self.frame = layoutAttributes.frame; +} + +@end + + + diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarCollectionViewLayout.h b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarCollectionViewLayout.h new file mode 100644 index 0000000..a9e5f43 --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarCollectionViewLayout.h @@ -0,0 +1,22 @@ +// +// FSCalendarAnimationLayout.h +// FSCalendar +// +// Created by dingwenchao on 1/3/16. +// Copyright © 2016 Wenchao Ding. All rights reserved. +// + +#import + +@class FSCalendar; + +@interface FSCalendarCollectionViewLayout : UICollectionViewLayout + +@property (weak, nonatomic) FSCalendar *calendar; + +@property (assign, nonatomic) CGFloat interitemSpacing; +@property (assign, nonatomic) UIEdgeInsets sectionInsets; +@property (assign, nonatomic) UICollectionViewScrollDirection scrollDirection; +@property (assign, nonatomic) CGSize headerReferenceSize; + +@end diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarCollectionViewLayout.m b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarCollectionViewLayout.m new file mode 100644 index 0000000..e8063d9 --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarCollectionViewLayout.m @@ -0,0 +1,560 @@ +// +// FSCalendarAnimationLayout.m +// FSCalendar +// +// Created by dingwenchao on 1/3/16. +// Copyright © 2016 Wenchao Ding. All rights reserved. +// + +#import "FSCalendarCollectionViewLayout.h" +#import "FSCalendar.h" +#import "FSCalendarDynamicHeader.h" +#import "FSCalendarCollectionView.h" +#import "FSCalendarExtensions.h" +#import "FSCalendarConstants.h" + +#define kFSCalendarSeparatorInterRows @"FSCalendarSeparatorInterRows" +#define kFSCalendarSeparatorInterColumns @"FSCalendarSeparatorInterColumns" + +@interface FSCalendarCollectionViewLayout () + +@property (assign, nonatomic) CGFloat *widths; +@property (assign, nonatomic) CGFloat *heights; +@property (assign, nonatomic) CGFloat *lefts; +@property (assign, nonatomic) CGFloat *tops; + +@property (assign, nonatomic) CGFloat *sectionHeights; +@property (assign, nonatomic) CGFloat *sectionTops; +@property (assign, nonatomic) CGFloat *sectionBottoms; +@property (assign, nonatomic) CGFloat *sectionRowCounts; + +@property (assign, nonatomic) CGSize estimatedItemSize; + +@property (assign, nonatomic) CGSize contentSize; +@property (assign, nonatomic) CGSize collectionViewSize; +@property (assign, nonatomic) NSInteger numberOfSections; + +@property (assign, nonatomic) FSCalendarSeparators separators; + +@property (strong, nonatomic) NSMutableDictionary *itemAttributes; +@property (strong, nonatomic) NSMutableDictionary *headerAttributes; +@property (strong, nonatomic) NSMutableDictionary *rowSeparatorAttributes; + +- (void)didReceiveNotifications:(NSNotification *)notification; + +@end + +@implementation FSCalendarCollectionViewLayout + +- (instancetype)init +{ + self = [super init]; + if (self) { + self.estimatedItemSize = CGSizeZero; + self.widths = NULL; + self.heights = NULL; + self.tops = NULL; + self.lefts = NULL; + + self.sectionHeights = NULL; + self.sectionTops = NULL; + self.sectionBottoms = NULL; + self.sectionRowCounts = NULL; + + self.scrollDirection = UICollectionViewScrollDirectionHorizontal; + self.sectionInsets = UIEdgeInsetsMake(5, 0, 5, 0); + + self.itemAttributes = [NSMutableDictionary dictionary]; + self.headerAttributes = [NSMutableDictionary dictionary]; + self.rowSeparatorAttributes = [NSMutableDictionary dictionary]; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveNotifications:) name:UIDeviceOrientationDidChangeNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveNotifications:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; + + [self registerClass:[FSCalendarSeparator class] forDecorationViewOfKind:kFSCalendarSeparatorInterRows]; + } + return self; +} + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:self name:UIDeviceOrientationDidChangeNotification object:nil]; + + free(self.widths); + free(self.heights); + free(self.tops); + free(self.lefts); + + free(self.sectionHeights); + free(self.sectionTops); + free(self.sectionRowCounts); + free(self.sectionBottoms); +} + +- (void)prepareLayout +{ + if (CGSizeEqualToSize(self.collectionViewSize, self.collectionView.frame.size) && self.numberOfSections == self.collectionView.numberOfSections && self.separators == self.calendar.appearance.separators) { + return; + } + self.collectionViewSize = self.collectionView.frame.size; + self.separators = self.calendar.appearance.separators; + + [self.itemAttributes removeAllObjects]; + [self.headerAttributes removeAllObjects]; + [self.rowSeparatorAttributes removeAllObjects]; + + self.headerReferenceSize = ({ + CGSize headerSize = CGSizeZero; + if (self.calendar.floatingMode) { + CGFloat headerHeight = self.calendar.preferredWeekdayHeight*1.5+self.calendar.preferredHeaderHeight; + headerSize = CGSizeMake(self.collectionView.fs_width, headerHeight); + } + headerSize; + }); + self.estimatedItemSize = ({ + CGFloat width = (self.collectionView.fs_width-self.sectionInsets.left-self.sectionInsets.right)/7.0; + CGFloat height = ({ + CGFloat height = FSCalendarStandardRowHeight; + if (!self.calendar.floatingMode) { + switch (self.calendar.transitionCoordinator.representingScope) { + case FSCalendarScopeMonth: { + height = (self.collectionView.fs_height-self.sectionInsets.top-self.sectionInsets.bottom)/6.0; + break; + } + case FSCalendarScopeWeek: { + height = (self.collectionView.fs_height-self.sectionInsets.top-self.sectionInsets.bottom); + break; + } + default: + break; + } + } else { + height = self.calendar.rowHeight; + } + height; + }); + CGSize size = CGSizeMake(width, height); + size; + }); + + // Calculate item widths and lefts + free(self.widths); + self.widths = ({ + NSInteger columnCount = 7; + size_t columnSize = sizeof(CGFloat)*columnCount; + CGFloat *widths = malloc(columnSize); + CGFloat contentWidth = self.collectionView.fs_width - self.sectionInsets.left - self.sectionInsets.right; + FSCalendarSliceCake(contentWidth, columnCount, widths); + widths; + }); + + free(self.lefts); + self.lefts = ({ + NSInteger columnCount = 7; + size_t columnSize = sizeof(CGFloat)*columnCount; + CGFloat *lefts = malloc(columnSize); + lefts[0] = self.sectionInsets.left; + for (int i = 1; i < columnCount; i++) { + lefts[i] = lefts[i-1] + self.widths[i-1]; + } + lefts; + }); + + // Calculate item heights and tops + free(self.heights); + self.heights = ({ + NSInteger rowCount = self.calendar.transitionCoordinator.representingScope == FSCalendarScopeWeek ? 1 : 6; + size_t rowSize = sizeof(CGFloat)*rowCount; + CGFloat *heights = malloc(rowSize); + if (!self.calendar.floatingMode) { + CGFloat contentHeight = self.collectionView.fs_height - self.sectionInsets.top - self.sectionInsets.bottom; + FSCalendarSliceCake(contentHeight, rowCount, heights); + } else { + for (int i = 0; i < rowCount; i++) { + heights[i] = self.estimatedItemSize.height; + } + } + heights; + }); + + free(self.tops); + self.tops = ({ + NSInteger rowCount = self.calendar.transitionCoordinator.representingScope == FSCalendarScopeWeek ? 1 : 6; + size_t rowSize = sizeof(CGFloat)*rowCount; + CGFloat *tops = malloc(rowSize); + tops[0] = self.sectionInsets.top; + for (int i = 1; i < rowCount; i++) { + tops[i] = tops[i-1] + self.heights[i-1]; + } + tops; + }); + + // Calculate content size + self.numberOfSections = self.collectionView.numberOfSections; + self.contentSize = ({ + CGSize contentSize = CGSizeZero; + if (!self.calendar.floatingMode) { + CGFloat width = self.collectionView.fs_width; + CGFloat height = self.collectionView.fs_height; + switch (self.scrollDirection) { + case UICollectionViewScrollDirectionHorizontal: { + width *= self.numberOfSections; + break; + } + case UICollectionViewScrollDirectionVertical: { + height *= self.numberOfSections; + break; + } + default: + break; + } + contentSize = CGSizeMake(width, height); + } else { + free(self.sectionHeights); + self.sectionHeights = malloc(sizeof(CGFloat)*self.numberOfSections); + free(self.sectionRowCounts); + self.sectionRowCounts = malloc(sizeof(NSInteger)*self.numberOfSections); + CGFloat width = self.collectionView.fs_width; + CGFloat height = 0; + for (int i = 0; i < self.numberOfSections; i++) { + NSInteger rowCount = [self.calendar.calculator numberOfRowsInSection:i]; + self.sectionRowCounts[i] = rowCount; + CGFloat sectionHeight = self.headerReferenceSize.height; + for (int j = 0; j < rowCount; j++) { + sectionHeight += self.heights[j]; + } + self.sectionHeights[i] = sectionHeight; + height += sectionHeight; + } + free(self.sectionTops); + self.sectionTops = malloc(sizeof(CGFloat)*self.numberOfSections); + free(self.sectionBottoms); + self.sectionBottoms = malloc(sizeof(CGFloat)*self.numberOfSections); + self.sectionTops[0] = 0; + self.sectionBottoms[0] = self.sectionHeights[0]; + for (int i = 1; i < self.numberOfSections; i++) { + self.sectionTops[i] = self.sectionTops[i-1] + self.sectionHeights[i-1]; + self.sectionBottoms[i] = self.sectionTops[i] + self.sectionHeights[i]; + } + contentSize = CGSizeMake(width, height); + } + contentSize; + }); + + [self.calendar adjustMonthPosition]; +} + +- (CGSize)collectionViewContentSize +{ + return self.contentSize; +} + +- (NSArray *)layoutAttributesForElementsInRect:(CGRect)rect +{ + // Clipping + rect = CGRectIntersection(rect, CGRectMake(0, 0, self.contentSize.width, self.contentSize.height)); + if (CGRectIsEmpty(rect)) return nil; + + // Calculating attributes + NSMutableArray *layoutAttributes = [NSMutableArray array]; + + if (!self.calendar.floatingMode) { + + switch (self.scrollDirection) { + case UICollectionViewScrollDirectionHorizontal: { + + NSInteger startColumn = ({ + NSInteger startSection = rect.origin.x/self.collectionView.fs_width; + CGFloat widthDelta = FSCalendarMod(CGRectGetMinX(rect), self.collectionView.fs_width)-self.sectionInsets.left; + widthDelta = MIN(MAX(0, widthDelta), self.collectionView.fs_width-self.sectionInsets.left); + NSInteger countDelta = FSCalendarFloor(widthDelta/self.estimatedItemSize.width); + NSInteger startColumn = startSection*7 + countDelta; + startColumn; + }); + + NSInteger endColumn = ({ + NSInteger endColumn; + CGFloat section = CGRectGetMaxX(rect)/self.collectionView.fs_width; + CGFloat remainder = FSCalendarMod(section, 1); + // https://stackoverflow.com/a/10335601/2398107 + if (remainder <= MAX(100*FLT_EPSILON*ABS(remainder), FLT_MIN)) { + endColumn = FSCalendarFloor(section)*7 - 1; + } else { + CGFloat widthDelta = FSCalendarMod(CGRectGetMaxX(rect), self.collectionView.fs_width)-self.sectionInsets.left; + widthDelta = MIN(MAX(0, widthDelta), self.collectionView.fs_width - self.sectionInsets.left); + NSInteger countDelta = FSCalendarCeil(widthDelta/self.estimatedItemSize.width); + endColumn = FSCalendarFloor(section)*7 + countDelta - 1; + } + endColumn; + }); + + NSInteger numberOfRows = self.calendar.transitionCoordinator.representingScope == FSCalendarScopeMonth ? 6 : 1; + + for (NSInteger column = startColumn; column <= endColumn; column++) { + for (NSInteger row = 0; row < numberOfRows; row++) { + NSInteger section = column / 7; + NSInteger item = column % 7 + row * 7; + NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:section]; + UICollectionViewLayoutAttributes *itemAttributes = [self layoutAttributesForItemAtIndexPath:indexPath]; + [layoutAttributes addObject:itemAttributes]; + + UICollectionViewLayoutAttributes *rowSeparatorAttributes = [self layoutAttributesForDecorationViewOfKind:kFSCalendarSeparatorInterRows atIndexPath:indexPath]; + if (rowSeparatorAttributes) { + [layoutAttributes addObject:rowSeparatorAttributes]; + } + } + } + + break; + } + case UICollectionViewScrollDirectionVertical: { + + NSInteger startRow = ({ + NSInteger startSection = rect.origin.y/self.collectionView.fs_height; + CGFloat heightDelta = FSCalendarMod(CGRectGetMinY(rect), self.collectionView.fs_height)-self.sectionInsets.top; + heightDelta = MIN(MAX(0, heightDelta), self.collectionView.fs_height-self.sectionInsets.top); + NSInteger countDelta = FSCalendarFloor(heightDelta/self.estimatedItemSize.height); + NSInteger startRow = startSection*6 + countDelta; + startRow; + }); + + NSInteger endRow = ({ + NSInteger endRow; + CGFloat section = CGRectGetMaxY(rect)/self.collectionView.fs_height; + CGFloat remainder = FSCalendarMod(section, 1); + // https://stackoverflow.com/a/10335601/2398107 + if (remainder <= MAX(100*FLT_EPSILON*ABS(remainder), FLT_MIN)) { + endRow = FSCalendarFloor(section)*6 - 1; + } else { + CGFloat heightDelta = FSCalendarMod(CGRectGetMaxY(rect), self.collectionView.fs_height)-self.sectionInsets.top; + heightDelta = MIN(MAX(0, heightDelta), self.collectionView.fs_height-self.sectionInsets.top); + NSInteger countDelta = FSCalendarCeil(heightDelta/self.estimatedItemSize.height); + endRow = FSCalendarFloor(section)*6 + countDelta-1; + } + endRow; + }); + + for (NSInteger row = startRow; row <= endRow; row++) { + for (NSInteger column = 0; column < 7; column++) { + NSInteger section = row / 6; + NSInteger item = column + (row % 6) * 7; + NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:section]; + UICollectionViewLayoutAttributes *itemAttributes = [self layoutAttributesForItemAtIndexPath:indexPath]; + [layoutAttributes addObject:itemAttributes]; + + UICollectionViewLayoutAttributes *rowSeparatorAttributes = [self layoutAttributesForDecorationViewOfKind:kFSCalendarSeparatorInterRows atIndexPath:indexPath]; + if (rowSeparatorAttributes) { + [layoutAttributes addObject:rowSeparatorAttributes]; + } + + } + } + + break; + } + default: + break; + } + + } else { + + NSInteger startSection = [self searchStartSection:rect :0 :self.numberOfSections-1]; + NSInteger startRowIndex = ({ + CGFloat heightDelta1 = MIN(self.sectionBottoms[startSection]-CGRectGetMinY(rect)-self.sectionInsets.bottom, self.sectionRowCounts[startSection]*self.estimatedItemSize.height); + NSInteger startRowCount = FSCalendarCeil(heightDelta1/self.estimatedItemSize.height); + NSInteger startRowIndex = self.sectionRowCounts[startSection]-startRowCount; + startRowIndex; + }); + + NSInteger endSection = [self searchEndSection:rect :startSection :self.numberOfSections-1]; + NSInteger endRowIndex = ({ + CGFloat heightDelta2 = MAX(CGRectGetMaxY(rect) - self.sectionTops[endSection]- self.headerReferenceSize.height - self.sectionInsets.top, 0); + NSInteger endRowCount = FSCalendarCeil(heightDelta2/self.estimatedItemSize.height); + NSInteger endRowIndex = endRowCount - 1; + endRowIndex; + }); + for (NSInteger section = startSection; section <= endSection; section++) { + NSInteger startRow = (section == startSection) ? startRowIndex : 0; + NSInteger endRow = (section == endSection) ? endRowIndex : self.sectionRowCounts[section]-1; + UICollectionViewLayoutAttributes *headerAttributes = [self layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader atIndexPath:[NSIndexPath indexPathForItem:0 inSection:section]]; + [layoutAttributes addObject:headerAttributes]; + for (NSInteger row = startRow; row <= endRow; row++) { + for (NSInteger column = 0; column < 7; column++) { + NSInteger item = row * 7 + column; + NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:section]; + UICollectionViewLayoutAttributes *itemAttributes = [self layoutAttributesForItemAtIndexPath:indexPath]; + [layoutAttributes addObject:itemAttributes]; + UICollectionViewLayoutAttributes *rowSeparatorAttributes = [self layoutAttributesForDecorationViewOfKind:kFSCalendarSeparatorInterRows atIndexPath:indexPath]; + if (rowSeparatorAttributes) { + [layoutAttributes addObject:rowSeparatorAttributes]; + } + } + } + } + + } + return [NSArray arrayWithArray:layoutAttributes]; + +} + +// Items +- (UICollectionViewLayoutAttributes *)layoutAttributesForItemAtIndexPath:(NSIndexPath *)indexPath +{ + FSCalendarCoordinate coordinate = [self.calendar.calculator coordinateForIndexPath:indexPath]; + NSInteger column = coordinate.column; + NSInteger row = coordinate.row; + UICollectionViewLayoutAttributes *attributes = self.itemAttributes[indexPath]; + if (!attributes) { + attributes = [UICollectionViewLayoutAttributes layoutAttributesForCellWithIndexPath:indexPath]; + CGRect frame = ({ + CGFloat x, y; + switch (self.scrollDirection) { + case UICollectionViewScrollDirectionHorizontal: { + x = self.lefts[column] + indexPath.section * self.collectionView.fs_width; + y = self.tops[row]; + break; + } + case UICollectionViewScrollDirectionVertical: { + x = self.lefts[column]; + if (!self.calendar.floatingMode) { + y = self.tops[row] + indexPath.section * self.collectionView.fs_height; + } else { + y = self.sectionTops[indexPath.section] + self.headerReferenceSize.height + self.tops[row]; + } + break; + } + default: + break; + } + CGFloat width = self.widths[column]; + CGFloat height = self.heights[row]; + CGRect frame = CGRectMake(x, y, width, height); + frame; + }); + attributes.frame = frame; + self.itemAttributes[indexPath] = attributes; + } + return attributes; +} + +// Section headers +- (UICollectionViewLayoutAttributes *)layoutAttributesForSupplementaryViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath +{ + if ([elementKind isEqualToString:UICollectionElementKindSectionHeader]) { + UICollectionViewLayoutAttributes *attributes = self.headerAttributes[indexPath]; + if (!attributes) { + attributes = [UICollectionViewLayoutAttributes layoutAttributesForSupplementaryViewOfKind:UICollectionElementKindSectionHeader withIndexPath:indexPath]; + attributes.frame = CGRectMake(0, self.sectionTops[indexPath.section], self.collectionView.fs_width, self.headerReferenceSize.height); + self.headerAttributes[indexPath] = attributes; + } + return attributes; + } + return nil; +} + +// Separators +- (UICollectionViewLayoutAttributes *)layoutAttributesForDecorationViewOfKind:(NSString *)elementKind atIndexPath:(NSIndexPath *)indexPath +{ + if ([elementKind isEqualToString:kFSCalendarSeparatorInterRows] && (self.separators & FSCalendarSeparatorInterRows)) { + UICollectionViewLayoutAttributes *attributes = self.rowSeparatorAttributes[indexPath]; + if (!attributes) { + FSCalendarCoordinate coordinate = [self.calendar.calculator coordinateForIndexPath:indexPath]; + if (coordinate.row >= [self.calendar.calculator numberOfRowsInSection:indexPath.section]-1) { + return nil; + } + attributes = [UICollectionViewLayoutAttributes layoutAttributesForDecorationViewOfKind:kFSCalendarSeparatorInterRows withIndexPath:indexPath]; + CGFloat x, y; + if (!self.calendar.floatingMode) { + switch (self.scrollDirection) { + case UICollectionViewScrollDirectionHorizontal: { + x = self.lefts[coordinate.column] + indexPath.section * self.collectionView.fs_width; + y = self.tops[coordinate.row]+self.heights[coordinate.row]; + break; + } + case UICollectionViewScrollDirectionVertical: { + x = 0; + y = self.tops[coordinate.row]+self.heights[coordinate.row] + indexPath.section * self.collectionView.fs_height; + break; + } + default: + break; + } + } else { + x = 0; + y = self.sectionTops[indexPath.section] + self.headerReferenceSize.height + self.tops[coordinate.row] + self.heights[coordinate.row]; + } + CGFloat width = self.collectionView.fs_width; + CGFloat height = FSCalendarStandardSeparatorThickness; + attributes.frame = CGRectMake(x, y, width, height); + attributes.zIndex = NSIntegerMax; + self.rowSeparatorAttributes[indexPath] = attributes; + } + return attributes; + } + return nil; +} + +#pragma mark - Notifications + +- (void)didReceiveNotifications:(NSNotification *)notification +{ + if ([notification.name isEqualToString:UIDeviceOrientationDidChangeNotification]) { + [self invalidateLayout]; + } + if ([notification.name isEqualToString:UIApplicationDidReceiveMemoryWarningNotification]) { + [self.itemAttributes removeAllObjects]; + [self.headerAttributes removeAllObjects]; + [self.rowSeparatorAttributes removeAllObjects]; + } +} + +#pragma mark - Private properties + +- (void)setScrollDirection:(UICollectionViewScrollDirection)scrollDirection +{ + if (_scrollDirection != scrollDirection) { + _scrollDirection = scrollDirection; + self.collectionViewSize = CGSizeAutomatic; + } +} + +#pragma mark - Private functions + +- (NSInteger)searchStartSection:(CGRect)rect :(NSInteger)left :(NSInteger)right +{ + NSInteger mid = left + (right-left)/2; + CGFloat y = rect.origin.y; + CGFloat minY = self.sectionTops[mid]; + CGFloat maxY = self.sectionBottoms[mid]; + if (y >= minY && y < maxY) { + return mid; + } else if (y < minY) { + return [self searchStartSection:rect :left :mid]; + } else { + return [self searchStartSection:rect :mid+1 :right]; + } +} + +- (NSInteger)searchEndSection:(CGRect)rect :(NSInteger)left :(NSInteger)right +{ + NSInteger mid = left + (right-left)/2; + CGFloat y = CGRectGetMaxY(rect); + CGFloat minY = self.sectionTops[mid]; + CGFloat maxY = self.sectionBottoms[mid]; + if (y > minY && y <= maxY) { + return mid; + } else if (y <= minY) { + return [self searchEndSection:rect :left :mid]; + } else { + return [self searchEndSection:rect :mid+1 :right]; + } +} + +@end + + +#undef kFSCalendarSeparatorInterColumns +#undef kFSCalendarSeparatorInterRows + + diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarConstants.h b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarConstants.h new file mode 100644 index 0000000..eaf6545 --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarConstants.h @@ -0,0 +1,99 @@ +// +// FSCalendarConstane.h +// FSCalendar +// +// Created by dingwenchao on 8/28/15. +// Copyright © 2016 Wenchao Ding. All rights reserved. +// +// https://github.com/Husseinhj +// + +#import +#import + +#pragma mark - Constants + +CG_EXTERN CGFloat const FSCalendarStandardHeaderHeight; +CG_EXTERN CGFloat const FSCalendarStandardWeekdayHeight; +CG_EXTERN CGFloat const FSCalendarStandardMonthlyPageHeight; +CG_EXTERN CGFloat const FSCalendarStandardWeeklyPageHeight; +CG_EXTERN CGFloat const FSCalendarStandardCellDiameter; +CG_EXTERN CGFloat const FSCalendarStandardSeparatorThickness; +CG_EXTERN CGFloat const FSCalendarAutomaticDimension; +CG_EXTERN CGFloat const FSCalendarDefaultBounceAnimationDuration; +CG_EXTERN CGFloat const FSCalendarStandardRowHeight; +CG_EXTERN CGFloat const FSCalendarStandardTitleTextSize; +CG_EXTERN CGFloat const FSCalendarStandardSubtitleTextSize; +CG_EXTERN CGFloat const FSCalendarStandardWeekdayTextSize; +CG_EXTERN CGFloat const FSCalendarStandardHeaderTextSize; +CG_EXTERN CGFloat const FSCalendarMaximumEventDotDiameter; +CG_EXTERN CGFloat const FSCalendarStandardScopeHandleHeight; + +UIKIT_EXTERN NSInteger const FSCalendarDefaultHourComponent; + +UIKIT_EXTERN NSString * const FSCalendarDefaultCellReuseIdentifier; +UIKIT_EXTERN NSString * const FSCalendarBlankCellReuseIdentifier; +UIKIT_EXTERN NSString * const FSCalendarInvalidArgumentsExceptionName; + +CG_EXTERN CGPoint const CGPointInfinity; +CG_EXTERN CGSize const CGSizeAutomatic; + +#if TARGET_INTERFACE_BUILDER +#define FSCalendarDeviceIsIPad NO +#else +#define FSCalendarDeviceIsIPad [[UIDevice currentDevice].model hasPrefix:@"iPad"] +#endif + +#define FSCalendarStandardSelectionColor FSColorRGBA(31,119,219,1.0) +#define FSCalendarStandardTodayColor FSColorRGBA(198,51,42 ,1.0) +#define FSCalendarStandardTitleTextColor FSColorRGBA(14,69,221 ,1.0) +#define FSCalendarStandardEventDotColor FSColorRGBA(31,119,219,0.75) + +#define FSCalendarStandardLineColor [[UIColor lightGrayColor] colorWithAlphaComponent:0.30] +#define FSCalendarStandardSeparatorColor [[UIColor lightGrayColor] colorWithAlphaComponent:0.60] +#define FSCalendarStandardScopeHandleColor [[UIColor lightGrayColor] colorWithAlphaComponent:0.50] + +#define FSColorRGBA(r,g,b,a) [UIColor colorWithRed:r/255.0 green:g/255.0 blue:b/255.0 alpha:a] +#define FSCalendarInAppExtension [[[NSBundle mainBundle] bundlePath] hasSuffix:@".appex"] + +#define FSCalendarFloor(c) floorf(c) +#define FSCalendarRound(c) roundf(c) +#define FSCalendarCeil(c) ceilf(c) +#define FSCalendarMod(c1,c2) fmodf(c1,c2) + +#define FSCalendarHalfRound(c) (FSCalendarRound(c*2)*0.5) +#define FSCalendarHalfFloor(c) (FSCalendarFloor(c*2)*0.5) +#define FSCalendarHalfCeil(c) (FSCalendarCeil(c*2)*0.5) + +#define FSCalendarUseWeakSelf __weak __typeof__(self) FSCalendarWeakSelf = self; +#define FSCalendarUseStrongSelf __strong __typeof__(self) self = FSCalendarWeakSelf; + + +#pragma mark - Deprecated + +#define FSCalendarDeprecated(instead) DEPRECATED_MSG_ATTRIBUTE(" Use " # instead " instead") + +FSCalendarDeprecated('borderRadius') +typedef NS_ENUM(NSUInteger, FSCalendarCellShape) { + FSCalendarCellShapeCircle = 0, + FSCalendarCellShapeRectangle = 1 +}; + +typedef NS_ENUM(NSUInteger, FSCalendarUnit) { + FSCalendarUnitMonth = NSCalendarUnitMonth, + FSCalendarUnitWeekOfYear = NSCalendarUnitWeekOfYear, + FSCalendarUnitDay = NSCalendarUnitDay +}; + +static inline void FSCalendarSliceCake(CGFloat cake, NSInteger count, CGFloat *pieces) { + CGFloat total = cake; + for (int i = 0; i < count; i++) { + NSInteger remains = count - i; + CGFloat piece = FSCalendarRound(total/remains*2)*0.5; + total -= piece; + pieces[i] = piece; + } +} + + + diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarConstants.m b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarConstants.m new file mode 100644 index 0000000..e488419 --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarConstants.m @@ -0,0 +1,46 @@ +// +// FSCalendarConstane.m +// FSCalendar +// +// Created by dingwenchao on 8/28/15. +// Copyright © 2016 Wenchao Ding. All rights reserved. +// +// https://github.com/Husseinhj +// + +#import "FSCalendarConstants.h" + +CGFloat const FSCalendarStandardHeaderHeight = 40; +CGFloat const FSCalendarStandardWeekdayHeight = 25; +CGFloat const FSCalendarStandardMonthlyPageHeight = 300.0; +CGFloat const FSCalendarStandardWeeklyPageHeight = 108+1/3.0; +CGFloat const FSCalendarStandardCellDiameter = 100/3.0; +CGFloat const FSCalendarStandardSeparatorThickness = 0.5; +CGFloat const FSCalendarAutomaticDimension = -1; +CGFloat const FSCalendarDefaultBounceAnimationDuration = 0.15; +CGFloat const FSCalendarStandardRowHeight = 38; +CGFloat const FSCalendarStandardTitleTextSize = 13.5; +CGFloat const FSCalendarStandardSubtitleTextSize = 10; +CGFloat const FSCalendarStandardWeekdayTextSize = 14; +CGFloat const FSCalendarStandardHeaderTextSize = 16.5; +CGFloat const FSCalendarMaximumEventDotDiameter = 4.8; +CGFloat const FSCalendarStandardScopeHandleHeight = 26; + +NSInteger const FSCalendarDefaultHourComponent = 0; + +NSString * const FSCalendarDefaultCellReuseIdentifier = @"_FSCalendarDefaultCellReuseIdentifier"; +NSString * const FSCalendarBlankCellReuseIdentifier = @"_FSCalendarBlankCellReuseIdentifier"; +NSString * const FSCalendarInvalidArgumentsExceptionName = @"Invalid argument exception"; + +CGPoint const CGPointInfinity = { + .x = CGFLOAT_MAX, + .y = CGFLOAT_MAX +}; + +CGSize const CGSizeAutomatic = { + .width = FSCalendarAutomaticDimension, + .height = FSCalendarAutomaticDimension +}; + + + diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarDelegationFactory.h b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarDelegationFactory.h new file mode 100644 index 0000000..5c0bb7f --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarDelegationFactory.h @@ -0,0 +1,17 @@ +// +// FSCalendarDelegationFactory.h +// FSCalendar +// +// Created by dingwenchao on 19/12/2016. +// Copyright © 2016 wenchaoios. All rights reserved. +// + +#import +#import "FSCalendarDelegationProxy.h" + +@interface FSCalendarDelegationFactory : NSObject + ++ (FSCalendarDelegationProxy *)dataSourceProxy; ++ (FSCalendarDelegationProxy *)delegateProxy; + +@end diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarDelegationFactory.m b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarDelegationFactory.m new file mode 100644 index 0000000..b185459 --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarDelegationFactory.m @@ -0,0 +1,40 @@ +// +// FSCalendarDelegationFactory.m +// FSCalendar +// +// Created by dingwenchao on 19/12/2016. +// Copyright © 2016 wenchaoios. All rights reserved. +// + +#import "FSCalendarDelegationFactory.h" + +#define FSCalendarSelectorEntry(SEL1,SEL2) NSStringFromSelector(@selector(SEL1)):NSStringFromSelector(@selector(SEL2)) + +@implementation FSCalendarDelegationFactory + ++ (FSCalendarDelegationProxy *)dataSourceProxy +{ + FSCalendarDelegationProxy *delegation = [[FSCalendarDelegationProxy alloc] init]; + delegation.protocol = @protocol(FSCalendarDataSource); + delegation.deprecations = @{FSCalendarSelectorEntry(calendar:numberOfEventsForDate:, calendar:hasEventForDate:)}; + return delegation; +} + ++ (FSCalendarDelegationProxy *)delegateProxy +{ + FSCalendarDelegationProxy *delegation = [[FSCalendarDelegationProxy alloc] init]; + delegation.protocol = @protocol(FSCalendarDelegateAppearance); + delegation.deprecations = @{ + FSCalendarSelectorEntry(calendarCurrentPageDidChange:, calendarCurrentMonthDidChange:), + FSCalendarSelectorEntry(calendar:shouldSelectDate:atMonthPosition:, calendar:shouldSelectDate:), + FSCalendarSelectorEntry(calendar:didSelectDate:atMonthPosition:, calendar:didSelectDate:), + FSCalendarSelectorEntry(calendar:shouldDeselectDate:atMonthPosition:, calendar:shouldDeselectDate:), + FSCalendarSelectorEntry(calendar:didDeselectDate:atMonthPosition:, calendar:didDeselectDate:) + }; + return delegation; +} + +@end + +#undef FSCalendarSelectorEntry + diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarDelegationProxy.h b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarDelegationProxy.h new file mode 100644 index 0000000..e95587d --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarDelegationProxy.h @@ -0,0 +1,31 @@ +// +// FSCalendarDelegationProxy.h +// FSCalendar +// +// Created by dingwenchao on 11/12/2016. +// Copyright © 2016 Wenchao Ding. All rights reserved. +// +// https://github.com/Husseinhj +// +// 1. Smart proxy delegation http://petersteinberger.com/blog/2013/smart-proxy-delegation/ +// 2. Manage deprecated delegation functions +// + +#import +#import "FSCalendar.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface FSCalendarDelegationProxy : NSProxy + +@property (weak , nonatomic) id delegation; +@property (strong, nonatomic) Protocol *protocol; +@property (strong, nonatomic) NSDictionary *deprecations; + +- (instancetype)init; +- (SEL)deprecatedSelectorOfSelector:(SEL)selector; + +@end + +NS_ASSUME_NONNULL_END + diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarDelegationProxy.m b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarDelegationProxy.m new file mode 100644 index 0000000..84e4a57 --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarDelegationProxy.m @@ -0,0 +1,68 @@ +// +// FSCalendarDelegationProxy.m +// FSCalendar +// +// Created by dingwenchao on 11/12/2016. +// Copyright © 2016 Wenchao Ding. All rights reserved. +// + +#import "FSCalendarDelegationProxy.h" +#import + +@implementation FSCalendarDelegationProxy + +- (instancetype)init +{ + return self; +} + +- (BOOL)respondsToSelector:(SEL)selector +{ + BOOL responds = [self.delegation respondsToSelector:selector]; + if (!responds) responds = [self.delegation respondsToSelector:[self deprecatedSelectorOfSelector:selector]]; + if (!responds) responds = [super respondsToSelector:selector]; + return responds; +} + +- (BOOL)conformsToProtocol:(Protocol *)protocol +{ + return [self.delegation conformsToProtocol:protocol]; +} + +- (void)forwardInvocation:(NSInvocation *)invocation +{ + SEL selector = invocation.selector; + if (![self.delegation respondsToSelector:selector]) { + selector = [self deprecatedSelectorOfSelector:selector]; + invocation.selector = selector; + } + if ([self.delegation respondsToSelector:selector]) { + [invocation invokeWithTarget:self.delegation]; + } +} + +- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel +{ + if ([self.delegation respondsToSelector:sel]) { + return [(NSObject *)self.delegation methodSignatureForSelector:sel]; + } + SEL selector = [self deprecatedSelectorOfSelector:sel]; + if ([self.delegation respondsToSelector:selector]) { + return [(NSObject *)self.delegation methodSignatureForSelector:selector]; + } +#if TARGET_INTERFACE_BUILDER + return [NSObject methodSignatureForSelector:@selector(init)]; +#endif + struct objc_method_description desc = protocol_getMethodDescription(self.protocol, sel, NO, YES); + const char *types = desc.types; + return types?[NSMethodSignature signatureWithObjCTypes:types]:[NSObject methodSignatureForSelector:@selector(init)]; +} + +- (SEL)deprecatedSelectorOfSelector:(SEL)selector +{ + NSString *selectorString = NSStringFromSelector(selector); + selectorString = self.deprecations[selectorString]; + return NSSelectorFromString(selectorString); +} + +@end diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarDynamicHeader.h b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarDynamicHeader.h new file mode 100644 index 0000000..dc9fe75 --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarDynamicHeader.h @@ -0,0 +1,84 @@ +// +// FSCalendarDynamicHeader.h +// Pods +// +// Created by DingWenchao on 6/29/15. +// +// 动感头文件,仅供框架内部使用。 +// Private header, don't use it. +// + +#import +#import + +#import "FSCalendar.h" +#import "FSCalendarCell.h" +#import "FSCalendarHeaderView.h" +#import "FSCalendarStickyHeader.h" +#import "FSCalendarCollectionView.h" +#import "FSCalendarCollectionViewLayout.h" +#import "FSCalendarScopeHandle.h" +#import "FSCalendarCalculator.h" +#import "FSCalendarTransitionCoordinator.h" +#import "FSCalendarDelegationProxy.h" + +@interface FSCalendar (Dynamic) + +@property (readonly, nonatomic) FSCalendarCollectionView *collectionView; +@property (readonly, nonatomic) FSCalendarScopeHandle *scopeHandle; +@property (readonly, nonatomic) FSCalendarCollectionViewLayout *collectionViewLayout; +@property (readonly, nonatomic) FSCalendarTransitionCoordinator *transitionCoordinator; +@property (readonly, nonatomic) FSCalendarCalculator *calculator; +@property (readonly, nonatomic) BOOL floatingMode; +@property (readonly, nonatomic) NSArray *visibleStickyHeaders; +@property (readonly, nonatomic) CGFloat preferredHeaderHeight; +@property (readonly, nonatomic) CGFloat preferredWeekdayHeight; +@property (readonly, nonatomic) UIView *bottomBorder; + +@property (readonly, nonatomic) NSCalendar *gregorian; +@property (readonly, nonatomic) NSDateComponents *components; +@property (readonly, nonatomic) NSDateFormatter *formatter; + +@property (readonly, nonatomic) UIView *contentView; +@property (readonly, nonatomic) UIView *daysContainer; + +@property (assign, nonatomic) BOOL needsAdjustingViewFrame; + +- (void)invalidateHeaders; +- (void)adjustMonthPosition; +- (void)configureAppearance; + +- (BOOL)isPageInRange:(NSDate *)page; +- (BOOL)isDateInRange:(NSDate *)date; + +- (CGSize)sizeThatFits:(CGSize)size scope:(FSCalendarScope)scope; + +@end + +@interface FSCalendarAppearance (Dynamic) + +@property (readwrite, nonatomic) FSCalendar *calendar; + +@property (readonly, nonatomic) NSDictionary *backgroundColors; +@property (readonly, nonatomic) NSDictionary *titleColors; +@property (readonly, nonatomic) NSDictionary *subtitleColors; +@property (readonly, nonatomic) NSDictionary *borderColors; + +@end + +@interface FSCalendarWeekdayView (Dynamic) + +@property (readwrite, nonatomic) FSCalendar *calendar; + +@end + +@interface FSCalendarCollectionViewLayout (Dynamic) + +@property (readonly, nonatomic) CGSize estimatedItemSize; + +@end + +@interface FSCalendarDelegationProxy() +@end + + diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarExtensions.h b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarExtensions.h new file mode 100644 index 0000000..4b066b4 --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarExtensions.h @@ -0,0 +1,84 @@ +// +// FSCalendarExtensions.h +// FSCalendar +// +// Created by dingwenchao on 10/8/16. +// Copyright © 2016 Wenchao Ding. All rights reserved. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface UIView (FSCalendarExtensions) + +@property (nonatomic) CGFloat fs_width; +@property (nonatomic) CGFloat fs_height; + +@property (nonatomic) CGFloat fs_top; +@property (nonatomic) CGFloat fs_left; +@property (nonatomic) CGFloat fs_bottom; +@property (nonatomic) CGFloat fs_right; + +@end + + +@interface CALayer (FSCalendarExtensions) + +@property (nonatomic) CGFloat fs_width; +@property (nonatomic) CGFloat fs_height; + +@property (nonatomic) CGFloat fs_top; +@property (nonatomic) CGFloat fs_left; +@property (nonatomic) CGFloat fs_bottom; +@property (nonatomic) CGFloat fs_right; + +@end + + +@interface NSCalendar (FSCalendarExtensions) + +- (nullable NSDate *)fs_firstDayOfMonth:(NSDate *)month; +- (nullable NSDate *)fs_lastDayOfMonth:(NSDate *)month; +- (nullable NSDate *)fs_firstDayOfWeek:(NSDate *)week; +- (nullable NSDate *)fs_lastDayOfWeek:(NSDate *)week; +- (nullable NSDate *)fs_middleDayOfWeek:(NSDate *)week; +- (NSInteger)fs_numberOfDaysInMonth:(NSDate *)month; + +@end + +@interface NSMapTable (FSCalendarExtensions) + +- (void)setObject:(nullable id)obj forKeyedSubscript:(id)key; +- (id)objectForKeyedSubscript:(id)key; + +@end + +@interface NSCache (FSCalendarExtensions) + +- (void)setObject:(nullable id)obj forKeyedSubscript:(id)key; +- (id)objectForKeyedSubscript:(id)key; + +@end + + +@interface NSObject (FSCalendarExtensions) + +#define IVAR_DEF(SET,GET,TYPE) \ +- (void)fs_set##SET##Variable:(TYPE)value forKey:(NSString *)key; \ +- (TYPE)fs_##GET##VariableForKey:(NSString *)key; +IVAR_DEF(Bool, bool, BOOL) +IVAR_DEF(Float, float, CGFloat) +IVAR_DEF(Integer, integer, NSInteger) +IVAR_DEF(UnsignedInteger, unsignedInteger, NSUInteger) +#undef IVAR_DEF + +- (void)fs_setVariable:(id)variable forKey:(NSString *)key; +- (id)fs_variableForKey:(NSString *)key; + +- (nullable id)fs_performSelector:(SEL)selector withObjects:(nullable id)firstObject, ... NS_REQUIRES_NIL_TERMINATION; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarExtensions.m b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarExtensions.m new file mode 100644 index 0000000..d407cc9 --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarExtensions.m @@ -0,0 +1,440 @@ +// +// FSCalendarExtensions.m +// FSCalendar +// +// Created by dingwenchao on 10/8/16. +// Copyright © 2016 Wenchao Ding. All rights reserved. +// + +#import "FSCalendarExtensions.h" +#import + +@implementation UIView (FSCalendarExtensions) + +- (CGFloat)fs_width +{ + return CGRectGetWidth(self.frame); +} + +- (void)setFs_width:(CGFloat)fs_width +{ + self.frame = CGRectMake(self.fs_left, self.fs_top, fs_width, self.fs_height); +} + +- (CGFloat)fs_height +{ + return CGRectGetHeight(self.frame); +} + +- (void)setFs_height:(CGFloat)fs_height +{ + self.frame = CGRectMake(self.fs_left, self.fs_top, self.fs_width, fs_height); +} + +- (CGFloat)fs_top +{ + return CGRectGetMinY(self.frame); +} + +- (void)setFs_top:(CGFloat)fs_top +{ + self.frame = CGRectMake(self.fs_left, fs_top, self.fs_width, self.fs_height); +} + +- (CGFloat)fs_bottom +{ + return CGRectGetMaxY(self.frame); +} + +- (void)setFs_bottom:(CGFloat)fs_bottom +{ + self.fs_top = fs_bottom - self.fs_height; +} + +- (CGFloat)fs_left +{ + return CGRectGetMinX(self.frame); +} + +- (void)setFs_left:(CGFloat)fs_left +{ + self.frame = CGRectMake(fs_left, self.fs_top, self.fs_width, self.fs_height); +} + +- (CGFloat)fs_right +{ + return CGRectGetMaxX(self.frame); +} + +- (void)setFs_right:(CGFloat)fs_right +{ + self.fs_left = self.fs_right - self.fs_width; +} + +@end + + +@implementation CALayer (FSCalendarExtensions) + +- (CGFloat)fs_width +{ + return CGRectGetWidth(self.frame); +} + +- (void)setFs_width:(CGFloat)fs_width +{ + self.frame = CGRectMake(self.fs_left, self.fs_top, fs_width, self.fs_height); +} + +- (CGFloat)fs_height +{ + return CGRectGetHeight(self.frame); +} + +- (void)setFs_height:(CGFloat)fs_height +{ + self.frame = CGRectMake(self.fs_left, self.fs_top, self.fs_width, fs_height); +} + +- (CGFloat)fs_top +{ + return CGRectGetMinY(self.frame); +} + +- (void)setFs_top:(CGFloat)fs_top +{ + self.frame = CGRectMake(self.fs_left, fs_top, self.fs_width, self.fs_height); +} + +- (CGFloat)fs_bottom +{ + return CGRectGetMaxY(self.frame); +} + +- (void)setFs_bottom:(CGFloat)fs_bottom +{ + self.fs_top = fs_bottom - self.fs_height; +} + +- (CGFloat)fs_left +{ + return CGRectGetMinX(self.frame); +} + +- (void)setFs_left:(CGFloat)fs_left +{ + self.frame = CGRectMake(fs_left, self.fs_top, self.fs_width, self.fs_height); +} + +- (CGFloat)fs_right +{ + return CGRectGetMaxX(self.frame); +} + +- (void)setFs_right:(CGFloat)fs_right +{ + self.fs_left = self.fs_right - self.fs_width; +} + +@end + +@interface NSCalendar (FSCalendarExtensionsPrivate) + +@property (readonly, nonatomic) NSDateComponents *fs_privateComponents; + +@end + +@implementation NSCalendar (FSCalendarExtensions) + +- (nullable NSDate *)fs_firstDayOfMonth:(NSDate *)month +{ + if (!month) return nil; + NSDateComponents *components = [self components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour fromDate:month]; + components.day = 1; + return [self dateFromComponents:components]; +} + +- (nullable NSDate *)fs_lastDayOfMonth:(NSDate *)month +{ + if (!month) return nil; + NSDateComponents *components = [self components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour fromDate:month]; + components.month++; + components.day = 0; + return [self dateFromComponents:components]; +} + +- (nullable NSDate *)fs_firstDayOfWeek:(NSDate *)week +{ + if (!week) return nil; + NSDateComponents *weekdayComponents = [self components:NSCalendarUnitWeekday fromDate:week]; + NSDateComponents *components = self.fs_privateComponents; + components.day = - (weekdayComponents.weekday - self.firstWeekday); + components.day = (components.day-7) % 7; + NSDate *firstDayOfWeek = [self dateByAddingComponents:components toDate:week options:0]; + firstDayOfWeek = [self dateBySettingHour:0 minute:0 second:0 ofDate:firstDayOfWeek options:0]; + components.day = NSIntegerMax; + return firstDayOfWeek; +} + +- (nullable NSDate *)fs_lastDayOfWeek:(NSDate *)week +{ + if (!week) return nil; + NSDateComponents *weekdayComponents = [self components:NSCalendarUnitWeekday fromDate:week]; + NSDateComponents *components = self.fs_privateComponents; + components.day = - (weekdayComponents.weekday - self.firstWeekday); + components.day = (components.day-7) % 7 + 6; + NSDate *lastDayOfWeek = [self dateByAddingComponents:components toDate:week options:0]; + lastDayOfWeek = [self dateBySettingHour:0 minute:0 second:0 ofDate:lastDayOfWeek options:0]; + components.day = NSIntegerMax; + return lastDayOfWeek; +} + +- (nullable NSDate *)fs_middleDayOfWeek:(NSDate *)week +{ + if (!week) return nil; + NSDateComponents *weekdayComponents = [self components:NSCalendarUnitWeekday fromDate:week]; + NSDateComponents *componentsToSubtract = self.fs_privateComponents; + componentsToSubtract.day = - (weekdayComponents.weekday - self.firstWeekday) + 3; + NSDate *middleDayOfWeek = [self dateByAddingComponents:componentsToSubtract toDate:week options:0]; + NSDateComponents *components = [self components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour fromDate:middleDayOfWeek]; + middleDayOfWeek = [self dateFromComponents:components]; + componentsToSubtract.day = NSIntegerMax; + return middleDayOfWeek; +} + +- (NSInteger)fs_numberOfDaysInMonth:(NSDate *)month +{ + if (!month) return 0; + NSRange days = [self rangeOfUnit:NSCalendarUnitDay + inUnit:NSCalendarUnitMonth + forDate:month]; + return days.length; +} + +- (NSDateComponents *)fs_privateComponents +{ + NSDateComponents *components = objc_getAssociatedObject(self, _cmd); + if (!components) { + components = [[NSDateComponents alloc] init]; + objc_setAssociatedObject(self, _cmd, components, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + } + return components; +} + +@end + +@implementation NSMapTable (FSCalendarExtensions) + +- (void)setObject:(nullable id)obj forKeyedSubscript:(id)key +{ + if (!key) return; + + if (obj) { + [self setObject:obj forKey:key]; + } else { + [self removeObjectForKey:key]; + } +} + +- (id)objectForKeyedSubscript:(id)key +{ + return [self objectForKey:key]; +} + +@end + +@implementation NSCache (FSCalendarExtensions) + +- (void)setObject:(nullable id)obj forKeyedSubscript:(id)key +{ + if (!key) return; + + if (obj) { + [self setObject:obj forKey:key]; + } else { + [self removeObjectForKey:key]; + } +} + +- (id)objectForKeyedSubscript:(id)key +{ + return [self objectForKey:key]; +} + +@end + +@implementation NSObject (FSCalendarExtensions) + +#define IVAR_IMP(SET,GET,TYPE) \ +- (void)fs_set##SET##Variable:(TYPE)value forKey:(NSString *)key \ +{ \ + Ivar ivar = class_getInstanceVariable([self class], key.UTF8String); \ + ((void (*)(id, Ivar, TYPE))object_setIvar)(self, ivar, value); \ +} \ +- (TYPE)fs_##GET##VariableForKey:(NSString *)key \ +{ \ + Ivar ivar = class_getInstanceVariable([self class], key.UTF8String); \ + ptrdiff_t offset = ivar_getOffset(ivar); \ + unsigned char *bytes = (unsigned char *)(__bridge void *)self; \ + TYPE value = *((TYPE *)(bytes+offset)); \ + return value; \ +} +IVAR_IMP(Bool,bool,BOOL) +IVAR_IMP(Float,float,CGFloat) +IVAR_IMP(Integer,integer,NSInteger) +IVAR_IMP(UnsignedInteger,unsignedInteger,NSUInteger) +#undef IVAR_IMP + +- (void)fs_setVariable:(id)variable forKey:(NSString *)key +{ + Ivar ivar = class_getInstanceVariable(self.class, key.UTF8String); + object_setIvar(self, ivar, variable); +} + +- (id)fs_variableForKey:(NSString *)key +{ + Ivar ivar = class_getInstanceVariable(self.class, key.UTF8String); + id variable = object_getIvar(self, ivar); + return variable; +} + +- (id)fs_performSelector:(SEL)selector withObjects:(nullable id)firstObject, ... +{ + if (!selector) return nil; + NSMethodSignature *signature = [self methodSignatureForSelector:selector]; + if (!signature) return nil; + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature]; + if (!invocation) return nil; + invocation.target = self; + invocation.selector = selector; + + // Parameters + if (firstObject) { + int index = 2; + va_list args; + va_start(args, firstObject); + if (firstObject) { + id obj = firstObject; + do { + const char *argType = [signature getArgumentTypeAtIndex:index]; + if(!strcmp(argType, @encode(id))){ + // object + [invocation setArgument:&obj atIndex:index++]; + } else { + NSString *argTypeString = [NSString stringWithUTF8String:argType]; + if ([argTypeString hasPrefix:@"{"] && [argTypeString hasSuffix:@"}"]) { + // struct +#define PARAM_STRUCT_TYPES(_type,_getter,_default) \ +if (!strcmp(argType, @encode(_type))) { \ + _type value = [obj respondsToSelector:@selector(_getter)]?[obj _getter]:_default; \ + [invocation setArgument:&value atIndex:index]; \ +} + PARAM_STRUCT_TYPES(CGPoint, CGPointValue, CGPointZero) + PARAM_STRUCT_TYPES(CGSize, CGSizeValue, CGSizeZero) + PARAM_STRUCT_TYPES(CGRect, CGRectValue, CGRectZero) + PARAM_STRUCT_TYPES(CGAffineTransform, CGAffineTransformValue, CGAffineTransformIdentity) + PARAM_STRUCT_TYPES(CATransform3D, CATransform3DValue, CATransform3DIdentity) + PARAM_STRUCT_TYPES(CGVector, CGVectorValue, CGVectorMake(0, 0)) + PARAM_STRUCT_TYPES(UIEdgeInsets, UIEdgeInsetsValue, UIEdgeInsetsZero) + PARAM_STRUCT_TYPES(UIOffset, UIOffsetValue, UIOffsetZero) + PARAM_STRUCT_TYPES(NSRange, rangeValue, NSMakeRange(NSNotFound, 0)) + +#undef PARAM_STRUCT_TYPES + index++; + } else { + // basic type +#define PARAM_BASIC_TYPES(_type,_getter) \ +if (!strcmp(argType, @encode(_type))) { \ + _type value = [obj respondsToSelector:@selector(_getter)]?[obj _getter]:0; \ + [invocation setArgument:&value atIndex:index]; \ +} + PARAM_BASIC_TYPES(BOOL, boolValue) + PARAM_BASIC_TYPES(int, intValue) + PARAM_BASIC_TYPES(unsigned int, unsignedIntValue) + PARAM_BASIC_TYPES(char, charValue) + PARAM_BASIC_TYPES(unsigned char, unsignedCharValue) + PARAM_BASIC_TYPES(long, longValue) + PARAM_BASIC_TYPES(unsigned long, unsignedLongValue) + PARAM_BASIC_TYPES(long long, longLongValue) + PARAM_BASIC_TYPES(unsigned long long, unsignedLongLongValue) + PARAM_BASIC_TYPES(float, floatValue) + PARAM_BASIC_TYPES(double, doubleValue) + +#undef PARAM_BASIC_TYPES + index++; + } + } + } while((obj = va_arg(args, id))); + + } + va_end(args); + [invocation retainArguments]; + } + + // Execute + [invocation invoke]; + + // Return + const char *returnType = signature.methodReturnType; + NSUInteger length = [signature methodReturnLength]; + id returnValue; + if (!strcmp(returnType, @encode(void))){ + // void + returnValue = nil; + } else if(!strcmp(returnType, @encode(id))){ + // id + void *value; + [invocation getReturnValue:&value]; + returnValue = (__bridge id)(value); + return returnValue; + } else { + NSString *returnTypeString = [NSString stringWithUTF8String:returnType]; + if ([returnTypeString hasPrefix:@"{"] && [returnTypeString hasSuffix:@"}"]) { + // struct +#define RETURN_STRUCT_TYPES(_type) \ +if (!strcmp(returnType, @encode(_type))) { \ + _type value; \ + [invocation getReturnValue:&value]; \ + returnValue = [NSValue value:&value withObjCType:@encode(_type)]; \ +} + RETURN_STRUCT_TYPES(CGPoint) + RETURN_STRUCT_TYPES(CGSize) + RETURN_STRUCT_TYPES(CGRect) + RETURN_STRUCT_TYPES(CGAffineTransform) + RETURN_STRUCT_TYPES(CATransform3D) + RETURN_STRUCT_TYPES(CGVector) + RETURN_STRUCT_TYPES(UIEdgeInsets) + RETURN_STRUCT_TYPES(UIOffset) + RETURN_STRUCT_TYPES(NSRange) + +#undef RETURN_STRUCT_TYPES + } else { + // basic + void *buffer = (void *)malloc(length); + [invocation getReturnValue:buffer]; +#define RETURN_BASIC_TYPES(_type) \ + if (!strcmp(returnType, @encode(_type))) { \ + returnValue = @(*((_type*)buffer)); \ +} + RETURN_BASIC_TYPES(BOOL) + RETURN_BASIC_TYPES(int) + RETURN_BASIC_TYPES(unsigned int) + RETURN_BASIC_TYPES(char) + RETURN_BASIC_TYPES(unsigned char) + RETURN_BASIC_TYPES(long) + RETURN_BASIC_TYPES(unsigned long) + RETURN_BASIC_TYPES(long long) + RETURN_BASIC_TYPES(unsigned long long) + RETURN_BASIC_TYPES(float) + RETURN_BASIC_TYPES(double) + +#undef RETURN_BASIC_TYPES + free(buffer); + } + } + return returnValue; +} + +@end + + diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarHeaderView.h b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarHeaderView.h new file mode 100644 index 0000000..2da931e --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarHeaderView.h @@ -0,0 +1,49 @@ +// +// FSCalendarHeader.h +// Pods +// +// Created by Wenchao Ding on 29/1/15. +// +// + +#import + + +@class FSCalendar, FSCalendarAppearance, FSCalendarHeaderLayout, FSCalendarCollectionView; + +@interface FSCalendarHeaderView : UIView + +@property (weak, nonatomic) FSCalendarCollectionView *collectionView; +@property (weak, nonatomic) FSCalendarHeaderLayout *collectionViewLayout; +@property (weak, nonatomic) FSCalendar *calendar; + +@property (assign, nonatomic) CGFloat scrollOffset; +@property (assign, nonatomic) UICollectionViewScrollDirection scrollDirection; +@property (assign, nonatomic) BOOL scrollEnabled; +@property (assign, nonatomic) BOOL needsAdjustingViewFrame; +@property (assign, nonatomic) BOOL needsAdjustingMonthPosition; + +- (void)setScrollOffset:(CGFloat)scrollOffset animated:(BOOL)animated; +- (void)reloadData; +- (void)configureAppearance; + +@end + + +@interface FSCalendarHeaderCell : UICollectionViewCell + +@property (weak, nonatomic) UILabel *titleLabel; +@property (weak, nonatomic) FSCalendarHeaderView *header; + +@end + +@interface FSCalendarHeaderLayout : UICollectionViewFlowLayout + +@end + +@interface FSCalendarHeaderTouchDeliver : UIView + +@property (weak, nonatomic) FSCalendar *calendar; +@property (weak, nonatomic) FSCalendarHeaderView *header; + +@end diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarHeaderView.m b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarHeaderView.m new file mode 100644 index 0000000..24614dc --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarHeaderView.m @@ -0,0 +1,327 @@ +// +// FSCalendarHeader.m +// Pods +// +// Created by Wenchao Ding on 29/1/15. +// +// + +#import "FSCalendar.h" +#import "NSString+Category.h" +#import "FSCalendarExtensions.h" +#import "FSCalendarHeaderView.h" +#import "FSCalendarCollectionView.h" +#import "FSCalendarDynamicHeader.h" + +@interface FSCalendarHeaderView () + +- (void)scrollToOffset:(CGFloat)scrollOffset animated:(BOOL)animated; +- (void)configureCell:(FSCalendarHeaderCell *)cell atIndexPath:(NSIndexPath *)indexPath; + +@end + +@implementation FSCalendarHeaderView + +#pragma mark - Life cycle + +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + [self initialize]; + } + return self; +} + +- (id)initWithCoder:(NSCoder *)aDecoder +{ + self = [super initWithCoder:aDecoder]; + if (self) { + [self initialize]; + } + return self; +} + +- (void)initialize +{ + _needsAdjustingViewFrame = YES; + _needsAdjustingMonthPosition = YES; + _scrollDirection = UICollectionViewScrollDirectionHorizontal; + _scrollEnabled = YES; + + FSCalendarHeaderLayout *collectionViewLayout = [[FSCalendarHeaderLayout alloc] init]; + self.collectionViewLayout = collectionViewLayout; + + FSCalendarCollectionView *collectionView = [[FSCalendarCollectionView alloc] initWithFrame:CGRectZero collectionViewLayout:collectionViewLayout]; + collectionView.scrollEnabled = NO; + collectionView.userInteractionEnabled = NO; + collectionView.backgroundColor = [UIColor clearColor]; + collectionView.dataSource = self; + collectionView.delegate = self; + collectionView.showsHorizontalScrollIndicator = NO; + collectionView.showsVerticalScrollIndicator = NO; + [self addSubview:collectionView]; + [collectionView registerClass:[FSCalendarHeaderCell class] forCellWithReuseIdentifier:@"cell"]; + self.collectionView = collectionView; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + if (_needsAdjustingViewFrame) { + _needsAdjustingViewFrame = NO; + _collectionViewLayout.itemSize = CGSizeMake(1, 1); + [_collectionViewLayout invalidateLayout]; + _collectionView.frame = CGRectMake(0, self.fs_height*0.1, self.fs_width, self.fs_height*0.9); + } + + if (_needsAdjustingMonthPosition) { + _needsAdjustingMonthPosition = NO; + [self scrollToOffset:_scrollOffset animated:NO]; + } + +} + +- (void)dealloc +{ + _collectionView.dataSource = nil; + _collectionView.delegate = nil; +} + +#pragma mark - + +- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView +{ + return 1; +} + +- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section +{ + NSInteger numberOfSections = self.calendar.collectionView.numberOfSections; + if (self.scrollDirection == UICollectionViewScrollDirectionVertical) { + return numberOfSections; + } + return numberOfSections + 2; +} + +- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath +{ + FSCalendarHeaderCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"cell" forIndexPath:indexPath]; + cell.header = self; + if ([self.calendar.calendarIdentifier isRTLCalendar]) { + [cell setTransform:CGAffineTransformMakeScale(-1, 1)]; + } + [self configureCell:cell atIndexPath:indexPath]; + return cell; +} + +- (void)collectionView:(UICollectionView *)collectionView didEndDisplayingCell:(UICollectionViewCell *)cell forItemAtIndexPath:(NSIndexPath *)indexPath +{ + [cell setNeedsLayout]; +} + +- (void)scrollViewDidScroll:(UIScrollView *)scrollView +{ + [_collectionView.visibleCells makeObjectsPerformSelector:@selector(setNeedsLayout)]; +} + +#pragma mark - Properties + +- (void)setCalendar:(FSCalendar *)calendar +{ + _calendar = calendar; + [self configureAppearance]; +} + +- (void)setScrollOffset:(CGFloat)scrollOffset +{ + [self setScrollOffset:scrollOffset animated:NO]; +} + +- (void)setScrollOffset:(CGFloat)scrollOffset animated:(BOOL)animated +{ + if (_scrollOffset != scrollOffset) { + _scrollOffset = scrollOffset; + } + [self scrollToOffset:scrollOffset animated:NO]; +} + +- (void)scrollToOffset:(CGFloat)scrollOffset animated:(BOOL)animated +{ + if (self.scrollDirection == UICollectionViewScrollDirectionHorizontal) { + CGFloat step = self.collectionView.fs_width*((self.scrollDirection==UICollectionViewScrollDirectionHorizontal)?0.5:1); + [_collectionView setContentOffset:CGPointMake((scrollOffset+0.5)*step, 0) animated:animated]; + } else { + CGFloat step = self.collectionView.fs_height; + [_collectionView setContentOffset:CGPointMake(0, scrollOffset*step) animated:animated]; + } +} + +- (void)setScrollDirection:(UICollectionViewScrollDirection)scrollDirection +{ + if (_scrollDirection != scrollDirection) { + _scrollDirection = scrollDirection; + _collectionViewLayout.scrollDirection = scrollDirection; + _needsAdjustingMonthPosition = YES; + [self setNeedsLayout]; + } +} + +- (void)setScrollEnabled:(BOOL)scrollEnabled +{ + if (_scrollEnabled != scrollEnabled) { + _scrollEnabled = scrollEnabled; + [_collectionView.visibleCells makeObjectsPerformSelector:@selector(setNeedsLayout)]; + } +} + +#pragma mark - Public + +- (void)reloadData +{ + [_collectionView reloadData]; +} + +- (void)configureCell:(FSCalendarHeaderCell *)cell atIndexPath:(NSIndexPath *)indexPath +{ + FSCalendarAppearance *appearance = self.calendar.appearance; + cell.titleLabel.font = appearance.headerTitleFont; + cell.titleLabel.textColor = appearance.headerTitleColor; + _calendar.formatter.dateFormat = appearance.headerDateFormat; + BOOL usesUpperCase = (appearance.caseOptions & 15) == FSCalendarCaseOptionsHeaderUsesUpperCase; + NSString *text = nil; + switch (self.calendar.transitionCoordinator.representingScope) { + case FSCalendarScopeMonth: { + if (_scrollDirection == UICollectionViewScrollDirectionHorizontal) { + // 多出的两项需要制空 + if ((indexPath.item == 0 || indexPath.item == [self.collectionView numberOfItemsInSection:0] - 1)) { + text = nil; + } else { + NSDate *date = [self.calendar.gregorian dateByAddingUnit:NSCalendarUnitMonth value:indexPath.item-1 toDate:self.calendar.minimumDate options:0]; + text = [_calendar.formatter stringFromDate:date]; + } + } else { + NSDate *date = [self.calendar.gregorian dateByAddingUnit:NSCalendarUnitMonth value:indexPath.item toDate:self.calendar.minimumDate options:0]; + text = [_calendar.formatter stringFromDate:date]; + } + break; + } + case FSCalendarScopeWeek: { + if ((indexPath.item == 0 || indexPath.item == [self.collectionView numberOfItemsInSection:0] - 1)) { + text = nil; + } else { + NSDate *firstPage = [self.calendar.gregorian fs_middleDayOfWeek:self.calendar.minimumDate]; + NSDate *date = [self.calendar.gregorian dateByAddingUnit:NSCalendarUnitWeekOfYear value:indexPath.item-1 toDate:firstPage options:0]; + text = [_calendar.formatter stringFromDate:date]; + } + break; + } + default: { + break; + } + } + text = usesUpperCase ? text.uppercaseString : text; + cell.titleLabel.text = text; + [cell setNeedsLayout]; +} + +- (void)configureAppearance +{ + [self.collectionView.visibleCells enumerateObjectsUsingBlock:^(__kindof FSCalendarHeaderCell * _Nonnull cell, NSUInteger idx, BOOL * _Nonnull stop) { + [self configureCell:cell atIndexPath:[self.collectionView indexPathForCell:cell]]; + }]; +} + +@end + + +@implementation FSCalendarHeaderCell + +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + titleLabel.textAlignment = NSTextAlignmentCenter; + titleLabel.lineBreakMode = NSLineBreakByWordWrapping; + titleLabel.numberOfLines = 0; + [self.contentView addSubview:titleLabel]; + self.titleLabel = titleLabel; + } + return self; +} + +- (void)setBounds:(CGRect)bounds +{ + [super setBounds:bounds]; + _titleLabel.frame = bounds; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + self.titleLabel.frame = self.contentView.bounds; + + if (self.header.scrollDirection == UICollectionViewScrollDirectionHorizontal) { + CGFloat position = [self.contentView convertPoint:CGPointMake(CGRectGetMidX(self.contentView.bounds), CGRectGetMidY(self.contentView.bounds)) toView:self.header].x; + CGFloat center = CGRectGetMidX(self.header.bounds); + if (self.header.scrollEnabled) { + self.contentView.alpha = 1.0 - (1.0-self.header.calendar.appearance.headerMinimumDissolvedAlpha)*ABS(center-position)/self.fs_width; + } else { + self.contentView.alpha = (position > self.header.fs_width*0.25 && position < self.header.fs_width*0.75); + } + } else if (self.header.scrollDirection == UICollectionViewScrollDirectionVertical) { + CGFloat position = [self.contentView convertPoint:CGPointMake(CGRectGetMidX(self.contentView.bounds), CGRectGetMidY(self.contentView.bounds)) toView:self.header].y; + CGFloat center = CGRectGetMidY(self.header.bounds); + self.contentView.alpha = 1.0 - (1.0-self.header.calendar.appearance.headerMinimumDissolvedAlpha)*ABS(center-position)/self.fs_height; + } + +} + +@end + + +@implementation FSCalendarHeaderLayout + +- (instancetype)init +{ + self = [super init]; + if (self) { + self.scrollDirection = UICollectionViewScrollDirectionHorizontal; + self.minimumInteritemSpacing = 0; + self.minimumLineSpacing = 0; + self.sectionInset = UIEdgeInsetsZero; + self.itemSize = CGSizeMake(1, 1); + } + return self; +} + +- (void)prepareLayout +{ + [super prepareLayout]; + + self.itemSize = CGSizeMake( + self.collectionView.fs_width*((self.scrollDirection==UICollectionViewScrollDirectionHorizontal)?0.5:1), + self.collectionView.fs_height + ); + +} + +@end + +@implementation FSCalendarHeaderTouchDeliver + +- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event +{ + UIView *hitView = [super hitTest:point withEvent:event]; + if (hitView == self) { + return _calendar.collectionView ?: hitView; + } + return hitView; +} + +@end + + diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarScopeHandle.h b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarScopeHandle.h new file mode 100644 index 0000000..455c3cf --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarScopeHandle.h @@ -0,0 +1,20 @@ +// +// FSCalendarScopeHandle.h +// FSCalendar +// +// Created by dingwenchao on 4/29/16. +// Copyright © 2016 Wenchao Ding. All rights reserved. +// + +#import + +@class FSCalendar; + +@interface FSCalendarScopeHandle : UIView + +@property (weak, nonatomic) UIPanGestureRecognizer *panGesture; +@property (weak, nonatomic) FSCalendar *calendar; + +- (void)handlePan:(id)sender; + +@end diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarScopeHandle.m b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarScopeHandle.m new file mode 100644 index 0000000..6eb789c --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarScopeHandle.m @@ -0,0 +1,78 @@ +// +// FSCalendarScopeHandle.m +// FSCalendar +// +// Created by dingwenchao on 4/29/16. +// Copyright © 2016 Wenchao Ding. All rights reserved. +// + +#import "FSCalendarScopeHandle.h" +#import "FSCalendar.h" +#import "FSCalendarTransitionCoordinator.h" +#import "FSCalendarDynamicHeader.h" +#import "FSCalendarExtensions.h" + +@interface FSCalendarScopeHandle () + +@property (weak, nonatomic) UIView *topBorder; +@property (weak, nonatomic) UIView *handleIndicator; + +@property (weak, nonatomic) FSCalendarAppearance *appearance; + +@property (assign, nonatomic) CGFloat lastTranslation; + +@end + +@implementation FSCalendarScopeHandle + +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + + UIView *view; + + view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 0, 1)]; + view.backgroundColor = FSCalendarStandardLineColor; + [self addSubview:view]; + self.topBorder = view; + + view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 30, 6)]; + view.layer.shouldRasterize = YES; + view.layer.masksToBounds = YES; + view.layer.cornerRadius = 3; + view.layer.backgroundColor = FSCalendarStandardScopeHandleColor.CGColor; + [self addSubview:view]; + self.handleIndicator = view; + + UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePan:)]; + panGesture.minimumNumberOfTouches = 1; + panGesture.maximumNumberOfTouches = 2; + [self addGestureRecognizer:panGesture]; + self.panGesture = panGesture; + + self.exclusiveTouch = YES; + + } + return self; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + self.topBorder.frame = CGRectMake(0, 0, self.fs_width, 1); + self.handleIndicator.center = CGPointMake(self.fs_width/2, self.fs_height/2-0.5); +} + +- (void)handlePan:(id)sender +{ + [self.calendar.transitionCoordinator handleScopeGesture:sender]; +} + +- (void)setCalendar:(FSCalendar *)calendar +{ + _calendar = calendar; + self.panGesture.delegate = self.calendar.transitionCoordinator; +} + +@end diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarStickyHeader.h b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarStickyHeader.h new file mode 100644 index 0000000..0391004 --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarStickyHeader.h @@ -0,0 +1,23 @@ +// +// FSCalendarStaticHeader.h +// FSCalendar +// +// Created by dingwenchao on 9/17/15. +// Copyright (c) 2015 Wenchao Ding. All rights reserved. +// + +#import + +@class FSCalendar,FSCalendarAppearance; + +@interface FSCalendarStickyHeader : UICollectionReusableView + +@property (weak, nonatomic) FSCalendar *calendar; + +@property (weak, nonatomic) UILabel *titleLabel; + +@property (strong, nonatomic) NSDate *month; + +- (void)configureAppearance; + +@end diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarStickyHeader.m b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarStickyHeader.m new file mode 100644 index 0000000..56fb75d --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarStickyHeader.m @@ -0,0 +1,108 @@ +// +// FSCalendarStaticHeader.m +// FSCalendar +// +// Created by dingwenchao on 9/17/15. +// Copyright (c) 2015 Wenchao Ding. All rights reserved. +// + +#import "FSCalendarStickyHeader.h" +#import "FSCalendar.h" +#import "FSCalendarWeekdayView.h" +#import "FSCalendarExtensions.h" +#import "FSCalendarConstants.h" +#import "FSCalendarDynamicHeader.h" + +@interface FSCalendarStickyHeader () + +@property (weak , nonatomic) UIView *contentView; +@property (weak , nonatomic) UIView *bottomBorder; +@property (weak , nonatomic) FSCalendarWeekdayView *weekdayView; + +@end + +@implementation FSCalendarStickyHeader + +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + + UIView *view; + UILabel *label; + + view = [[UIView alloc] initWithFrame:CGRectZero]; + view.backgroundColor = [UIColor clearColor]; + [self addSubview:view]; + self.contentView = view; + + label = [[UILabel alloc] initWithFrame:CGRectZero]; + label.textAlignment = NSTextAlignmentCenter; + label.numberOfLines = 0; + [_contentView addSubview:label]; + self.titleLabel = label; + + view = [[UIView alloc] initWithFrame:CGRectZero]; + view.backgroundColor = FSCalendarStandardLineColor; + [_contentView addSubview:view]; + self.bottomBorder = view; + + FSCalendarWeekdayView *weekdayView = [[FSCalendarWeekdayView alloc] init]; + [self.contentView addSubview:weekdayView]; + self.weekdayView = weekdayView; + } + return self; +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + _contentView.frame = self.bounds; + + CGFloat weekdayHeight = _calendar.preferredWeekdayHeight; + CGFloat weekdayMargin = weekdayHeight * 0.1; + CGFloat titleWidth = _contentView.fs_width; + + self.weekdayView.frame = CGRectMake(0, _contentView.fs_height-weekdayHeight-weekdayMargin, self.contentView.fs_width, weekdayHeight); + + CGFloat titleHeight = [@"1" sizeWithAttributes:@{NSFontAttributeName:self.calendar.appearance.headerTitleFont}].height*1.5 + weekdayMargin*3; + + _bottomBorder.frame = CGRectMake(0, _contentView.fs_height-weekdayHeight-weekdayMargin*2, _contentView.fs_width, 1.0); + _titleLabel.frame = CGRectMake(0, _bottomBorder.fs_bottom-titleHeight-weekdayMargin, titleWidth,titleHeight); + +} + +#pragma mark - Properties + +- (void)setCalendar:(FSCalendar *)calendar +{ + if (![_calendar isEqual:calendar]) { + _calendar = calendar; + _weekdayView.calendar = calendar; + [self configureAppearance]; + } +} + +#pragma mark - Private methods + +- (void)configureAppearance +{ + _titleLabel.font = self.calendar.appearance.headerTitleFont; + _titleLabel.textColor = self.calendar.appearance.headerTitleColor; + [self.weekdayView configureAppearance]; +} + +- (void)setMonth:(NSDate *)month +{ + _month = month; + _calendar.formatter.dateFormat = self.calendar.appearance.headerDateFormat; + BOOL usesUpperCase = (self.calendar.appearance.caseOptions & 15) == FSCalendarCaseOptionsHeaderUsesUpperCase; + NSString *text = [_calendar.formatter stringFromDate:_month]; + text = usesUpperCase ? text.uppercaseString : text; + self.titleLabel.text = text; +} + +@end + + diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarTransitionCoordinator.h b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarTransitionCoordinator.h new file mode 100644 index 0000000..eccbafd --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarTransitionCoordinator.h @@ -0,0 +1,59 @@ +// +// FSCalendarTransitionCoordinator.h +// FSCalendar +// +// Created by dingwenchao on 3/13/16. +// Copyright © 2016 Wenchao Ding. All rights reserved. +// + +#import "FSCalendar.h" +#import "FSCalendarCollectionView.h" +#import "FSCalendarCollectionViewLayout.h" +#import "FSCalendarScopeHandle.h" + +typedef NS_ENUM(NSUInteger, FSCalendarTransition) { + FSCalendarTransitionNone, + FSCalendarTransitionMonthToWeek, + FSCalendarTransitionWeekToMonth +}; +typedef NS_ENUM(NSUInteger, FSCalendarTransitionState) { + FSCalendarTransitionStateIdle, + FSCalendarTransitionStateChanging, + FSCalendarTransitionStateFinishing, +}; + +@interface FSCalendarTransitionCoordinator : NSObject + +@property (weak, nonatomic) FSCalendar *calendar; +@property (weak, nonatomic) FSCalendarCollectionView *collectionView; +@property (weak, nonatomic) FSCalendarCollectionViewLayout *collectionViewLayout; + +@property (assign, nonatomic) FSCalendarTransition transition; +@property (assign, nonatomic) FSCalendarTransitionState state; + +@property (assign, nonatomic) CGSize cachedMonthSize; + +@property (readonly, nonatomic) FSCalendarScope representingScope; + +- (instancetype)initWithCalendar:(FSCalendar *)calendar; + +- (void)performScopeTransitionFromScope:(FSCalendarScope)fromScope toScope:(FSCalendarScope)toScope animated:(BOOL)animated; +- (void)performBoundingRectTransitionFromMonth:(NSDate *)fromMonth toMonth:(NSDate *)toMonth duration:(CGFloat)duration; + +- (void)handleScopeGesture:(id)sender; + +@end + + +@interface FSCalendarTransitionAttributes : NSObject + +@property (assign, nonatomic) CGRect sourceBounds; +@property (assign, nonatomic) CGRect targetBounds; +@property (strong, nonatomic) NSDate *sourcePage; +@property (strong, nonatomic) NSDate *targetPage; +@property (assign, nonatomic) NSInteger focusedRowNumber; +@property (assign, nonatomic) NSDate *focusedDate; +@property (strong, nonatomic) NSDate *firstDayOfMonth; + +@end + diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarTransitionCoordinator.m b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarTransitionCoordinator.m new file mode 100644 index 0000000..ae266dc --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarTransitionCoordinator.m @@ -0,0 +1,746 @@ +// +// FSCalendarTransitionCoordinator.m +// FSCalendar +// +// Created by Wenchao Ding on 3/13/16. +// Copyright © 2016 Wenchao Ding. All rights reserved. +// + +#import "FSCalendarTransitionCoordinator.h" +#import "FSCalendarExtensions.h" +#import "FSCalendarDynamicHeader.h" +#import + +@interface FSCalendarTransitionCoordinator () + +@property (readonly, nonatomic) FSCalendarTransitionAttributes *transitionAttributes; +@property (strong , nonatomic) FSCalendarTransitionAttributes *pendingAttributes; +@property (assign , nonatomic) CGFloat lastTranslation; + +- (void)performTransitionCompletionAnimated:(BOOL)animated; +- (void)performTransitionCompletion:(FSCalendarTransition)transition animated:(BOOL)animated; + +- (void)performAlphaAnimationFrom:(CGFloat)fromAlpha to:(CGFloat)toAlpha duration:(CGFloat)duration exception:(NSInteger)exception completion:(void(^)(void))completion; +- (void)performForwardTransition:(FSCalendarTransition)transition fromProgress:(CGFloat)progress; +- (void)performBackwardTransition:(FSCalendarTransition)transition fromProgress:(CGFloat)progress; +- (void)performAlphaAnimationWithProgress:(CGFloat)progress; +- (void)performPathAnimationWithProgress:(CGFloat)progress; + +- (void)scopeTransitionDidBegin:(UIPanGestureRecognizer *)panGesture; +- (void)scopeTransitionDidUpdate:(UIPanGestureRecognizer *)panGesture; +- (void)scopeTransitionDidEnd:(UIPanGestureRecognizer *)panGesture; + +- (CGRect)boundingRectForScope:(FSCalendarScope)scope page:(NSDate *)page; + +- (void)boundingRectWillChange:(CGRect)targetBounds animated:(BOOL)animated; + +@end + +@implementation FSCalendarTransitionCoordinator + +- (instancetype)initWithCalendar:(FSCalendar *)calendar +{ + self = [super init]; + if (self) { + self.calendar = calendar; + self.collectionView = self.calendar.collectionView; + self.collectionViewLayout = self.calendar.collectionViewLayout; + } + return self; +} + +#pragma mark - Target actions + +- (void)handleScopeGesture:(UIPanGestureRecognizer *)sender +{ + switch (sender.state) { + case UIGestureRecognizerStateBegan: { + [self scopeTransitionDidBegin:sender]; + break; + } + case UIGestureRecognizerStateChanged: { + [self scopeTransitionDidUpdate:sender]; + break; + } + case UIGestureRecognizerStateEnded: + case UIGestureRecognizerStateCancelled: + case UIGestureRecognizerStateFailed:{ + [self scopeTransitionDidEnd:sender]; + break; + } + default: { + break; + } + } +} + +#pragma mark - + +- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer +{ + if (self.state != FSCalendarTransitionStateIdle) { + return NO; + } +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + + if (gestureRecognizer == self.calendar.scopeGesture && self.calendar.collectionViewLayout.scrollDirection == UICollectionViewScrollDirectionVertical) { + return NO; + } + if (gestureRecognizer == self.calendar.scopeHandle.panGesture) { + CGFloat velocity = [(UIPanGestureRecognizer *)gestureRecognizer velocityInView:gestureRecognizer.view].y; + return self.calendar.scope == FSCalendarScopeWeek ? velocity >= 0 : velocity <= 0; + } + if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] && [[gestureRecognizer valueForKey:@"_targets"] containsObject:self.calendar]) { + CGPoint velocity = [(UIPanGestureRecognizer *)gestureRecognizer velocityInView:gestureRecognizer.view]; + BOOL shouldStart = self.calendar.scope == FSCalendarScopeWeek ? velocity.y >= 0 : velocity.y <= 0; + if (!shouldStart) return NO; + shouldStart = (ABS(velocity.x)<=ABS(velocity.y)); + if (shouldStart) { + self.calendar.collectionView.panGestureRecognizer.enabled = NO; + self.calendar.collectionView.panGestureRecognizer.enabled = YES; + } + return shouldStart; + } + return YES; + +#pragma GCC diagnostic pop + + return NO; +} + +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer +{ + return otherGestureRecognizer == self.collectionView.panGestureRecognizer && self.collectionView.decelerating; +} + +- (void)scopeTransitionDidBegin:(UIPanGestureRecognizer *)panGesture +{ + if (self.state != FSCalendarTransitionStateIdle) return; + + CGPoint velocity = [panGesture velocityInView:panGesture.view]; + switch (self.calendar.scope) { + case FSCalendarScopeMonth: { + if (velocity.y < 0) { + self.state = FSCalendarTransitionStateChanging; + self.transition = FSCalendarTransitionMonthToWeek; + } + break; + } + case FSCalendarScopeWeek: { + if (velocity.y > 0) { + self.state = FSCalendarTransitionStateChanging; + self.transition = FSCalendarTransitionWeekToMonth; + } + break; + } + default: + break; + } + if (self.state != FSCalendarTransitionStateChanging) return; + + self.pendingAttributes = self.transitionAttributes; + self.lastTranslation = [panGesture translationInView:panGesture.view].y; + + if (self.transition == FSCalendarTransitionWeekToMonth) { + [self.calendar fs_setVariable:self.pendingAttributes.targetPage forKey:@"_currentPage"]; + [self prelayoutForWeekToMonthTransition]; + self.collectionView.fs_top = -self.pendingAttributes.focusedRowNumber*self.calendar.collectionViewLayout.estimatedItemSize.height; + + } +} + +- (void)scopeTransitionDidUpdate:(UIPanGestureRecognizer *)panGesture +{ + if (self.state != FSCalendarTransitionStateChanging) return; + + CGFloat translation = [panGesture translationInView:panGesture.view].y; + + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + switch (self.transition) { + case FSCalendarTransitionMonthToWeek: { + CGFloat progress = ({ + CGFloat minTranslation = CGRectGetHeight(self.pendingAttributes.targetBounds) - CGRectGetHeight(self.pendingAttributes.sourceBounds); + translation = MAX(minTranslation, translation); + translation = MIN(0, translation); + CGFloat progress = translation/minTranslation; + progress; + }); + [self performAlphaAnimationWithProgress:progress]; + [self performPathAnimationWithProgress:progress]; + break; + } + case FSCalendarTransitionWeekToMonth: { + CGFloat progress = ({ + CGFloat maxTranslation = CGRectGetHeight(self.pendingAttributes.targetBounds) - CGRectGetHeight(self.pendingAttributes.sourceBounds); + translation = MIN(maxTranslation, translation); + translation = MAX(0, translation); + CGFloat progress = translation/maxTranslation; + progress; + }); + [self performAlphaAnimationWithProgress:progress]; + [self performPathAnimationWithProgress:progress]; + break; + } + default: + break; + } + [CATransaction commit]; + self.lastTranslation = translation; +} + +- (void)scopeTransitionDidEnd:(UIPanGestureRecognizer *)panGesture +{ + if (self.state != FSCalendarTransitionStateChanging) return; + + self.state = FSCalendarTransitionStateFinishing; + + CGFloat translation = [panGesture translationInView:panGesture.view].y; + CGFloat velocity = [panGesture velocityInView:panGesture.view].y; + + switch (self.transition) { + case FSCalendarTransitionMonthToWeek: { + CGFloat progress = ({ + CGFloat minTranslation = CGRectGetHeight(self.pendingAttributes.targetBounds) - CGRectGetHeight(self.pendingAttributes.sourceBounds); + translation = MAX(minTranslation, translation); + translation = MIN(0, translation); + CGFloat progress = translation/minTranslation; + progress; + }); + if (velocity >= 0) { + [self performBackwardTransition:self.transition fromProgress:progress]; + } else { + [self performForwardTransition:self.transition fromProgress:progress]; + } + break; + } + case FSCalendarTransitionWeekToMonth: { + CGFloat progress = ({ + CGFloat maxTranslation = CGRectGetHeight(self.pendingAttributes.targetBounds) - CGRectGetHeight(self.pendingAttributes.sourceBounds); + translation = MAX(0, translation); + translation = MIN(maxTranslation, translation); + CGFloat progress = translation/maxTranslation; + progress; + }); + if (velocity >= 0) { + [self performForwardTransition:self.transition fromProgress:progress]; + } else { + [self performBackwardTransition:self.transition fromProgress:progress]; + } + break; + } + default: + break; + } + +} + +#pragma mark - Public methods + +- (void)performScopeTransitionFromScope:(FSCalendarScope)fromScope toScope:(FSCalendarScope)toScope animated:(BOOL)animated +{ + if (fromScope == toScope) return; + + self.transition = ({ + FSCalendarTransition transition = FSCalendarTransitionNone; + if (fromScope == FSCalendarScopeMonth && toScope == FSCalendarScopeWeek) { + transition = FSCalendarTransitionMonthToWeek; + } else if (fromScope == FSCalendarScopeWeek && toScope == FSCalendarScopeMonth) { + transition = FSCalendarTransitionWeekToMonth; + } + transition; + }); + + // Start transition + self.state = FSCalendarTransitionStateFinishing; + FSCalendarTransitionAttributes *attr = self.transitionAttributes; + self.pendingAttributes = attr; + + switch (self.transition) { + + case FSCalendarTransitionMonthToWeek: { + + [self.calendar fs_setVariable:attr.targetPage forKey:@"_currentPage"]; + self.calendar.contentView.clipsToBounds = YES; + + if (animated) { + CGFloat duration = 0.3; + + [self performAlphaAnimationFrom:1 to:0 duration:0.22 exception:attr.focusedRowNumber completion:^{ + [self performTransitionCompletionAnimated:animated]; + }]; + + if (self.calendar.delegate && ([self.calendar.delegate respondsToSelector:@selector(calendar:boundingRectWillChange:animated:)] || [self.calendar.delegate respondsToSelector:@selector(calendarCurrentScopeWillChange:animated:)])) { + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationsEnabled:YES]; + [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; + [UIView setAnimationDuration:duration]; + self.collectionView.fs_top = -attr.focusedRowNumber*self.calendar.collectionViewLayout.estimatedItemSize.height; + [self boundingRectWillChange:attr.targetBounds animated:animated]; + [UIView commitAnimations]; + } + + } else { + + [self performTransitionCompletionAnimated:animated]; + [self boundingRectWillChange:attr.targetBounds animated:animated]; + + } + + break; + } + + case FSCalendarTransitionWeekToMonth: { + + [self.calendar fs_setVariable:attr.targetPage forKey:@"_currentPage"]; + + [self prelayoutForWeekToMonthTransition]; + + if (animated) { + + CGFloat duration = 0.3; + + [self performAlphaAnimationFrom:0 to:1 duration:duration exception:attr.focusedRowNumber completion:^{ + [self performTransitionCompletionAnimated:animated]; + }]; + + [CATransaction begin]; + [CATransaction setDisableActions:NO]; + if (self.calendar.delegate && ([self.calendar.delegate respondsToSelector:@selector(calendar:boundingRectWillChange:animated:)] || [self.calendar.delegate respondsToSelector:@selector(calendarCurrentScopeWillChange:animated:)])) { + self.collectionView.fs_top = -attr.focusedRowNumber*self.calendar.collectionViewLayout.estimatedItemSize.height; + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationsEnabled:YES]; + [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; + [UIView setAnimationDuration:duration]; + self.collectionView.fs_top = 0; + [self boundingRectWillChange:attr.targetBounds animated:animated]; + [UIView commitAnimations]; + } + [CATransaction commit]; + + } else { + + [self performTransitionCompletionAnimated:animated]; + [self boundingRectWillChange:attr.targetBounds animated:animated]; + + } + break; + } + default: + break; + } + +} + +- (void)performBoundingRectTransitionFromMonth:(NSDate *)fromMonth toMonth:(NSDate *)toMonth duration:(CGFloat)duration +{ + if (self.calendar.scope != FSCalendarScopeMonth) return; + NSInteger lastRowCount = [self.calendar.calculator numberOfRowsInMonth:fromMonth]; + NSInteger currentRowCount = [self.calendar.calculator numberOfRowsInMonth:toMonth]; + if (lastRowCount != currentRowCount) { + CGFloat animationDuration = duration; + CGRect bounds = (CGRect){CGPointZero,[self.calendar sizeThatFits:self.calendar.frame.size scope:FSCalendarScopeMonth]}; + self.state = FSCalendarTransitionStateChanging; + void (^completion)(BOOL) = ^(BOOL finished) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(MAX(0, duration-animationDuration) * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + self.calendar.needsAdjustingViewFrame = YES; + [self.calendar setNeedsLayout]; + self.state = FSCalendarTransitionStateIdle; + }); + }; + if (FSCalendarInAppExtension) { + // Detect today extension: http://stackoverflow.com/questions/25048026/ios-8-extension-how-to-detect-running + [self boundingRectWillChange:bounds animated:YES]; + completion(YES); + } else { + [UIView animateWithDuration:animationDuration delay:0 options:UIViewAnimationOptionAllowUserInteraction animations:^{ + [self boundingRectWillChange:bounds animated:YES]; + } completion:completion]; + } + + } +} + +#pragma mark - Private properties + +- (void)performTransitionCompletionAnimated:(BOOL)animated +{ + [self performTransitionCompletion:self.transition animated:animated]; +} + +- (void)performTransitionCompletion:(FSCalendarTransition)transition animated:(BOOL)animated +{ + switch (transition) { + case FSCalendarTransitionMonthToWeek: { + [self.calendar.visibleCells enumerateObjectsUsingBlock:^(UICollectionViewCell *obj, NSUInteger idx, BOOL * stop) { + obj.contentView.layer.opacity = 1; + }]; + self.collectionViewLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal; + self.calendar.calendarHeaderView.scrollDirection = self.collectionViewLayout.scrollDirection; + self.calendar.needsAdjustingViewFrame = YES; + [self.collectionView reloadData]; + [self.calendar.calendarHeaderView reloadData]; + break; + } + case FSCalendarTransitionWeekToMonth: { + self.calendar.needsAdjustingViewFrame = YES; + [self.calendar.visibleCells enumerateObjectsUsingBlock:^(UICollectionViewCell *obj, NSUInteger idx, BOOL * stop) { + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + obj.contentView.layer.opacity = 1; + [CATransaction commit]; + [obj.contentView.layer removeAnimationForKey:@"opacity"]; + }]; + break; + } + default: + break; + } + self.state = FSCalendarTransitionStateIdle; + self.transition = FSCalendarTransitionNone; + self.calendar.contentView.clipsToBounds = NO; + self.pendingAttributes = nil; + [self.calendar setNeedsLayout]; + [self.calendar layoutIfNeeded]; +} + +- (FSCalendarTransitionAttributes *)transitionAttributes +{ + FSCalendarTransitionAttributes *attributes = [[FSCalendarTransitionAttributes alloc] init]; + attributes.sourceBounds = self.calendar.bounds; + attributes.sourcePage = self.calendar.currentPage; + switch (self.transition) { + + case FSCalendarTransitionMonthToWeek: { + + NSDate *focusedDate = ({ + NSArray *candidates = ({ + NSMutableArray *dates = self.calendar.selectedDates.reverseObjectEnumerator.allObjects.mutableCopy; + if (self.calendar.today) { + [dates addObject:self.calendar.today]; + } + if (self.calendar.currentPage) { + [dates addObject:self.calendar.currentPage]; + } + dates.copy; + }); + NSArray *visibleCandidates = [candidates filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(NSDate * _Nullable evaluatedObject, NSDictionary * _Nullable bindings) { + NSIndexPath *indexPath = [self.calendar.calculator indexPathForDate:evaluatedObject scope:FSCalendarScopeMonth]; + NSInteger currentSection = [self.calendar.calculator indexPathForDate:self.calendar.currentPage scope:FSCalendarScopeMonth].section; + return indexPath.section == currentSection; + }]]; + NSDate *date = visibleCandidates.firstObject; + date; + }); + NSInteger focusedRow = [self.calendar.calculator coordinateForIndexPath:[self.calendar.calculator indexPathForDate:focusedDate scope:FSCalendarScopeMonth]].row; + + NSDate *currentPage = self.calendar.currentPage; + NSIndexPath *indexPath = [self.calendar.calculator indexPathForDate:currentPage scope:FSCalendarScopeMonth]; + NSDate *monthHead = [self.calendar.calculator monthHeadForSection:indexPath.section]; + NSDate *targetPage = [self.calendar.gregorian dateByAddingUnit:NSCalendarUnitDay value:focusedRow*7 toDate:monthHead options:0]; + + attributes.focusedRowNumber = focusedRow; + attributes.focusedDate = focusedDate; + attributes.targetPage = targetPage; + attributes.targetBounds = [self boundingRectForScope:FSCalendarScopeWeek page:attributes.targetPage]; + + break; + } + case FSCalendarTransitionWeekToMonth: { + + NSInteger focusedRow = 0; + NSDate *currentPage = self.calendar.currentPage; + + NSDate *focusedDate = ({ + NSArray *candidates = ({ + NSMutableArray *dates = self.calendar.selectedDates.reverseObjectEnumerator.allObjects.mutableCopy; + if (self.calendar.today) { + [dates addObject:self.calendar.today]; + } + if (self.calendar.currentPage) { + [dates addObject:[self.calendar.gregorian fs_lastDayOfWeek:currentPage]]; + } + dates.copy; + }); + NSArray *visibleCandidates = [candidates filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(NSDate * _Nullable evaluatedObject, NSDictionary * _Nullable bindings) { + NSIndexPath *indexPath = [self.calendar.calculator indexPathForDate:evaluatedObject scope:FSCalendarScopeWeek]; + NSInteger currentSection = [self.calendar.calculator indexPathForDate:self.calendar.currentPage scope:FSCalendarScopeWeek].section; + return indexPath.section == currentSection; + }]]; + NSDate *date = visibleCandidates.firstObject; + date; + }); + + NSDate *firstDayOfMonth = [self.calendar.gregorian fs_firstDayOfMonth:focusedDate]; + attributes.focusedDate = focusedDate; + firstDayOfMonth = firstDayOfMonth ?: [self.calendar.gregorian fs_firstDayOfMonth:currentPage]; + NSInteger numberOfPlaceholdersForPrev = [self.calendar.calculator numberOfHeadPlaceholdersForMonth:firstDayOfMonth]; + NSDate *firstDateOfPage = [self.calendar.gregorian dateByAddingUnit:NSCalendarUnitDay value:-numberOfPlaceholdersForPrev toDate:firstDayOfMonth options:0]; + + for (int i = 0; i < 6; i++) { + NSDate *currentRow = [self.calendar.gregorian dateByAddingUnit:NSCalendarUnitWeekOfYear value:i toDate:firstDateOfPage options:0]; + if ([self.calendar.gregorian isDate:currentRow inSameDayAsDate:currentPage]) { + focusedRow = i; + currentPage = firstDayOfMonth; + break; + } + } + attributes.focusedRowNumber = focusedRow; + attributes.targetPage = currentPage; + attributes.firstDayOfMonth = firstDayOfMonth; + + attributes.targetBounds = [self boundingRectForScope:FSCalendarScopeMonth page:attributes.targetPage]; + + break; + } + default: + break; + } + return attributes; +} + +#pragma mark - Private properties + +- (FSCalendarScope)representingScope +{ + switch (self.state) { + case FSCalendarTransitionStateIdle: { + return self.calendar.scope; + } + case FSCalendarTransitionStateChanging: + case FSCalendarTransitionStateFinishing: { + return FSCalendarScopeMonth; + } + } +} + +#pragma mark - Private methods + +- (CGRect)boundingRectForScope:(FSCalendarScope)scope page:(NSDate *)page +{ + CGSize contentSize; + switch (scope) { + case FSCalendarScopeMonth: { + if (self.calendar.placeholderType == FSCalendarPlaceholderTypeFillSixRows) { + contentSize = self.cachedMonthSize; + } else { + CGFloat padding = self.calendar.collectionViewLayout.sectionInsets.top + self.calendar.collectionViewLayout.sectionInsets.bottom; + contentSize = CGSizeMake(self.calendar.fs_width, + self.calendar.preferredHeaderHeight+ + self.calendar.preferredWeekdayHeight+ + ([self.calendar.calculator numberOfRowsInMonth:page]*self.calendar.collectionViewLayout.estimatedItemSize.height)+ + self.calendar.scopeHandle.fs_height+padding); + } + break; + } + case FSCalendarScopeWeek: { + contentSize = [self.calendar sizeThatFits:self.calendar.frame.size scope:scope]; + break; + } + } + return (CGRect){CGPointZero,contentSize}; +} + +- (void)boundingRectWillChange:(CGRect)targetBounds animated:(BOOL)animated +{ + self.calendar.scopeHandle.fs_bottom = CGRectGetMaxY(targetBounds); + self.calendar.contentView.fs_height = CGRectGetHeight(targetBounds)-self.calendar.scopeHandle.fs_height; + self.calendar.daysContainer.fs_height = CGRectGetHeight(targetBounds)-self.calendar.preferredHeaderHeight-self.calendar.preferredWeekdayHeight-self.calendar.scopeHandle.fs_height; + [[self.calendar valueForKey:@"delegateProxy"] calendar:self.calendar boundingRectWillChange:targetBounds animated:animated]; +} + +- (void)performForwardTransition:(FSCalendarTransition)transition fromProgress:(CGFloat)progress +{ + FSCalendarTransitionAttributes *attr = self.pendingAttributes; + switch (transition) { + case FSCalendarTransitionMonthToWeek: { + + [self.calendar willChangeValueForKey:@"scope"]; + [self.calendar fs_setUnsignedIntegerVariable:FSCalendarScopeWeek forKey:@"_scope"]; + [self.calendar didChangeValueForKey:@"scope"]; + + [self.calendar fs_setVariable:attr.targetPage forKey:@"_currentPage"]; + + self.calendar.contentView.clipsToBounds = YES; + + CGFloat currentAlpha = MAX(1-progress*1.1,0); + CGFloat duration = 0.3; + [self performAlphaAnimationFrom:currentAlpha to:0 duration:0.22 exception:attr.focusedRowNumber completion:^{ + [self performTransitionCompletionAnimated:YES]; + }]; + + if (self.calendar.delegate && ([self.calendar.delegate respondsToSelector:@selector(calendar:boundingRectWillChange:animated:)] || [self.calendar.delegate respondsToSelector:@selector(calendarCurrentScopeWillChange:animated:)])) { + [UIView beginAnimations:@"delegateTranslation" context:"translation"]; + [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; + [UIView setAnimationDuration:duration]; + self.collectionView.fs_top = -attr.focusedRowNumber*self.calendar.collectionViewLayout.estimatedItemSize.height; + [self boundingRectWillChange:attr.targetBounds animated:YES]; + [UIView commitAnimations]; + } + + break; + } + case FSCalendarTransitionWeekToMonth: { + + [self.calendar willChangeValueForKey:@"scope"]; + [self.calendar fs_setUnsignedIntegerVariable:FSCalendarScopeMonth forKey:@"_scope"]; + [self.calendar didChangeValueForKey:@"scope"]; + + [self performAlphaAnimationFrom:progress to:1 duration:0.4 exception:attr.focusedRowNumber completion:^{ + [self performTransitionCompletionAnimated:YES]; + }]; + + CGFloat duration = 0.3; + [CATransaction begin]; + [CATransaction setDisableActions:NO]; + + if (self.calendar.delegate && ([self.calendar.delegate respondsToSelector:@selector(calendar:boundingRectWillChange:animated:)] || [self.calendar.delegate respondsToSelector:@selector(calendarCurrentScopeWillChange:animated:)])) { + [UIView beginAnimations:@"delegateTranslation" context:"translation"]; + [UIView setAnimationsEnabled:YES]; + [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; + [UIView setAnimationDuration:duration]; + self.collectionView.fs_top = 0; + [self boundingRectWillChange:attr.targetBounds animated:YES]; + [UIView commitAnimations]; + } + [CATransaction commit]; + break; + } + default: + break; + } +} + +- (void)performBackwardTransition:(FSCalendarTransition)transition fromProgress:(CGFloat)progress +{ + switch (transition) { + case FSCalendarTransitionMonthToWeek: { + + [self.calendar willChangeValueForKey:@"scope"]; + [self.calendar fs_setUnsignedIntegerVariable:FSCalendarScopeMonth forKey:@"_scope"]; + [self.calendar didChangeValueForKey:@"scope"]; + + [self performAlphaAnimationFrom:MAX(1-progress*1.1,0) to:1 duration:0.3 exception:self.pendingAttributes.focusedRowNumber completion:^{ + [self.calendar.visibleCells enumerateObjectsUsingBlock:^(__kindof UICollectionViewCell * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { + obj.contentView.layer.opacity = 1; + [obj.contentView.layer removeAnimationForKey:@"opacity"]; + }]; + self.pendingAttributes = nil; + self.state = FSCalendarTransitionStateIdle; + }]; + + if (self.calendar.delegate && ([self.calendar.delegate respondsToSelector:@selector(calendar:boundingRectWillChange:animated:)] || [self.calendar.delegate respondsToSelector:@selector(calendarCurrentScopeWillChange:animated:)])) { + [UIView beginAnimations:@"delegateTranslation" context:"translation"]; + [UIView setAnimationsEnabled:YES]; + [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; + [UIView setAnimationDuration:0.3]; + self.collectionView.fs_top = 0; + [self boundingRectWillChange:self.pendingAttributes.sourceBounds animated:YES]; + [UIView commitAnimations]; + } + break; + } + case FSCalendarTransitionWeekToMonth: { + + [self.calendar willChangeValueForKey:@"scope"]; + [self.calendar fs_setUnsignedIntegerVariable:FSCalendarScopeWeek forKey:@"_scope"]; + [self.calendar didChangeValueForKey:@"scope"]; + + [self performAlphaAnimationFrom:progress to:0 duration:0.3 exception:self.pendingAttributes.focusedRowNumber completion:^{ + [self.calendar fs_setVariable:self.pendingAttributes.sourcePage forKey:@"_currentPage"]; + [self performTransitionCompletion:FSCalendarTransitionMonthToWeek animated:YES]; + }]; + + if (self.calendar.delegate && ([self.calendar.delegate respondsToSelector:@selector(calendar:boundingRectWillChange:animated:)] || [self.calendar.delegate respondsToSelector:@selector(calendarCurrentScopeWillChange:animated:)])) { + [UIView beginAnimations:@"delegateTranslation" context:"translation"]; + [UIView setAnimationsEnabled:YES]; + [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut]; + [UIView setAnimationDuration:0.3]; + self.collectionView.fs_top = (-self.pendingAttributes.focusedRowNumber*self.calendar.collectionViewLayout.estimatedItemSize.height); + [self boundingRectWillChange:self.pendingAttributes.sourceBounds animated:YES]; + [UIView commitAnimations]; + } + break; + } + default: + break; + } +} + +- (void)performAlphaAnimationFrom:(CGFloat)fromAlpha to:(CGFloat)toAlpha duration:(CGFloat)duration exception:(NSInteger)exception completion:(void(^)(void))completion; +{ + [self.calendar.visibleCells enumerateObjectsUsingBlock:^(FSCalendarCell *cell, NSUInteger idx, BOOL *stop) { + if (CGRectContainsPoint(self.collectionView.bounds, cell.center)) { + BOOL shouldPerformAlpha = NO; + NSIndexPath *indexPath = [self.collectionView indexPathForCell:cell]; + NSInteger row = [self.calendar.calculator coordinateForIndexPath:indexPath].row; + shouldPerformAlpha = row != exception; + if (shouldPerformAlpha) { + CABasicAnimation *opacity = [CABasicAnimation animationWithKeyPath:@"opacity"]; + opacity.duration = duration; + opacity.fromValue = @(fromAlpha); + opacity.toValue = @(toAlpha); + opacity.removedOnCompletion = NO; + opacity.fillMode = kCAFillModeForwards; + [cell.contentView.layer addAnimation:opacity forKey:@"opacity"]; + } + } + }]; + if (completion) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(duration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + completion(); + }); + } +} + +- (void)performAlphaAnimationWithProgress:(CGFloat)progress +{ + CGFloat opacity = self.transition == FSCalendarTransitionMonthToWeek ? MAX((1-progress*1.1),0) : progress; + [self.calendar.visibleCells enumerateObjectsUsingBlock:^(FSCalendarCell *cell, NSUInteger idx, BOOL *stop) { + if (CGRectContainsPoint(self.collectionView.bounds, cell.center)) { + BOOL shouldPerformAlpha = NO; + NSIndexPath *indexPath = [self.collectionView indexPathForCell:cell]; + NSInteger row = [self.calendar.calculator coordinateForIndexPath:indexPath].row; + shouldPerformAlpha = row != self.pendingAttributes.focusedRowNumber; + if (shouldPerformAlpha) { + cell.contentView.layer.opacity = opacity; + } + } + }]; +} + +- (void)performPathAnimationWithProgress:(CGFloat)progress +{ + CGFloat targetHeight = CGRectGetHeight(self.pendingAttributes.targetBounds); + CGFloat sourceHeight = CGRectGetHeight(self.pendingAttributes.sourceBounds); + CGFloat currentHeight = sourceHeight - (sourceHeight-targetHeight)*progress - self.calendar.scopeHandle.fs_height; + CGRect currentBounds = CGRectMake(0, 0, CGRectGetWidth(self.pendingAttributes.targetBounds), currentHeight+self.calendar.scopeHandle.fs_height); + self.collectionView.fs_top = (-self.pendingAttributes.focusedRowNumber*self.calendar.collectionViewLayout.estimatedItemSize.height)*(self.transition == FSCalendarTransitionMonthToWeek?progress:(1-progress)); + [self boundingRectWillChange:currentBounds animated:NO]; + if (self.transition == FSCalendarTransitionWeekToMonth) { + self.calendar.contentView.fs_height = targetHeight; + } +} + + +- (void)prelayoutForWeekToMonthTransition +{ + self.calendar.contentView.clipsToBounds = YES; + self.calendar.contentView.fs_height = CGRectGetHeight(self.pendingAttributes.targetBounds)-self.calendar.scopeHandle.fs_height; + self.collectionViewLayout.scrollDirection = (UICollectionViewScrollDirection)self.calendar.scrollDirection; + self.calendar.calendarHeaderView.scrollDirection = self.collectionViewLayout.scrollDirection; + self.calendar.needsAdjustingViewFrame = YES; + [self.calendar setNeedsLayout]; + [self.collectionView reloadData]; + [self.calendar.calendarHeaderView reloadData]; + [self.calendar layoutIfNeeded]; +} + +@end + +@implementation FSCalendarTransitionAttributes + + +@end + diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarWeekdayView.h b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarWeekdayView.h new file mode 100644 index 0000000..282c90e --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarWeekdayView.h @@ -0,0 +1,27 @@ +// +// FSCalendarWeekdayView.h +// FSCalendar +// +// Created by dingwenchao on 03/11/2016. +// Copyright © 2016 dingwenchao. All rights reserved. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@class FSCalendar; + +@interface FSCalendarWeekdayView : UIView + +/** + An array of UILabel objects displaying the weekday symbols. + */ +@property (readonly, nonatomic) NSArray *weekdayLabels; + +- (void)configureAppearance; + +@end + +NS_ASSUME_NONNULL_END diff --git a/Pods/FSCalendar+Persian/FSCalendar/FSCalendarWeekdayView.m b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarWeekdayView.m new file mode 100644 index 0000000..404b70a --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/FSCalendarWeekdayView.m @@ -0,0 +1,119 @@ +// +// FSCalendarWeekdayView.m +// FSCalendar +// +// Created by dingwenchao on 03/11/2016. +// Copyright © 2016 Wenchao Ding. All rights reserved. +// + +#import "FSCalendar.h" +#import "NSLocale+Category.h" +#import "NSString+Category.h" +#import "FSCalendarExtensions.h" +#import "FSCalendarWeekdayView.h" +#import "FSCalendarDynamicHeader.h" + +@interface FSCalendarWeekdayView() + +@property (strong, nonatomic) NSPointerArray *weekdayPointers; +@property (weak , nonatomic) UIView *contentView; +@property (weak , nonatomic) FSCalendar *calendar; + +- (void)commonInit; + +@end + +@implementation FSCalendarWeekdayView + +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + [self commonInit]; + } + return self; +} + +- (instancetype)initWithCoder:(NSCoder *)coder +{ + self = [super initWithCoder:coder]; + if (self) { + [self commonInit]; + } + return self; +} + +- (void)commonInit +{ + UIView *contentView = [[UIView alloc] initWithFrame:CGRectZero]; + [self addSubview:contentView]; + _contentView = contentView; + + _weekdayPointers = [NSPointerArray weakObjectsPointerArray]; + for (int i = 0; i < 7; i++) { + UILabel *weekdayLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + weekdayLabel.textAlignment = NSTextAlignmentCenter; + [self.contentView addSubview:weekdayLabel]; + [_weekdayPointers addPointer:(__bridge void * _Nullable)(weekdayLabel)]; + } +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + self.contentView.frame = self.bounds; + + // Position Calculation + NSInteger count = self.weekdayPointers.count; + size_t size = sizeof(CGFloat)*count; + CGFloat *widths = malloc(size); + CGFloat contentWidth = self.contentView.fs_width; + FSCalendarSliceCake(contentWidth, count, widths); + + CGFloat x = 0; + for (NSInteger i = 0; i < count; i++) { + CGFloat width = widths[i]; + UILabel *label = [self.weekdayPointers pointerAtIndex:i]; + label.frame = CGRectMake(x, 0, width, self.contentView.fs_height); + x += width; + } + free(widths); +} + +- (void)setCalendar:(FSCalendar *)calendar +{ + _calendar = calendar; + [self configureAppearance]; +} + +- (NSArray *)weekdayLabels +{ + return self.weekdayPointers.allObjects; +} + +- (void)configureAppearance +{ + BOOL useVeryShortWeekdaySymbols = (self.calendar.appearance.caseOptions & (15<<4) ) == FSCalendarCaseOptionsWeekdayUsesSingleUpperCase; + NSArray *weekdaySymbols = useVeryShortWeekdaySymbols ? self.calendar.gregorian.veryShortStandaloneWeekdaySymbols : self.calendar.gregorian.shortStandaloneWeekdaySymbols; + BOOL useDefaultWeekdayCase = (self.calendar.appearance.caseOptions & (15<<4) ) == FSCalendarCaseOptionsWeekdayUsesDefaultCase; + + NSInteger firstWeek = self.calendar.firstWeekday; + BOOL isRtl = [_calendar.calendarIdentifier isRTLCalendar] && [_calendar.locale isRtlLocale]; + if (isRtl && [_calendar.locale isEqual:@"fa-IR"]) { + firstWeek = 7; + } + for (NSInteger i = 0; i < self.weekdayPointers.count; i++) { + NSInteger index = (i + firstWeek-1) % 7; + UILabel *label = [self.weekdayPointers pointerAtIndex:i]; + label.font = self.calendar.appearance.weekdayFont; + label.textColor = self.calendar.appearance.weekdayTextColor; + label.text = useDefaultWeekdayCase ? weekdaySymbols[index] : [weekdaySymbols[index] uppercaseString]; + + if (isRtl) { + [label setTransform:CGAffineTransformMakeScale(-1,1)]; + } + } +} + +@end diff --git a/Pods/FSCalendar+Persian/FSCalendar/NSLocale+Category.h b/Pods/FSCalendar+Persian/FSCalendar/NSLocale+Category.h new file mode 100644 index 0000000..894e7a4 --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/NSLocale+Category.h @@ -0,0 +1,15 @@ +// +// NSLocale+Category.h +// FSCalendar +// +// Created by Hussein Habibi Juybari on 10/10/18. +// Copyright © 2018 wenchaoios. All rights reserved. +// + +#import + +@interface NSLocale (Category) + +-(BOOL) isRtlLocale; + +@end diff --git a/Pods/FSCalendar+Persian/FSCalendar/NSLocale+Category.m b/Pods/FSCalendar+Persian/FSCalendar/NSLocale+Category.m new file mode 100644 index 0000000..e282a4f --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/NSLocale+Category.m @@ -0,0 +1,22 @@ +// +// NSLocale+Category.m +// FSCalendar +// +// Created by Hussein Habibi Juybari on 10/10/18. +// Copyright © 2018 wenchaoios. All rights reserved. +// + +#import "NSLocale+Category.h" + +@implementation NSLocale(Category) + +-(BOOL) isRtlLocale { + NSString *lanId = self.localeIdentifier; + NSArray *langSep = [lanId componentsSeparatedByString:@"-"]; + + NSLocaleLanguageDirection langDirction = [NSLocale characterDirectionForLanguage:langSep.firstObject]; + + return langDirction; +} + +@end diff --git a/Pods/FSCalendar+Persian/FSCalendar/NSString+Category.h b/Pods/FSCalendar+Persian/FSCalendar/NSString+Category.h new file mode 100644 index 0000000..645f70e --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/NSString+Category.h @@ -0,0 +1,15 @@ +// +// NSString+Category.h +// FSCalendar +// +// Created by Hussein Habibi on 4/12/18. +// Copyright © 2018 wenchaoios. All rights reserved. +// + +#import + +@interface NSString (Category) + +-(BOOL) isRTLCalendar; + +@end diff --git a/Pods/FSCalendar+Persian/FSCalendar/NSString+Category.m b/Pods/FSCalendar+Persian/FSCalendar/NSString+Category.m new file mode 100644 index 0000000..2c062bf --- /dev/null +++ b/Pods/FSCalendar+Persian/FSCalendar/NSString+Category.m @@ -0,0 +1,19 @@ +// +// NSString+Category.m +// FSCalendar +// +// Created by Hussein Habibi on 4/12/18. +// Copyright © 2018 wenchaoios. All rights reserved. +// + +#import "NSString+Category.h" + +@implementation NSString (Category) + +-(BOOL) isRTLCalendar{ + NSArray *rtlId = @[NSCalendarIdentifierIslamicCivil,NSCalendarIdentifierPersian, + NSCalendarIdentifierIslamicUmmAlQura,NSCalendarIdentifierIslamic]; + return [rtlId containsObject:self]; +} + +@end diff --git a/Pods/FSCalendar+Persian/LICENSE b/Pods/FSCalendar+Persian/LICENSE new file mode 100644 index 0000000..fb2a795 --- /dev/null +++ b/Pods/FSCalendar+Persian/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2013-2016 FSCalendar (https://github.com/WenchaoD/FSCalendar) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/Pods/FSCalendar+Persian/README.md b/Pods/FSCalendar+Persian/README.md new file mode 100644 index 0000000..708bdb5 --- /dev/null +++ b/Pods/FSCalendar+Persian/README.md @@ -0,0 +1,353 @@ + + +![logo](https://raw.githubusercontent.com/Husseinhj/FSCalendar/master/ScreenShots/FSCalendar-Persian.png) +
+[![Build Status](https://travis-ci.org/Husseinhj/FSCalendar.svg?branch=master)](https://travis-ci.org/Husseinhj/FSCalendar) +[![Version](https://img.shields.io/cocoapods/v/FSCalendar+Persian.svg?style=flat)](http://cocoadocs.org/docsets/FSCalendar+Persian) + +[![Platform](https://img.shields.io/badge/platform-iOS%207%2B-blue.svg?style=flat)](http://cocoadocs.org/docsets/FSCalendar+Persian) +[![Carthage compatible](https://img.shields.io/cocoapods/p/FSCalendar+Persian.svg)](https://github.com/Carthage/Carthage) +
+[![Languages](https://img.shields.io/badge/language-objc%20|%20swift-FF69B4.svg?style=plastic)](#) + +# Table of contents +* [Screenshots](#screenshots) +* [Installation](#installation) +* [Pre-knowledge](#pre-knowledge) +* [Support](#support) +* [Contact](#contact) + +## Screenshots + +### Persian Calendar and Arabic Calendar + +| ![Week](https://github.com/Husseinhj/FSCalendar/raw/master/ScreenShots/Simulator%20Screen%20Shot%20-%20iPhone%208%20Plus%20-%202018-03-01%20at%2014.32.47.png) | ![Month](https://github.com/Husseinhj/FSCalendar/raw/master/ScreenShots/Simulator%20Screen%20Shot%20-%20iPhone%208%20Plus%20-%202018-03-01%20at%2014.33.06.png) | ![DIY](https://github.com/Husseinhj/FSCalendar/raw/master/ScreenShots/Simulator%20Screen%20Shot%20-%20iPhone%208%20Plus%20-%202018-03-01%20at%2016.46.44.png) | +| ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | +| ![Range](https://github.com/Husseinhj/FSCalendar/raw/master/ScreenShots/Simulator%20Screen%20Shot%20-%20iPhone%208%20Plus%20-%202018-03-01%20at%2015.04.12.png) | ![Week range](https://github.com/Husseinhj/FSCalendar/raw/master/ScreenShots/Simulator%20Screen%20Shot%20-%20iPhone%208%20Plus%20-%202018-03-01%20at%2015.27.00.png) | ![Range selection](https://github.com/Husseinhj/FSCalendar/raw/master/ScreenShots/Simulator%20Screen%20Shot%20-%20iPhone%208%20Plus%20-%202018-03-01%20at%2015.26.50.png) | + + +### iPhone +![fscalendar](https://cloud.githubusercontent.com/assets/5186464/10262249/4fabae40-69f2-11e5-97ab-afbacd0a3da2.jpg) + +### iPad +![fscalendar-ipad](https://cloud.githubusercontent.com/assets/5186464/10927681/d2448cb6-82dc-11e5-9d11-f664a06698a7.jpg) + +### Safe Orientation + +![fscalendar-scope-orientation-autolayout](https://cloud.githubusercontent.com/assets/5186464/20325758/ea125e1e-abc0-11e6-9e29-491acbcb0d07.gif) + +### Today Extension +| iOS8/9 | iOS10 | +| ---------------------------------------- | ---------------------------------------- | +| ![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) | + +### Interactive Scope Gesture +| ![1](https://cloud.githubusercontent.com/assets/5186464/21559640/e92a9ccc-ce8a-11e6-8c60-e52204f33249.gif) | +| ---- | + +### DIY support +| ![1](https://cloud.githubusercontent.com/assets/5186464/20026983/22354a0e-a342-11e6-8ae6-0614ea7f35ae.gif) | +| ------------- | +> To customize your own cell, view DIY Example in `Example-Swift` or `Example-Objc` + + +### Swipe-To-Choose + +| Single-Selection
Swipe-To-Choose | Multiple-Selection
Swipe-To-Choose | DIY
Swipe-To-Choose | +| ---------------------------------------- | ---------------------------------------- | ---------------------------------------- | +| ![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) | + +## Achievement of Users + +| ![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) +| +| ------------- | ------------- | ------------- | ------------- | + +#### [***More Achievements***](https://github.com/WenchaoD/FSCalendar/wiki/) are available in [***FSCalendar Gallery***](https://github.com/WenchaoD/FSCalendar/wiki/) + +# Installation + +## CocoaPods of RTL support Version: + +* For iOS8+: 👍 + +```ruby +use_frameworks! +target '' do + pod 'FSCalendar+Persian' +end +``` + +* For iOS7+: + +```ruby +target '' do + pod 'FSCalendar+Persian' +end +``` + +> [NSCalendarExtension](https://github.com/WenchaoD/NSCalendarExtension) is required to get iOS7 compatibility. + +## Carthage: +* For iOS8+ + +```ruby +github "hussein_hj/FSCalendar" +``` + +## Manually: +* Drag all files under `FSCalendar` folder into your project. 👍 + +> Alternatively to give it a test run, simply press `command+u` in `Example-Objc` or `Example-Swift` and launch the ***UITest Target***.
+> Only the methods marked "👍" support IBInspectable / IBDesignable feature. [Have fun with Interface builder](#roll_with_interface_builder) + + +# Setup + +## Use Interface Builder + +1、 Drag an UIView object to ViewController Scene +2、 Change the `Custom Class` to `FSCalendar`
+3、 Link `dataSource` and `delegate` to the ViewController
+ +![fscalendar-ib](https://cloud.githubusercontent.com/assets/5186464/9488580/a360297e-4c0d-11e5-8548-ee9274e7c4af.jpg) + +4、 Finally, implement `FSCalendarDataSource` and `FSCalendarDelegate` in your `ViewController` + +## Or use code + +```objc +@property (weak , nonatomic) FSCalendar *calendar; +``` +```objc +// In loadView(Recommended) or viewDidLoad +FSCalendar *calendar = [[FSCalendar alloc] initWithFrame:CGRectMake(0, 0, 320, 300)]; +calendar.dataSource = self; +calendar.delegate = self; +[self.view addSubview:calendar]; +self.calendar = calendar; +``` +
+ +## Or swift + +* To use `FSCalendar` in swift, you need to [Create Bridge Header](https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html) first. + + +```swift +fileprivate weak var calendar: FSCalendar! +``` +```swift +// In loadView or viewDidLoad +let calendar = FSCalendar(frame: CGRect(x: 0, y: 0, width: 320, height: 300)) +calendar.dataSource = self +calendar.delegate = self +view.addSubview(calendar) +self.calendar = calendar +``` + +> To use **FSCalendar** in Swift3, see `Example-Swift` for details. + +## How to use RTL calendar? + +It's easy (Objective-C) : +```objc +calendar.locale = [NSLocale localeWithLocaleIdentifier:@"fa-IR"]; +calendar.identifier = NSCalendarIdentifierPersian; +calendar.firstWeekday = 7; + +.... + +#pragma mark - FSCalendarDataSource + +- (NSDate *)minimumDateForCalendar:(FSCalendar *)calendar { + return [self.dateFormatter dateFromString:@"2016-07-08"]; +} +``` + +Swift : + +```swift + +calendar.locale = NSLocale.init(localeIdentifier: "fa-IR") as Locale +calendar.identifier = NSCalendar.Identifier.persian.rawValue +calendar.firstWeekday = 7 + +.... + +// MARK:- FSCalendarDataSource + +func minimumDate(for calendar: FSCalendar) -> Date { + return self.formatter.date(from: "2016-07-08")! +} + +``` +Also can see [here](https://github.com/Husseinhj/FSCalendar/commit/0ed037e852f4dc9b0d7569c00e21e75839aae7ef#diff-72ae6ec586cbfec0236fb013c01c9f20) where is these codes + +## Warning +`FSCalendar` ***doesn't*** update frame by itself, Please implement + +* For ***AutoLayout*** + +```objc +- (void)calendar:(FSCalendar *)calendar boundingRectWillChange:(CGRect)bounds animated:(BOOL)animated +{ + self.calendarHeightConstraint.constant = CGRectGetHeight(bounds); + // Do other updates here + [self.view layoutIfNeeded]; +} +``` + +* For ***Manual Layout*** + +```objc +- (void)calendar:(FSCalendar *)calendar boundingRectWillChange:(CGRect)bounds animated:(BOOL)animated +{ + calendar.frame = (CGRect){calendar.frame.origin,bounds.size}; + // Do other updates here +} +``` + +* If you are using ***Masonry*** + +```objc +- (void)calendar:(FSCalendar *)calendar boundingRectWillChange:(CGRect)bounds animated:(BOOL)animated +{ + [calendar mas_updateConstraints:^(MASConstraintMaker *make) { + make.height.equalTo(@(bounds.size.height)); + // Do other updates + }]; + [self.view layoutIfNeeded]; +} +``` + +* If you are using ***SnapKit*** + +```swift +func calendar(_ calendar: FSCalendar, boundingRectWillChange bounds: CGRect, animated: Bool) { + calendar.snp.updateConstraints { (make) in + make.height.equalTo(bounds.height) + // Do other updates + } + self.view.layoutIfNeeded() +} +``` + +### Roll with Interface Builder +![fscalendar - ibdesignable](https://cloud.githubusercontent.com/assets/5186464/9301716/2e76a2ca-4503-11e5-8450-1fa7aa93e9fd.gif) + +# Pre-knowledge + +> In `Swift3`, `NSDate` and `NSDateFormatter` have been renamed to ***Date*** and ***DateFormatter*** , see `Example-Swift` for details. + +## How to create NSDate object + +* By **NSCalendar**. + +```objc +self.gregorian = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian]; +``` + +Then: + +```objc +NSDate *date = [gregorian dateWithEra:1 year:2016 month:9 day:10 hour:0 minute:0 second:0 nanosecond:0]; +// 2016-09-10 00:00:00 +``` + + +* Or by **NSDateFormatter** + +```objc +self.formatter = [[NSDateFormatter alloc] init]; +self.formatter.dateFormat = @"yyyy-MM-dd"; +``` + +Then: + +```objc +NSDate *date = [self.formatter dateFromString:@"2016-09-10"]; +``` + +## How to print out NSDate object + +* Use **NSDateFormatter** + +```objc +self.formatter = [[NSDateFormatter alloc] init]; +self.formatter.dateFormat = @"yyyy/MM/dd"; +``` + +```objc +NSString *string = [self.formatter stringFromDate:date]; +NSLog(@"Date is %@", string); +``` + +## How to manipulate NSDate with NSCalendar + +```objc +self.gregorian = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian]; +``` +* Get component of NSDate + +```objc +NSInteger era = [self.gregorian component:NSCalendarUnitEra fromDate:date]; +NSInteger year = [self.gregorian component:NSCalendarUnitYear fromDate:date]; +NSInteger month = [self.gregorian component:NSCalendarUnitMonth fromDate:date]; +NSInteger day = [self.gregorian component:NSCalendarUnitDay fromDate:date]; +NSInteger hour = [self.gregorian component:NSCalendarUnitHour fromDate:date]; +NSInteger minute = [self.gregorian component:NSCalendarUnitMinute fromDate:date]; +... + +``` + +* Get next **month** + +```objc +NSDate *nextMonth = [self.gregorain dateByAddingUnit:NSCalendarUnitMonth value:1 toDate:date options:0]; +``` + +* Get next **day** + +```objc +NSDate *nextDay = [self.gregorain dateByAddingUnit:NSCalendarUnitDay value:1 toDate:date options:0]; +``` + +* Is date in today/tomorrow/yesterday/weekend + +```objc +BOOL isToday = [self.gregorian isDateInToday:date]; +BOOL isYesterday = [self.gregorian isDateInYesterday:date]; +BOOL isTomorrow = [self.gregorian isDateInTomorrow:date]; +BOOL isWeekend = [self.gregorian isDateInWeekend:date]; +``` + +* Compare two dates + +```objc + +BOOL sameDay = [self.gregorian isDate:date1 inSameDayAsDate:date2]; +// Yes if the date1 and date2 are in same day + + +[self.gregorian compareDate:date1 toDate:date2 toUnitGranularity:unit]; +// compare the era/year/month/day/hour/minute .etc ... +// return NSOrderAscending/NSOrderSame/NSOrderDecending + +BOOL inSameUnit = [self.gregorian isDate:date1 equalToDate:date2 toUnitGranularity:unit]; +// if the given unit (era/year/month/day/hour/minute .etc) are the same + + +``` + +## Contact +* Telegram: [**@Hussein_hj**](https://t.me/Hussein_hj) +* Twitter:[**@Hussein_Juybari**](https://twitter.com/hussein_juybari) + +> If your made a beautiful calendar with this library in your app, please take a screen shot and [@me](https://twitter.com/hussein_juybari) in twitter. Your help really means a lot to me!
+ + +# License +FSCalendar is available under the MIT license. See the LICENSE file for more info. + +### [Documentation](https://husseinhj.github.io/FSCalendar/) | [More Usage](https://github.com/Husseinhj/FSCalendar/blob/master/MOREUSAGE.md) | diff --git a/Pods/Manifest.lock b/Pods/Manifest.lock new file mode 100644 index 0000000..e38b46d --- /dev/null +++ b/Pods/Manifest.lock @@ -0,0 +1,20 @@ +PODS: + - "FSCalendar+Persian (2.9.2)" + - SPStorkController (1.6.5) + +DEPENDENCIES: + - "FSCalendar+Persian" + - SPStorkController + +SPEC REPOS: + https://github.com/cocoapods/specs.git: + - "FSCalendar+Persian" + - SPStorkController + +SPEC CHECKSUMS: + "FSCalendar+Persian": fc5b323015db8a93c48c61b9c0c59f3a705d8297 + SPStorkController: f74a60dbcd3c35180c996688873f6eadac839642 + +PODFILE CHECKSUM: 388c0f1a2c275c2cee70116388b673441083cdae + +COCOAPODS: 1.5.2 diff --git a/Pods/Pods.xcodeproj/project.pbxproj b/Pods/Pods.xcodeproj/project.pbxproj new file mode 100644 index 0000000..b49bfa0 --- /dev/null +++ b/Pods/Pods.xcodeproj/project.pbxproj @@ -0,0 +1,1267 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 07F2CF533929DCE53CEF22EA7CFE9E69 /* FSCalendarCollectionViewLayout.m in Sources */ = {isa = PBXBuildFile; fileRef = CC8A0C406BAD2B954B57EC44F249F90E /* FSCalendarCollectionViewLayout.m */; }; + 08762A15D4394DE9D666C9B7F31610B4 /* FSCalendarDelegationFactory.h in Headers */ = {isa = PBXBuildFile; fileRef = E28B5F91AA22D1C55F50E44DD9F39839 /* FSCalendarDelegationFactory.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 12A7B0D185627042EA7D47DCE6DF5748 /* FSCalendarExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = E86D99D80A868F5216CC32EC49A382AD /* FSCalendarExtensions.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 14F2ABBBA9B67D3782E60B9F2BD480E1 /* FSCalendarCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = 2037C4140D6D86CD7DB133348BA50EAE /* FSCalendarCollectionView.m */; }; + 14F94575C2D09D1D23CE3462B1361DA4 /* Pods-pro-serviceUITests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 871A9291044B93D5FE280B9AA20B9C53 /* Pods-pro-serviceUITests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 17D80AB2A0433F80228DE376D1DBD7F2 /* FSCalendarWeekdayView.h in Headers */ = {isa = PBXBuildFile; fileRef = 59480774938E948862280EE4612BB053 /* FSCalendarWeekdayView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1BD8FDF83BE5BAAF52602BAB16D60E21 /* SPStorkPresentingAnimationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CEC6C25B07499F84F5384DAB0247E62D /* SPStorkPresentingAnimationController.swift */; }; + 1EBB6FCFDD1B58E052C074DCD7D4F83E /* NSLocale+Category.h in Headers */ = {isa = PBXBuildFile; fileRef = 597B3F89CE35A5805E9DE839823909FF /* NSLocale+Category.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 1FE70CAA486C68CD811D7AAD6907B04B /* NSString+Category.m in Sources */ = {isa = PBXBuildFile; fileRef = 6D8D3EEF61876B838F8411712C8FDA93 /* NSString+Category.m */; }; + 2A0C7E4AE9D378340B5ED61B3C13E1B0 /* SPStorkHaptic.swift in Sources */ = {isa = PBXBuildFile; fileRef = FFF53E9305A12D477CBAAE67F0E6BEAA /* SPStorkHaptic.swift */; }; + 2A50DA02BA56EB4850D596BA6EF9FEFC /* SPStorkCloseView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A8211DE2AB8E3B4A9F1E2EE96314F13 /* SPStorkCloseView.swift */; }; + 2FDB02BA3EA5B8391CD378BE1E9E5BC8 /* FSCalendar+Persian-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = DB4A6DCF6B5BBD469993091715B82ADA /* FSCalendar+Persian-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 36337CC61EB63AEAC9072F75B4475987 /* FSCalendarTransitionCoordinator.h in Headers */ = {isa = PBXBuildFile; fileRef = F1617E9F0AC3AEB12968A43925948905 /* FSCalendarTransitionCoordinator.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 36DB6762A2C21928A61E08DFF8D011E6 /* FSCalendar.h in Headers */ = {isa = PBXBuildFile; fileRef = E67CD264A492AEB55E5F4B306D9470DA /* FSCalendar.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 44CF38707E6B14382274BFF66FF0F506 /* SPStorkControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F8A4A69B47CC51D78D3DD5B857F29232 /* SPStorkControllerDelegate.swift */; }; + 4BF84BE2AB036F243AB646ED1BD849CF /* SPStorkController-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = B3226F6B0BF0B3319A04300A5621E06C /* SPStorkController-dummy.m */; }; + 567AEDF1581D72398E7F74F3E79B4B7E /* FSCalendarCalculator.h in Headers */ = {isa = PBXBuildFile; fileRef = A0056DAA88954B7060840CCDE1DBA4D9 /* FSCalendarCalculator.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 59A09F371AFD17F4A44A2F34564FF5BE /* FSCalendar+Deprecated.m in Sources */ = {isa = PBXBuildFile; fileRef = B7B082A0009DC7F3B2A04F669F3BD0D3 /* FSCalendar+Deprecated.m */; }; + 5C41DA6C326F37C89EC35069304BCF15 /* FSCalendarConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 32DCFDEF08EB09029F0C8F9C5930C6DC /* FSCalendarConstants.m */; }; + 5D7118DF99596ED2375328DDC7BC9C8B /* FSCalendarHeaderView.h in Headers */ = {isa = PBXBuildFile; fileRef = 8FD76AE62D8FB1D1A4503EB44377596B /* FSCalendarHeaderView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5FD9F570D8E0DE51BC261CF59F33FA7E /* FSCalendarDelegationProxy.h in Headers */ = {isa = PBXBuildFile; fileRef = D2ECC741B7B20CD045084E6C67BC1A0C /* FSCalendarDelegationProxy.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6102948D28F514C701DB22B36CB8BA34 /* FSCalendarScopeHandle.m in Sources */ = {isa = PBXBuildFile; fileRef = 0E4D28FC2AA46AF4F1953997BE1C6CB2 /* FSCalendarScopeHandle.m */; }; + 634B9BA6D00BC152D5B0D7FB2597B200 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E826AE0196CB3540E72242664FBD3F32 /* UIKit.framework */; }; + 6474279BD680FB0E25D50DDCC5C3F587 /* FSCalendarStickyHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = 6CDD7B6A7AEBD878F8230FE5529F68AD /* FSCalendarStickyHeader.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 6E05226078B373CA01D601C5A894C011 /* FSCalendarDelegationFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = 941C4A1AB02BB6B0229C80983173274F /* FSCalendarDelegationFactory.m */; }; + 7556EBF7B0E61C7E2ADA7F41E075BA9E /* FSCalendarAppearance.m in Sources */ = {isa = PBXBuildFile; fileRef = 6B30D00C742771B518F025FC33F6C53C /* FSCalendarAppearance.m */; }; + 75E9E8FEAEE50E90FC186B962D5F69E6 /* SPStorkController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7E5C32347E0BC58203E2945F571FD6D5 /* SPStorkController.swift */; }; + 785E68490C090D4B32704EE17CF71A37 /* FSCalendarTransitionCoordinator.m in Sources */ = {isa = PBXBuildFile; fileRef = 27E5D5ACE2E28E1044705EC33BE7F098 /* FSCalendarTransitionCoordinator.m */; }; + 7C6FC4F353CA8EF16E43566EC11818B8 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D6E839864EE09C8CE0528DE01FD9241A /* QuartzCore.framework */; }; + 7D4095AD807E801D9794E74CE768B7AB /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 90C7A160ABE5DAC85DC33E762CF55AE1 /* Foundation.framework */; }; + 7DDA8AC5C25E68301425C9F63C927C65 /* Pods-pro-serviceTests-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 65CD2108F2A45D6F53B33351BC320418 /* Pods-pro-serviceTests-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 8809E5B103DBACC37E45D868CA146D98 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 90C7A160ABE5DAC85DC33E762CF55AE1 /* Foundation.framework */; }; + 91079CF4D2426E39EC6C6C9D08C79F04 /* NSLocale+Category.m in Sources */ = {isa = PBXBuildFile; fileRef = 09962FC39A115A050970F744DD3898E5 /* NSLocale+Category.m */; }; + 928B20E85CE7D67FAF43C3E93FE86554 /* FSCalendarCell.m in Sources */ = {isa = PBXBuildFile; fileRef = DD924D15389F147EC8418FB6309D279D /* FSCalendarCell.m */; }; + 938ED81307AEC8A61BD8B6C9548A1F77 /* FSCalendarCalculator.m in Sources */ = {isa = PBXBuildFile; fileRef = E04F9FF8E298F887D06CC5C312313147 /* FSCalendarCalculator.m */; }; + 96BEB3DC4BD8EF3C7F547C3E8A16CCE5 /* Pods-pro-service-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = C4EA5F0CEFFD68E552A4BEE0CD7D83B4 /* Pods-pro-service-dummy.m */; }; + 9AE53F0BC6EDE5B517DBBBE22DC7F730 /* FSCalendarCollectionView.h in Headers */ = {isa = PBXBuildFile; fileRef = 67F8C03CC900D8B441764A073366596F /* FSCalendarCollectionView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9C566B5D740908B59F2D865DD02E6A33 /* NSString+Category.h in Headers */ = {isa = PBXBuildFile; fileRef = 64F24D32FC12B209C0D81E97E7032D3D /* NSString+Category.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9DB286DB734EE2753109CCC0CFDBF97B /* Pods-pro-serviceTests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 70722A47C6484E52B0E59B8E6C8A1018 /* Pods-pro-serviceTests-dummy.m */; }; + 9FB061E4A92C3AC1F85FB3FBCCCCC613 /* FSCalendarDynamicHeader.h in Headers */ = {isa = PBXBuildFile; fileRef = C86FFDEC8B47AF8416AA36ED01D23EB9 /* FSCalendarDynamicHeader.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A195A49F11E1F552B02F7D8965CD9611 /* FSCalendarWeekdayView.m in Sources */ = {isa = PBXBuildFile; fileRef = DFD62247902A1F3DED8015480A32B067 /* FSCalendarWeekdayView.m */; }; + A1D80714919926FFC1466E0B57F07869 /* FSCalendarConstants.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FFDF742492A53C80EB3DE6535DE5F5B /* FSCalendarConstants.h */; settings = {ATTRIBUTES = (Public, ); }; }; + A5D6FB46D8A7F924EE815DB46CD270F2 /* FSCalendar.m in Sources */ = {isa = PBXBuildFile; fileRef = 1340ACECFA7D446240EF07172970FD00 /* FSCalendar.m */; }; + A9A3475F9294AAF93568D0C68EF93CF7 /* FSCalendarDelegationProxy.m in Sources */ = {isa = PBXBuildFile; fileRef = B12186F66D1E03A7BCFB5C4AE87B1521 /* FSCalendarDelegationProxy.m */; }; + B367A1C1FEFC58F9DD84FFD47B2C685E /* FSCalendarCollectionViewLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 672D224DA9B7D5AC9B3CFFC14E6E573C /* FSCalendarCollectionViewLayout.h */; settings = {ATTRIBUTES = (Public, ); }; }; + B62DAE4DB75DDECB8514C2BE9CEE47C6 /* SPStorkViewControllerExtenshion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 547A4253407FC2D717107D533F5F55AB /* SPStorkViewControllerExtenshion.swift */; }; + BB94A66A8FAC9E6B69B60BDD3D387960 /* FSCalendarScopeHandle.h in Headers */ = {isa = PBXBuildFile; fileRef = 5FFB19535BD560AA60D3767E7385CA78 /* FSCalendarScopeHandle.h */; settings = {ATTRIBUTES = (Public, ); }; }; + BDF49092D330774F3FE0FDD074A6B2BE /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E826AE0196CB3540E72242664FBD3F32 /* UIKit.framework */; }; + C520F9455A25E2890C5842CB9E3AE7F4 /* FSCalendar+Persian-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = 56BE36AF4DEFE50F5EC93FF14726AD07 /* FSCalendar+Persian-dummy.m */; }; + C79E8964B2187FBF1B7BF9B9D8ACAC7E /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 90C7A160ABE5DAC85DC33E762CF55AE1 /* Foundation.framework */; }; + C8C332A8EF3C0CF47850C47CCB72B2E6 /* FSCalendarHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = FA04650D9681EFF5B977601DEF8C9EA1 /* FSCalendarHeaderView.m */; }; + C90F836A8B160986C36496E28ECAF15D /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 90C7A160ABE5DAC85DC33E762CF55AE1 /* Foundation.framework */; }; + CBA53FA534356A7B34E57EE87BC2ACFE /* SPStorkCloseButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = C76D8B680CDCE7E26C3B0CC70AEAFCA1 /* SPStorkCloseButton.swift */; }; + CC5A94C08ECC3799933A4C5ED467D3D4 /* FSCalendarCell.h in Headers */ = {isa = PBXBuildFile; fileRef = 0E8561AB2371B5201E922CF42E262C3C /* FSCalendarCell.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D2945C979C2219AB9D091DBBEF80FE8D /* Pods-pro-service-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 96814702861E83711D229A6BB8D04988 /* Pods-pro-service-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D4B9BEB4D9017BEAE539A378AC11DF91 /* SPStorkTransitioningDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = ED117FDBBF58D5320F0DF7D30F3E294F /* SPStorkTransitioningDelegate.swift */; }; + D8805ED0CE15BBD35227FF02282138D3 /* SPStorkDismissingAnimationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = AED0ABCCF1195CE1A4A353BB41C07B44 /* SPStorkDismissingAnimationController.swift */; }; + D9E00A2895E24A67DFBA194F6F17D302 /* FSCalendarStickyHeader.m in Sources */ = {isa = PBXBuildFile; fileRef = F815E1771794F0A722A7E3DD0C6A28C8 /* FSCalendarStickyHeader.m */; }; + DAB7160695AA0DD218F587C30DD64FA3 /* SPStorkController-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 880CDBD4E287D3C8A81117F4E795129D /* SPStorkController-umbrella.h */; settings = {ATTRIBUTES = (Public, ); }; }; + E825DC0574DF2275EAFC5A4AAAC19B29 /* FSCalendarAppearance.h in Headers */ = {isa = PBXBuildFile; fileRef = 0631EE55DC12C3B0774A10C4D885C276 /* FSCalendarAppearance.h */; settings = {ATTRIBUTES = (Public, ); }; }; + ED7CC8CA13A804FD26070F1E253BA247 /* FSCalendarExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 7C44A35B8BB3D9AC584093B8CAE4B311 /* FSCalendarExtensions.m */; }; + F11B51857F8518AAEB2F2678ECD70765 /* SPStorkIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C31FD338837D7DE5BFC048C25D11AB79 /* SPStorkIndicatorView.swift */; }; + F27994341E30A244A74CC7FB5B6AA085 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 90C7A160ABE5DAC85DC33E762CF55AE1 /* Foundation.framework */; }; + F76BD96B7EAC916995E20D20B641A1B4 /* SPStorkPresentationController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 263E6A3755EFC14A8822EF25FBB26A8D /* SPStorkPresentationController.swift */; }; + F9837B7F07FB5A78D58FF54F09D2226F /* Pods-pro-serviceUITests-dummy.m in Sources */ = {isa = PBXBuildFile; fileRef = D303B5541F09205EB50F59DDFA7527EA /* Pods-pro-serviceUITests-dummy.m */; }; + FD472DDC631E81024F68960744EB88C7 /* SPStorkCodeDraw.swift in Sources */ = {isa = PBXBuildFile; fileRef = 13C3E15A817EB8BD9B365C6A51E88697 /* SPStorkCodeDraw.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 096973DB39184B89485F2D25BBA2D8CA /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = DBCEA81D6F42C130C2B7F6D8C96D9239; + remoteInfo = SPStorkController; + }; + 502417070B4DFF5A92B8350D059B9F56 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = CA9DD0796C9EEAC8BB17940FF4F80790; + remoteInfo = "Pods-pro-service"; + }; + 76DCC112109C32C4CB97D058945315C5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = CA9DD0796C9EEAC8BB17940FF4F80790; + remoteInfo = "Pods-pro-service"; + }; + B0D44AA449F20D0D72A8B7993EAD07E5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = D41D8CD98F00B204E9800998ECF8427E /* Project object */; + proxyType = 1; + remoteGlobalIDString = 0BE1F8B2620BD8F90F13035023DE3466; + remoteInfo = "FSCalendar+Persian"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 009563408E8A3D18EC416FBA86127DFC /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 0631EE55DC12C3B0774A10C4D885C276 /* FSCalendarAppearance.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FSCalendarAppearance.h; path = FSCalendar/FSCalendarAppearance.h; sourceTree = ""; }; + 09962FC39A115A050970F744DD3898E5 /* NSLocale+Category.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSLocale+Category.m"; path = "FSCalendar/NSLocale+Category.m"; sourceTree = ""; }; + 0A8211DE2AB8E3B4A9F1E2EE96314F13 /* SPStorkCloseView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SPStorkCloseView.swift; path = Source/SPStorkController/Views/SPStorkCloseView.swift; sourceTree = ""; }; + 0E4D28FC2AA46AF4F1953997BE1C6CB2 /* FSCalendarScopeHandle.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FSCalendarScopeHandle.m; path = FSCalendar/FSCalendarScopeHandle.m; sourceTree = ""; }; + 0E8561AB2371B5201E922CF42E262C3C /* FSCalendarCell.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FSCalendarCell.h; path = FSCalendar/FSCalendarCell.h; sourceTree = ""; }; + 1340ACECFA7D446240EF07172970FD00 /* FSCalendar.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FSCalendar.m; path = FSCalendar/FSCalendar.m; sourceTree = ""; }; + 13C3E15A817EB8BD9B365C6A51E88697 /* SPStorkCodeDraw.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SPStorkCodeDraw.swift; path = Source/SPStorkController/CodeDraw/SPStorkCodeDraw.swift; sourceTree = ""; }; + 1447747FDBED86D9BF4E2D1A437C3F0C /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 1A5C7A882EC979B2AAE4612A09B747D1 /* Pods-pro-service.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-pro-service.modulemap"; sourceTree = ""; }; + 1D6BC915AA92A3928178170A7C9C5FE4 /* SPStorkController-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SPStorkController-prefix.pch"; sourceTree = ""; }; + 2037C4140D6D86CD7DB133348BA50EAE /* FSCalendarCollectionView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FSCalendarCollectionView.m; path = FSCalendar/FSCalendarCollectionView.m; sourceTree = ""; }; + 249883BD10DC21836F257667E4683BC1 /* Pods-pro-serviceTests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-pro-serviceTests-acknowledgements.markdown"; sourceTree = ""; }; + 263E6A3755EFC14A8822EF25FBB26A8D /* SPStorkPresentationController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SPStorkPresentationController.swift; path = Source/SPStorkController/TransitioningDelegate/SPStorkPresentationController.swift; sourceTree = ""; }; + 27E5D5ACE2E28E1044705EC33BE7F098 /* FSCalendarTransitionCoordinator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FSCalendarTransitionCoordinator.m; path = FSCalendar/FSCalendarTransitionCoordinator.m; sourceTree = ""; }; + 28B8F3FB6876DFDCA25F8F5E5C1F0675 /* Pods-pro-serviceTests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-pro-serviceTests-acknowledgements.plist"; sourceTree = ""; }; + 2DE1C9F64DEF9EF453D47B18384DCD27 /* Pods-pro-serviceUITests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-pro-serviceUITests.modulemap"; sourceTree = ""; }; + 2EC56A3770C1B4288749210C6EB33923 /* Pods-pro-serviceUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-pro-serviceUITests.release.xcconfig"; sourceTree = ""; }; + 32DCFDEF08EB09029F0C8F9C5930C6DC /* FSCalendarConstants.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FSCalendarConstants.m; path = FSCalendar/FSCalendarConstants.m; sourceTree = ""; }; + 337FA11D58CEB4F9B986D32ED30F16E3 /* Pods-pro-service.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-pro-service.debug.xcconfig"; sourceTree = ""; }; + 3529C0EEEDB63D46B316D6C3AF654669 /* Pods_pro_serviceTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_pro_serviceTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 40F421CF613E634953816E242C9D1BBA /* Pods-pro-service-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-pro-service-acknowledgements.markdown"; sourceTree = ""; }; + 41A48F6397BA5A15F298958473E3A87C /* Pods-pro-service-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-pro-service-resources.sh"; sourceTree = ""; }; + 4502C042CE52B6DE846FCBBC2664E5D1 /* Pods-pro-serviceTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-pro-serviceTests.debug.xcconfig"; sourceTree = ""; }; + 4646E797847E945638285BBEBC4B1812 /* Pods_pro_service.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_pro_service.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 547A4253407FC2D717107D533F5F55AB /* SPStorkViewControllerExtenshion.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SPStorkViewControllerExtenshion.swift; path = Source/SPStorkController/Extenshion/SPStorkViewControllerExtenshion.swift; sourceTree = ""; }; + 56BE36AF4DEFE50F5EC93FF14726AD07 /* FSCalendar+Persian-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "FSCalendar+Persian-dummy.m"; sourceTree = ""; }; + 59480774938E948862280EE4612BB053 /* FSCalendarWeekdayView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FSCalendarWeekdayView.h; path = FSCalendar/FSCalendarWeekdayView.h; sourceTree = ""; }; + 597B3F89CE35A5805E9DE839823909FF /* NSLocale+Category.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSLocale+Category.h"; path = "FSCalendar/NSLocale+Category.h"; sourceTree = ""; }; + 5FFB19535BD560AA60D3767E7385CA78 /* FSCalendarScopeHandle.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FSCalendarScopeHandle.h; path = FSCalendar/FSCalendarScopeHandle.h; sourceTree = ""; }; + 5FFDF742492A53C80EB3DE6535DE5F5B /* FSCalendarConstants.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FSCalendarConstants.h; path = FSCalendar/FSCalendarConstants.h; sourceTree = ""; }; + 64F24D32FC12B209C0D81E97E7032D3D /* NSString+Category.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = "NSString+Category.h"; path = "FSCalendar/NSString+Category.h"; sourceTree = ""; }; + 65CD2108F2A45D6F53B33351BC320418 /* Pods-pro-serviceTests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-pro-serviceTests-umbrella.h"; sourceTree = ""; }; + 672D224DA9B7D5AC9B3CFFC14E6E573C /* FSCalendarCollectionViewLayout.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FSCalendarCollectionViewLayout.h; path = FSCalendar/FSCalendarCollectionViewLayout.h; sourceTree = ""; }; + 67F8C03CC900D8B441764A073366596F /* FSCalendarCollectionView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FSCalendarCollectionView.h; path = FSCalendar/FSCalendarCollectionView.h; sourceTree = ""; }; + 6AE13B50212A971B111F9A9C1BAF05F0 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6B30D00C742771B518F025FC33F6C53C /* FSCalendarAppearance.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FSCalendarAppearance.m; path = FSCalendar/FSCalendarAppearance.m; sourceTree = ""; }; + 6CDD7B6A7AEBD878F8230FE5529F68AD /* FSCalendarStickyHeader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FSCalendarStickyHeader.h; path = FSCalendar/FSCalendarStickyHeader.h; sourceTree = ""; }; + 6D8D3EEF61876B838F8411712C8FDA93 /* NSString+Category.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "NSString+Category.m"; path = "FSCalendar/NSString+Category.m"; sourceTree = ""; }; + 6E71438AC86CBA5D0DAF3C091E437013 /* Pods_pro_serviceUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_pro_serviceUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 70216EE0681D4C2F73E2A3E77F530948 /* SPStorkController.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SPStorkController.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 70722A47C6484E52B0E59B8E6C8A1018 /* Pods-pro-serviceTests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-pro-serviceTests-dummy.m"; sourceTree = ""; }; + 78191B7D1939A451184D02C75CF8904B /* Pods-pro-serviceUITests-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-pro-serviceUITests-resources.sh"; sourceTree = ""; }; + 7B36AEA29E3435A181F6AF4DA452F228 /* FSCalendar+Persian-prefix.pch */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FSCalendar+Persian-prefix.pch"; sourceTree = ""; }; + 7C44A35B8BB3D9AC584093B8CAE4B311 /* FSCalendarExtensions.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FSCalendarExtensions.m; path = FSCalendar/FSCalendarExtensions.m; sourceTree = ""; }; + 7E5C32347E0BC58203E2945F571FD6D5 /* SPStorkController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SPStorkController.swift; path = Source/SPStorkController/SPStorkController.swift; sourceTree = ""; }; + 8039158DFBC593C815EE026B534F38D0 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 827640F1C8D3D726EF4EFDFDBF853DBF /* Pods-pro-serviceUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-pro-serviceUITests.debug.xcconfig"; sourceTree = ""; }; + 86F2CDC44CADAC5EA4B271F7F7BFBBE2 /* FSCalendar+Persian.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "FSCalendar+Persian.xcconfig"; sourceTree = ""; }; + 871A9291044B93D5FE280B9AA20B9C53 /* Pods-pro-serviceUITests-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-pro-serviceUITests-umbrella.h"; sourceTree = ""; }; + 880CDBD4E287D3C8A81117F4E795129D /* SPStorkController-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "SPStorkController-umbrella.h"; sourceTree = ""; }; + 89632C4E08F69A71F0E6513CBB39BCB7 /* FSCalendar_Persian.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = FSCalendar_Persian.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 8B4E7BBD1AE76CEC45869265AF31FA2A /* SPStorkController.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = SPStorkController.xcconfig; sourceTree = ""; }; + 8FD76AE62D8FB1D1A4503EB44377596B /* FSCalendarHeaderView.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FSCalendarHeaderView.h; path = FSCalendar/FSCalendarHeaderView.h; sourceTree = ""; }; + 90C7A160ABE5DAC85DC33E762CF55AE1 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */ = {isa = PBXFileReference; explicitFileType = text.script.ruby; includeInIndex = 1; name = Podfile; path = ../Podfile; sourceTree = SOURCE_ROOT; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; + 941C4A1AB02BB6B0229C80983173274F /* FSCalendarDelegationFactory.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FSCalendarDelegationFactory.m; path = FSCalendar/FSCalendarDelegationFactory.m; sourceTree = ""; }; + 96814702861E83711D229A6BB8D04988 /* Pods-pro-service-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "Pods-pro-service-umbrella.h"; sourceTree = ""; }; + 995EE19C4CE97E34CD1AF1EC04E5B8DD /* Pods-pro-serviceUITests-acknowledgements.markdown */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; path = "Pods-pro-serviceUITests-acknowledgements.markdown"; sourceTree = ""; }; + A0056DAA88954B7060840CCDE1DBA4D9 /* FSCalendarCalculator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FSCalendarCalculator.h; path = FSCalendar/FSCalendarCalculator.h; sourceTree = ""; }; + A2606F2FE14BB5A988FA7CFEFC22D8B8 /* Pods-pro-serviceTests-resources.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-pro-serviceTests-resources.sh"; sourceTree = ""; }; + A39D2CD656ED8B0130FCF26324FDA4A9 /* Pods-pro-service-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-pro-service-acknowledgements.plist"; sourceTree = ""; }; + AED0ABCCF1195CE1A4A353BB41C07B44 /* SPStorkDismissingAnimationController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SPStorkDismissingAnimationController.swift; path = Source/SPStorkController/TransitioningDelegate/SPStorkDismissingAnimationController.swift; sourceTree = ""; }; + B12186F66D1E03A7BCFB5C4AE87B1521 /* FSCalendarDelegationProxy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FSCalendarDelegationProxy.m; path = FSCalendar/FSCalendarDelegationProxy.m; sourceTree = ""; }; + B3226F6B0BF0B3319A04300A5621E06C /* SPStorkController-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "SPStorkController-dummy.m"; sourceTree = ""; }; + B7B082A0009DC7F3B2A04F669F3BD0D3 /* FSCalendar+Deprecated.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = "FSCalendar+Deprecated.m"; path = "FSCalendar/FSCalendar+Deprecated.m"; sourceTree = ""; }; + BBFCB44F80C5A51ED1B0656253C7608E /* Pods-pro-serviceUITests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-pro-serviceUITests-frameworks.sh"; sourceTree = ""; }; + BC9A46E94C37DB6BC63C05988DF042ED /* Pods-pro-service.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-pro-service.release.xcconfig"; sourceTree = ""; }; + C25AE44EB14613C4D868D8294AF65F11 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + C299234EF0DF3876A8B69E8602335827 /* Pods-pro-serviceUITests-acknowledgements.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; path = "Pods-pro-serviceUITests-acknowledgements.plist"; sourceTree = ""; }; + C31FD338837D7DE5BFC048C25D11AB79 /* SPStorkIndicatorView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SPStorkIndicatorView.swift; path = Source/SPStorkController/Views/SPStorkIndicatorView.swift; sourceTree = ""; }; + C4EA5F0CEFFD68E552A4BEE0CD7D83B4 /* Pods-pro-service-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-pro-service-dummy.m"; sourceTree = ""; }; + C76D8B680CDCE7E26C3B0CC70AEAFCA1 /* SPStorkCloseButton.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SPStorkCloseButton.swift; path = Source/SPStorkController/Views/SPStorkCloseButton.swift; sourceTree = ""; }; + C86FFDEC8B47AF8416AA36ED01D23EB9 /* FSCalendarDynamicHeader.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FSCalendarDynamicHeader.h; path = FSCalendar/FSCalendarDynamicHeader.h; sourceTree = ""; }; + CC8A0C406BAD2B954B57EC44F249F90E /* FSCalendarCollectionViewLayout.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FSCalendarCollectionViewLayout.m; path = FSCalendar/FSCalendarCollectionViewLayout.m; sourceTree = ""; }; + CEC6C25B07499F84F5384DAB0247E62D /* SPStorkPresentingAnimationController.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SPStorkPresentingAnimationController.swift; path = Source/SPStorkController/TransitioningDelegate/SPStorkPresentingAnimationController.swift; sourceTree = ""; }; + D0BC09F68726C585750CE647A354E330 /* Pods-pro-serviceTests-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-pro-serviceTests-frameworks.sh"; sourceTree = ""; }; + D2ECC741B7B20CD045084E6C67BC1A0C /* FSCalendarDelegationProxy.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FSCalendarDelegationProxy.h; path = FSCalendar/FSCalendarDelegationProxy.h; sourceTree = ""; }; + D303B5541F09205EB50F59DDFA7527EA /* Pods-pro-serviceUITests-dummy.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; path = "Pods-pro-serviceUITests-dummy.m"; sourceTree = ""; }; + D6E839864EE09C8CE0528DE01FD9241A /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.sdk/System/Library/Frameworks/QuartzCore.framework; sourceTree = DEVELOPER_DIR; }; + DB4A6DCF6B5BBD469993091715B82ADA /* FSCalendar+Persian-umbrella.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; path = "FSCalendar+Persian-umbrella.h"; sourceTree = ""; }; + DB7D617D5B891A53DDF150C069069C31 /* Pods-pro-serviceTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; path = "Pods-pro-serviceTests.release.xcconfig"; sourceTree = ""; }; + DD924D15389F147EC8418FB6309D279D /* FSCalendarCell.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FSCalendarCell.m; path = FSCalendar/FSCalendarCell.m; sourceTree = ""; }; + DFD62247902A1F3DED8015480A32B067 /* FSCalendarWeekdayView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FSCalendarWeekdayView.m; path = FSCalendar/FSCalendarWeekdayView.m; sourceTree = ""; }; + E04F9FF8E298F887D06CC5C312313147 /* FSCalendarCalculator.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FSCalendarCalculator.m; path = FSCalendar/FSCalendarCalculator.m; sourceTree = ""; }; + E28B5F91AA22D1C55F50E44DD9F39839 /* FSCalendarDelegationFactory.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FSCalendarDelegationFactory.h; path = FSCalendar/FSCalendarDelegationFactory.h; sourceTree = ""; }; + E67CD264A492AEB55E5F4B306D9470DA /* FSCalendar.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FSCalendar.h; path = FSCalendar/FSCalendar.h; sourceTree = ""; }; + E826AE0196CB3540E72242664FBD3F32 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS11.3.sdk/System/Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; }; + E86D99D80A868F5216CC32EC49A382AD /* FSCalendarExtensions.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FSCalendarExtensions.h; path = FSCalendar/FSCalendarExtensions.h; sourceTree = ""; }; + ED117FDBBF58D5320F0DF7D30F3E294F /* SPStorkTransitioningDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SPStorkTransitioningDelegate.swift; path = Source/SPStorkController/TransitioningDelegate/SPStorkTransitioningDelegate.swift; sourceTree = ""; }; + ED2E66AFC0D16D316D69A30EF6D2C804 /* Pods-pro-serviceTests.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "Pods-pro-serviceTests.modulemap"; sourceTree = ""; }; + F1617E9F0AC3AEB12968A43925948905 /* FSCalendarTransitionCoordinator.h */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.h; name = FSCalendarTransitionCoordinator.h; path = FSCalendar/FSCalendarTransitionCoordinator.h; sourceTree = ""; }; + F815E1771794F0A722A7E3DD0C6A28C8 /* FSCalendarStickyHeader.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FSCalendarStickyHeader.m; path = FSCalendar/FSCalendarStickyHeader.m; sourceTree = ""; }; + F8A4A69B47CC51D78D3DD5B857F29232 /* SPStorkControllerDelegate.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SPStorkControllerDelegate.swift; path = Source/SPStorkController/Protocols/SPStorkControllerDelegate.swift; sourceTree = ""; }; + FA04650D9681EFF5B977601DEF8C9EA1 /* FSCalendarHeaderView.m */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.c.objc; name = FSCalendarHeaderView.m; path = FSCalendar/FSCalendarHeaderView.m; sourceTree = ""; }; + FA0CDAB26D37FE0FE5CC0B74CA70F56F /* SPStorkController.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = SPStorkController.modulemap; sourceTree = ""; }; + FF3937B9DD82E1039C6F64BBC215934A /* Pods-pro-service-frameworks.sh */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.script.sh; path = "Pods-pro-service-frameworks.sh"; sourceTree = ""; }; + FF97562717BEC36D09D7A8DE8C29DAD2 /* FSCalendar+Persian.modulemap */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.module; path = "FSCalendar+Persian.modulemap"; sourceTree = ""; }; + FFF53E9305A12D477CBAAE67F0E6BEAA /* SPStorkHaptic.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = SPStorkHaptic.swift; path = Source/SPStorkController/Models/SPStorkHaptic.swift; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 212CEF8F3C26555D4968A3739789EAFD /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + C79E8964B2187FBF1B7BF9B9D8ACAC7E /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 51A852EF19DDCFA854C1D8CC1BE53D97 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + C90F836A8B160986C36496E28ECAF15D /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 57B921AE4D0CF2C47C818E1095C379F8 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F27994341E30A244A74CC7FB5B6AA085 /* Foundation.framework in Frameworks */, + BDF49092D330774F3FE0FDD074A6B2BE /* UIKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7FBBFF2DCAE2BE8610D6C92B6B1E4287 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8809E5B103DBACC37E45D868CA146D98 /* Foundation.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + ABC2EF8D37BCB0E555296C44D65C4519 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 7D4095AD807E801D9794E74CE768B7AB /* Foundation.framework in Frameworks */, + 7C6FC4F353CA8EF16E43566EC11818B8 /* QuartzCore.framework in Frameworks */, + 634B9BA6D00BC152D5B0D7FB2597B200 /* UIKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 0B5DA84D19A46867B9DDBC1DFF3A0B3A /* Pods-pro-serviceUITests */ = { + isa = PBXGroup; + children = ( + 8039158DFBC593C815EE026B534F38D0 /* Info.plist */, + 2DE1C9F64DEF9EF453D47B18384DCD27 /* Pods-pro-serviceUITests.modulemap */, + 995EE19C4CE97E34CD1AF1EC04E5B8DD /* Pods-pro-serviceUITests-acknowledgements.markdown */, + C299234EF0DF3876A8B69E8602335827 /* Pods-pro-serviceUITests-acknowledgements.plist */, + D303B5541F09205EB50F59DDFA7527EA /* Pods-pro-serviceUITests-dummy.m */, + BBFCB44F80C5A51ED1B0656253C7608E /* Pods-pro-serviceUITests-frameworks.sh */, + 78191B7D1939A451184D02C75CF8904B /* Pods-pro-serviceUITests-resources.sh */, + 871A9291044B93D5FE280B9AA20B9C53 /* Pods-pro-serviceUITests-umbrella.h */, + 827640F1C8D3D726EF4EFDFDBF853DBF /* Pods-pro-serviceUITests.debug.xcconfig */, + 2EC56A3770C1B4288749210C6EB33923 /* Pods-pro-serviceUITests.release.xcconfig */, + ); + name = "Pods-pro-serviceUITests"; + path = "Target Support Files/Pods-pro-serviceUITests"; + sourceTree = ""; + }; + 10FBD01056BCD45FEF7C1E6A058545F8 /* Support Files */ = { + isa = PBXGroup; + children = ( + C25AE44EB14613C4D868D8294AF65F11 /* Info.plist */, + FA0CDAB26D37FE0FE5CC0B74CA70F56F /* SPStorkController.modulemap */, + 8B4E7BBD1AE76CEC45869265AF31FA2A /* SPStorkController.xcconfig */, + B3226F6B0BF0B3319A04300A5621E06C /* SPStorkController-dummy.m */, + 1D6BC915AA92A3928178170A7C9C5FE4 /* SPStorkController-prefix.pch */, + 880CDBD4E287D3C8A81117F4E795129D /* SPStorkController-umbrella.h */, + ); + name = "Support Files"; + path = "../Target Support Files/SPStorkController"; + sourceTree = ""; + }; + 122DA2E5084A4393C29BE363C764795C /* Frameworks */ = { + isa = PBXGroup; + children = ( + 9EBF83A17FAAD0333B507DD3E1099181 /* iOS */, + ); + name = Frameworks; + sourceTree = ""; + }; + 1B76DC4FD789CF6951C1962325877F13 /* Pods-pro-serviceTests */ = { + isa = PBXGroup; + children = ( + 6AE13B50212A971B111F9A9C1BAF05F0 /* Info.plist */, + ED2E66AFC0D16D316D69A30EF6D2C804 /* Pods-pro-serviceTests.modulemap */, + 249883BD10DC21836F257667E4683BC1 /* Pods-pro-serviceTests-acknowledgements.markdown */, + 28B8F3FB6876DFDCA25F8F5E5C1F0675 /* Pods-pro-serviceTests-acknowledgements.plist */, + 70722A47C6484E52B0E59B8E6C8A1018 /* Pods-pro-serviceTests-dummy.m */, + D0BC09F68726C585750CE647A354E330 /* Pods-pro-serviceTests-frameworks.sh */, + A2606F2FE14BB5A988FA7CFEFC22D8B8 /* Pods-pro-serviceTests-resources.sh */, + 65CD2108F2A45D6F53B33351BC320418 /* Pods-pro-serviceTests-umbrella.h */, + 4502C042CE52B6DE846FCBBC2664E5D1 /* Pods-pro-serviceTests.debug.xcconfig */, + DB7D617D5B891A53DDF150C069069C31 /* Pods-pro-serviceTests.release.xcconfig */, + ); + name = "Pods-pro-serviceTests"; + path = "Target Support Files/Pods-pro-serviceTests"; + sourceTree = ""; + }; + 5ED7CBCEF932470CFE473505E149126A /* Products */ = { + isa = PBXGroup; + children = ( + 89632C4E08F69A71F0E6513CBB39BCB7 /* FSCalendar_Persian.framework */, + 4646E797847E945638285BBEBC4B1812 /* Pods_pro_service.framework */, + 3529C0EEEDB63D46B316D6C3AF654669 /* Pods_pro_serviceTests.framework */, + 6E71438AC86CBA5D0DAF3C091E437013 /* Pods_pro_serviceUITests.framework */, + 70216EE0681D4C2F73E2A3E77F530948 /* SPStorkController.framework */, + ); + name = Products; + sourceTree = ""; + }; + 6A5E624C7EEDD60F859F53C481FCC476 /* Targets Support Files */ = { + isa = PBXGroup; + children = ( + 7D4FD2471FBA8997D5AE26F50B8D2DAF /* Pods-pro-service */, + 1B76DC4FD789CF6951C1962325877F13 /* Pods-pro-serviceTests */, + 0B5DA84D19A46867B9DDBC1DFF3A0B3A /* Pods-pro-serviceUITests */, + ); + name = "Targets Support Files"; + sourceTree = ""; + }; + 7D4FD2471FBA8997D5AE26F50B8D2DAF /* Pods-pro-service */ = { + isa = PBXGroup; + children = ( + 009563408E8A3D18EC416FBA86127DFC /* Info.plist */, + 1A5C7A882EC979B2AAE4612A09B747D1 /* Pods-pro-service.modulemap */, + 40F421CF613E634953816E242C9D1BBA /* Pods-pro-service-acknowledgements.markdown */, + A39D2CD656ED8B0130FCF26324FDA4A9 /* Pods-pro-service-acknowledgements.plist */, + C4EA5F0CEFFD68E552A4BEE0CD7D83B4 /* Pods-pro-service-dummy.m */, + FF3937B9DD82E1039C6F64BBC215934A /* Pods-pro-service-frameworks.sh */, + 41A48F6397BA5A15F298958473E3A87C /* Pods-pro-service-resources.sh */, + 96814702861E83711D229A6BB8D04988 /* Pods-pro-service-umbrella.h */, + 337FA11D58CEB4F9B986D32ED30F16E3 /* Pods-pro-service.debug.xcconfig */, + BC9A46E94C37DB6BC63C05988DF042ED /* Pods-pro-service.release.xcconfig */, + ); + name = "Pods-pro-service"; + path = "Target Support Files/Pods-pro-service"; + sourceTree = ""; + }; + 7DB346D0F39D3F0E887471402A8071AB = { + isa = PBXGroup; + children = ( + 93A4A3777CF96A4AAC1D13BA6DCCEA73 /* Podfile */, + 122DA2E5084A4393C29BE363C764795C /* Frameworks */, + E57E77FDBB22E753A94A6497F57E4194 /* Pods */, + 5ED7CBCEF932470CFE473505E149126A /* Products */, + 6A5E624C7EEDD60F859F53C481FCC476 /* Targets Support Files */, + ); + sourceTree = ""; + }; + 9EBF83A17FAAD0333B507DD3E1099181 /* iOS */ = { + isa = PBXGroup; + children = ( + 90C7A160ABE5DAC85DC33E762CF55AE1 /* Foundation.framework */, + D6E839864EE09C8CE0528DE01FD9241A /* QuartzCore.framework */, + E826AE0196CB3540E72242664FBD3F32 /* UIKit.framework */, + ); + name = iOS; + sourceTree = ""; + }; + A09B30AC83B9C77FA108C5ADADB66072 /* FSCalendar+Persian */ = { + isa = PBXGroup; + children = ( + E67CD264A492AEB55E5F4B306D9470DA /* FSCalendar.h */, + 1340ACECFA7D446240EF07172970FD00 /* FSCalendar.m */, + B7B082A0009DC7F3B2A04F669F3BD0D3 /* FSCalendar+Deprecated.m */, + 0631EE55DC12C3B0774A10C4D885C276 /* FSCalendarAppearance.h */, + 6B30D00C742771B518F025FC33F6C53C /* FSCalendarAppearance.m */, + A0056DAA88954B7060840CCDE1DBA4D9 /* FSCalendarCalculator.h */, + E04F9FF8E298F887D06CC5C312313147 /* FSCalendarCalculator.m */, + 0E8561AB2371B5201E922CF42E262C3C /* FSCalendarCell.h */, + DD924D15389F147EC8418FB6309D279D /* FSCalendarCell.m */, + 67F8C03CC900D8B441764A073366596F /* FSCalendarCollectionView.h */, + 2037C4140D6D86CD7DB133348BA50EAE /* FSCalendarCollectionView.m */, + 672D224DA9B7D5AC9B3CFFC14E6E573C /* FSCalendarCollectionViewLayout.h */, + CC8A0C406BAD2B954B57EC44F249F90E /* FSCalendarCollectionViewLayout.m */, + 5FFDF742492A53C80EB3DE6535DE5F5B /* FSCalendarConstants.h */, + 32DCFDEF08EB09029F0C8F9C5930C6DC /* FSCalendarConstants.m */, + E28B5F91AA22D1C55F50E44DD9F39839 /* FSCalendarDelegationFactory.h */, + 941C4A1AB02BB6B0229C80983173274F /* FSCalendarDelegationFactory.m */, + D2ECC741B7B20CD045084E6C67BC1A0C /* FSCalendarDelegationProxy.h */, + B12186F66D1E03A7BCFB5C4AE87B1521 /* FSCalendarDelegationProxy.m */, + C86FFDEC8B47AF8416AA36ED01D23EB9 /* FSCalendarDynamicHeader.h */, + E86D99D80A868F5216CC32EC49A382AD /* FSCalendarExtensions.h */, + 7C44A35B8BB3D9AC584093B8CAE4B311 /* FSCalendarExtensions.m */, + 8FD76AE62D8FB1D1A4503EB44377596B /* FSCalendarHeaderView.h */, + FA04650D9681EFF5B977601DEF8C9EA1 /* FSCalendarHeaderView.m */, + 5FFB19535BD560AA60D3767E7385CA78 /* FSCalendarScopeHandle.h */, + 0E4D28FC2AA46AF4F1953997BE1C6CB2 /* FSCalendarScopeHandle.m */, + 6CDD7B6A7AEBD878F8230FE5529F68AD /* FSCalendarStickyHeader.h */, + F815E1771794F0A722A7E3DD0C6A28C8 /* FSCalendarStickyHeader.m */, + F1617E9F0AC3AEB12968A43925948905 /* FSCalendarTransitionCoordinator.h */, + 27E5D5ACE2E28E1044705EC33BE7F098 /* FSCalendarTransitionCoordinator.m */, + 59480774938E948862280EE4612BB053 /* FSCalendarWeekdayView.h */, + DFD62247902A1F3DED8015480A32B067 /* FSCalendarWeekdayView.m */, + 597B3F89CE35A5805E9DE839823909FF /* NSLocale+Category.h */, + 09962FC39A115A050970F744DD3898E5 /* NSLocale+Category.m */, + 64F24D32FC12B209C0D81E97E7032D3D /* NSString+Category.h */, + 6D8D3EEF61876B838F8411712C8FDA93 /* NSString+Category.m */, + DE46773C7CC4C3D34745000A51E8F998 /* Support Files */, + ); + path = "FSCalendar+Persian"; + sourceTree = ""; + }; + BAFCE1984BCE69F29DFC7986B9B0F204 /* SPStorkController */ = { + isa = PBXGroup; + children = ( + C76D8B680CDCE7E26C3B0CC70AEAFCA1 /* SPStorkCloseButton.swift */, + 0A8211DE2AB8E3B4A9F1E2EE96314F13 /* SPStorkCloseView.swift */, + 13C3E15A817EB8BD9B365C6A51E88697 /* SPStorkCodeDraw.swift */, + 7E5C32347E0BC58203E2945F571FD6D5 /* SPStorkController.swift */, + F8A4A69B47CC51D78D3DD5B857F29232 /* SPStorkControllerDelegate.swift */, + AED0ABCCF1195CE1A4A353BB41C07B44 /* SPStorkDismissingAnimationController.swift */, + FFF53E9305A12D477CBAAE67F0E6BEAA /* SPStorkHaptic.swift */, + C31FD338837D7DE5BFC048C25D11AB79 /* SPStorkIndicatorView.swift */, + 263E6A3755EFC14A8822EF25FBB26A8D /* SPStorkPresentationController.swift */, + CEC6C25B07499F84F5384DAB0247E62D /* SPStorkPresentingAnimationController.swift */, + ED117FDBBF58D5320F0DF7D30F3E294F /* SPStorkTransitioningDelegate.swift */, + 547A4253407FC2D717107D533F5F55AB /* SPStorkViewControllerExtenshion.swift */, + 10FBD01056BCD45FEF7C1E6A058545F8 /* Support Files */, + ); + path = SPStorkController; + sourceTree = ""; + }; + DE46773C7CC4C3D34745000A51E8F998 /* Support Files */ = { + isa = PBXGroup; + children = ( + FF97562717BEC36D09D7A8DE8C29DAD2 /* FSCalendar+Persian.modulemap */, + 86F2CDC44CADAC5EA4B271F7F7BFBBE2 /* FSCalendar+Persian.xcconfig */, + 56BE36AF4DEFE50F5EC93FF14726AD07 /* FSCalendar+Persian-dummy.m */, + 7B36AEA29E3435A181F6AF4DA452F228 /* FSCalendar+Persian-prefix.pch */, + DB4A6DCF6B5BBD469993091715B82ADA /* FSCalendar+Persian-umbrella.h */, + 1447747FDBED86D9BF4E2D1A437C3F0C /* Info.plist */, + ); + name = "Support Files"; + path = "../Target Support Files/FSCalendar+Persian"; + sourceTree = ""; + }; + E57E77FDBB22E753A94A6497F57E4194 /* Pods */ = { + isa = PBXGroup; + children = ( + A09B30AC83B9C77FA108C5ADADB66072 /* FSCalendar+Persian */, + BAFCE1984BCE69F29DFC7986B9B0F204 /* SPStorkController */, + ); + name = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 52BCEB1D69B2385F38070A509A66107D /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + D2945C979C2219AB9D091DBBEF80FE8D /* Pods-pro-service-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 587835A061DCAA1A94B08272FC9C3A39 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 7DDA8AC5C25E68301425C9F63C927C65 /* Pods-pro-serviceTests-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 88B6D19D24382FE62D111F46138F25E4 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 2FDB02BA3EA5B8391CD378BE1E9E5BC8 /* FSCalendar+Persian-umbrella.h in Headers */, + 36DB6762A2C21928A61E08DFF8D011E6 /* FSCalendar.h in Headers */, + E825DC0574DF2275EAFC5A4AAAC19B29 /* FSCalendarAppearance.h in Headers */, + 567AEDF1581D72398E7F74F3E79B4B7E /* FSCalendarCalculator.h in Headers */, + CC5A94C08ECC3799933A4C5ED467D3D4 /* FSCalendarCell.h in Headers */, + 9AE53F0BC6EDE5B517DBBBE22DC7F730 /* FSCalendarCollectionView.h in Headers */, + B367A1C1FEFC58F9DD84FFD47B2C685E /* FSCalendarCollectionViewLayout.h in Headers */, + A1D80714919926FFC1466E0B57F07869 /* FSCalendarConstants.h in Headers */, + 08762A15D4394DE9D666C9B7F31610B4 /* FSCalendarDelegationFactory.h in Headers */, + 5FD9F570D8E0DE51BC261CF59F33FA7E /* FSCalendarDelegationProxy.h in Headers */, + 9FB061E4A92C3AC1F85FB3FBCCCCC613 /* FSCalendarDynamicHeader.h in Headers */, + 12A7B0D185627042EA7D47DCE6DF5748 /* FSCalendarExtensions.h in Headers */, + 5D7118DF99596ED2375328DDC7BC9C8B /* FSCalendarHeaderView.h in Headers */, + BB94A66A8FAC9E6B69B60BDD3D387960 /* FSCalendarScopeHandle.h in Headers */, + 6474279BD680FB0E25D50DDCC5C3F587 /* FSCalendarStickyHeader.h in Headers */, + 36337CC61EB63AEAC9072F75B4475987 /* FSCalendarTransitionCoordinator.h in Headers */, + 17D80AB2A0433F80228DE376D1DBD7F2 /* FSCalendarWeekdayView.h in Headers */, + 1EBB6FCFDD1B58E052C074DCD7D4F83E /* NSLocale+Category.h in Headers */, + 9C566B5D740908B59F2D865DD02E6A33 /* NSString+Category.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8C4426AD7C7A1935CE9430E6B5D06617 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 14F94575C2D09D1D23CE3462B1361DA4 /* Pods-pro-serviceUITests-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 9D6CE737B73F377493C091FEAD384C51 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + DAB7160695AA0DD218F587C30DD64FA3 /* SPStorkController-umbrella.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 0BE1F8B2620BD8F90F13035023DE3466 /* FSCalendar+Persian */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4ADD88BFC2372F007AF2FCE0E98AA401 /* Build configuration list for PBXNativeTarget "FSCalendar+Persian" */; + buildPhases = ( + 3A1B2406516756026DFF458EA4222FDA /* Sources */, + ABC2EF8D37BCB0E555296C44D65C4519 /* Frameworks */, + 88B6D19D24382FE62D111F46138F25E4 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "FSCalendar+Persian"; + productName = "FSCalendar+Persian"; + productReference = 89632C4E08F69A71F0E6513CBB39BCB7 /* FSCalendar_Persian.framework */; + productType = "com.apple.product-type.framework"; + }; + 524EDEAB32B9EDDF0C124FA7CC95EC6B /* Pods-pro-serviceTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = F9FF4776B50A61BD49939E6F3AB4F85F /* Build configuration list for PBXNativeTarget "Pods-pro-serviceTests" */; + buildPhases = ( + A8545114FB77FA735D6D085889EE221D /* Sources */, + 51A852EF19DDCFA854C1D8CC1BE53D97 /* Frameworks */, + 587835A061DCAA1A94B08272FC9C3A39 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + FBD842E9636A44B92F0888028D32DB8A /* PBXTargetDependency */, + ); + name = "Pods-pro-serviceTests"; + productName = "Pods-pro-serviceTests"; + productReference = 3529C0EEEDB63D46B316D6C3AF654669 /* Pods_pro_serviceTests.framework */; + productType = "com.apple.product-type.framework"; + }; + 6CD02229725EA5E3DA59EADA0EAB54BD /* Pods-pro-serviceUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 16CB1A9EB87C68770618FC6C8C691614 /* Build configuration list for PBXNativeTarget "Pods-pro-serviceUITests" */; + buildPhases = ( + DC7DF1AE3CA6C880CF9AC0450DF3C9BF /* Sources */, + 212CEF8F3C26555D4968A3739789EAFD /* Frameworks */, + 8C4426AD7C7A1935CE9430E6B5D06617 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + 0A6A80E85BC7D462969E33D8C629FA30 /* PBXTargetDependency */, + ); + name = "Pods-pro-serviceUITests"; + productName = "Pods-pro-serviceUITests"; + productReference = 6E71438AC86CBA5D0DAF3C091E437013 /* Pods_pro_serviceUITests.framework */; + productType = "com.apple.product-type.framework"; + }; + CA9DD0796C9EEAC8BB17940FF4F80790 /* Pods-pro-service */ = { + isa = PBXNativeTarget; + buildConfigurationList = C13341F7E83A23FC0349584F5A29F743 /* Build configuration list for PBXNativeTarget "Pods-pro-service" */; + buildPhases = ( + DE821172B83A7B3B21B3D5F3030128A3 /* Sources */, + 7FBBFF2DCAE2BE8610D6C92B6B1E4287 /* Frameworks */, + 52BCEB1D69B2385F38070A509A66107D /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + 367EC615AFF87390EC13169033692826 /* PBXTargetDependency */, + E0192DED7DABA544DE57235DBF945DD7 /* PBXTargetDependency */, + ); + name = "Pods-pro-service"; + productName = "Pods-pro-service"; + productReference = 4646E797847E945638285BBEBC4B1812 /* Pods_pro_service.framework */; + productType = "com.apple.product-type.framework"; + }; + DBCEA81D6F42C130C2B7F6D8C96D9239 /* SPStorkController */ = { + isa = PBXNativeTarget; + buildConfigurationList = B23EA3024A904EA0B9286700D2F0A17D /* Build configuration list for PBXNativeTarget "SPStorkController" */; + buildPhases = ( + 2CC6B718ED8D53FF1F5A1A229C7F2616 /* Sources */, + 57B921AE4D0CF2C47C818E1095C379F8 /* Frameworks */, + 9D6CE737B73F377493C091FEAD384C51 /* Headers */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = SPStorkController; + productName = SPStorkController; + productReference = 70216EE0681D4C2F73E2A3E77F530948 /* SPStorkController.framework */; + productType = "com.apple.product-type.framework"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + D41D8CD98F00B204E9800998ECF8427E /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 0930; + LastUpgradeCheck = 0930; + }; + buildConfigurationList = 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 7DB346D0F39D3F0E887471402A8071AB; + productRefGroup = 5ED7CBCEF932470CFE473505E149126A /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 0BE1F8B2620BD8F90F13035023DE3466 /* FSCalendar+Persian */, + CA9DD0796C9EEAC8BB17940FF4F80790 /* Pods-pro-service */, + 524EDEAB32B9EDDF0C124FA7CC95EC6B /* Pods-pro-serviceTests */, + 6CD02229725EA5E3DA59EADA0EAB54BD /* Pods-pro-serviceUITests */, + DBCEA81D6F42C130C2B7F6D8C96D9239 /* SPStorkController */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 2CC6B718ED8D53FF1F5A1A229C7F2616 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CBA53FA534356A7B34E57EE87BC2ACFE /* SPStorkCloseButton.swift in Sources */, + 2A50DA02BA56EB4850D596BA6EF9FEFC /* SPStorkCloseView.swift in Sources */, + FD472DDC631E81024F68960744EB88C7 /* SPStorkCodeDraw.swift in Sources */, + 4BF84BE2AB036F243AB646ED1BD849CF /* SPStorkController-dummy.m in Sources */, + 75E9E8FEAEE50E90FC186B962D5F69E6 /* SPStorkController.swift in Sources */, + 44CF38707E6B14382274BFF66FF0F506 /* SPStorkControllerDelegate.swift in Sources */, + D8805ED0CE15BBD35227FF02282138D3 /* SPStorkDismissingAnimationController.swift in Sources */, + 2A0C7E4AE9D378340B5ED61B3C13E1B0 /* SPStorkHaptic.swift in Sources */, + F11B51857F8518AAEB2F2678ECD70765 /* SPStorkIndicatorView.swift in Sources */, + F76BD96B7EAC916995E20D20B641A1B4 /* SPStorkPresentationController.swift in Sources */, + 1BD8FDF83BE5BAAF52602BAB16D60E21 /* SPStorkPresentingAnimationController.swift in Sources */, + D4B9BEB4D9017BEAE539A378AC11DF91 /* SPStorkTransitioningDelegate.swift in Sources */, + B62DAE4DB75DDECB8514C2BE9CEE47C6 /* SPStorkViewControllerExtenshion.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 3A1B2406516756026DFF458EA4222FDA /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 59A09F371AFD17F4A44A2F34564FF5BE /* FSCalendar+Deprecated.m in Sources */, + C520F9455A25E2890C5842CB9E3AE7F4 /* FSCalendar+Persian-dummy.m in Sources */, + A5D6FB46D8A7F924EE815DB46CD270F2 /* FSCalendar.m in Sources */, + 7556EBF7B0E61C7E2ADA7F41E075BA9E /* FSCalendarAppearance.m in Sources */, + 938ED81307AEC8A61BD8B6C9548A1F77 /* FSCalendarCalculator.m in Sources */, + 928B20E85CE7D67FAF43C3E93FE86554 /* FSCalendarCell.m in Sources */, + 14F2ABBBA9B67D3782E60B9F2BD480E1 /* FSCalendarCollectionView.m in Sources */, + 07F2CF533929DCE53CEF22EA7CFE9E69 /* FSCalendarCollectionViewLayout.m in Sources */, + 5C41DA6C326F37C89EC35069304BCF15 /* FSCalendarConstants.m in Sources */, + 6E05226078B373CA01D601C5A894C011 /* FSCalendarDelegationFactory.m in Sources */, + A9A3475F9294AAF93568D0C68EF93CF7 /* FSCalendarDelegationProxy.m in Sources */, + ED7CC8CA13A804FD26070F1E253BA247 /* FSCalendarExtensions.m in Sources */, + C8C332A8EF3C0CF47850C47CCB72B2E6 /* FSCalendarHeaderView.m in Sources */, + 6102948D28F514C701DB22B36CB8BA34 /* FSCalendarScopeHandle.m in Sources */, + D9E00A2895E24A67DFBA194F6F17D302 /* FSCalendarStickyHeader.m in Sources */, + 785E68490C090D4B32704EE17CF71A37 /* FSCalendarTransitionCoordinator.m in Sources */, + A195A49F11E1F552B02F7D8965CD9611 /* FSCalendarWeekdayView.m in Sources */, + 91079CF4D2426E39EC6C6C9D08C79F04 /* NSLocale+Category.m in Sources */, + 1FE70CAA486C68CD811D7AAD6907B04B /* NSString+Category.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + A8545114FB77FA735D6D085889EE221D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 9DB286DB734EE2753109CCC0CFDBF97B /* Pods-pro-serviceTests-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DC7DF1AE3CA6C880CF9AC0450DF3C9BF /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F9837B7F07FB5A78D58FF54F09D2226F /* Pods-pro-serviceUITests-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + DE821172B83A7B3B21B3D5F3030128A3 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 96BEB3DC4BD8EF3C7F547C3E8A16CCE5 /* Pods-pro-service-dummy.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 0A6A80E85BC7D462969E33D8C629FA30 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "Pods-pro-service"; + target = CA9DD0796C9EEAC8BB17940FF4F80790 /* Pods-pro-service */; + targetProxy = 502417070B4DFF5A92B8350D059B9F56 /* PBXContainerItemProxy */; + }; + 367EC615AFF87390EC13169033692826 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "FSCalendar+Persian"; + target = 0BE1F8B2620BD8F90F13035023DE3466 /* FSCalendar+Persian */; + targetProxy = B0D44AA449F20D0D72A8B7993EAD07E5 /* PBXContainerItemProxy */; + }; + E0192DED7DABA544DE57235DBF945DD7 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = SPStorkController; + target = DBCEA81D6F42C130C2B7F6D8C96D9239 /* SPStorkController */; + targetProxy = 096973DB39184B89485F2D25BBA2D8CA /* PBXContainerItemProxy */; + }; + FBD842E9636A44B92F0888028D32DB8A /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = "Pods-pro-service"; + target = CA9DD0796C9EEAC8BB17940FF4F80790 /* Pods-pro-service */; + targetProxy = 76DCC112109C32C4CB97D058945315C5 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin XCBuildConfiguration section */ + 065EB6ED66ADE49CF75A74056307B567 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 86F2CDC44CADAC5EA4B271F7F7BFBBE2 /* FSCalendar+Persian.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/FSCalendar+Persian/FSCalendar+Persian-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/FSCalendar+Persian/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/FSCalendar+Persian/FSCalendar+Persian.modulemap"; + PRODUCT_MODULE_NAME = FSCalendar_Persian; + PRODUCT_NAME = FSCalendar_Persian; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 553022A828EE1991F07D2D73F565AEF8 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGNING_ALLOWED = NO; + CODE_SIGNING_REQUIRED = NO; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_DEBUG=1", + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRIP_INSTALLED_PRODUCT = NO; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SYMROOT = "${SRCROOT}/../build"; + }; + name = Debug; + }; + 58CE816B060A41D32CEC095441D0E3E0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGNING_ALLOWED = NO; + CODE_SIGNING_REQUIRED = NO; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "POD_CONFIGURATION_RELEASE=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_NAME = "$(TARGET_NAME)"; + STRIP_INSTALLED_PRODUCT = NO; + SYMROOT = "${SRCROOT}/../build"; + }; + name = Release; + }; + 5A1DDE4919971D8D9B952CBF117E163A /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = BC9A46E94C37DB6BC63C05988DF042ED /* Pods-pro-service.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-pro-service/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-pro-service/Pods-pro-service.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 6732521AE73E3B404876A3D3626A3056 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = DB7D617D5B891A53DDF150C069069C31 /* Pods-pro-serviceTests.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-pro-serviceTests/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 8993A6CDE948E4921080844F4C3CC9CA /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2EC56A3770C1B4288749210C6EB33923 /* Pods-pro-serviceUITests.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-pro-serviceUITests/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + 9833B0D7AB29AC25615DF40EA5CEFD0E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 337FA11D58CEB4F9B986D32ED30F16E3 /* Pods-pro-service.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-pro-service/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-pro-service/Pods-pro-service.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + 9CD4D47B45FE260821AE10B47C8A1C6A /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 4502C042CE52B6DE846FCBBC2664E5D1 /* Pods-pro-serviceTests.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-pro-serviceTests/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + C733F3E4D32580F7B820C7214B6740A4 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8B4E7BBD1AE76CEC45869265AF31FA2A /* SPStorkController.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SPStorkController/SPStorkController-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SPStorkController/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/SPStorkController/SPStorkController.modulemap"; + PRODUCT_MODULE_NAME = SPStorkController; + PRODUCT_NAME = SPStorkController; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + DCE9C796F0B86F18C88EB3D774D6FEC9 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 86F2CDC44CADAC5EA4B271F7F7BFBBE2 /* FSCalendar+Persian.xcconfig */; + buildSettings = { + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/FSCalendar+Persian/FSCalendar+Persian-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/FSCalendar+Persian/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/FSCalendar+Persian/FSCalendar+Persian.modulemap"; + PRODUCT_MODULE_NAME = FSCalendar_Persian; + PRODUCT_NAME = FSCalendar_Persian; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + DFF7344E3D8BF8FCE39656FEECEF15C4 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 8B4E7BBD1AE76CEC45869265AF31FA2A /* SPStorkController.xcconfig */; + buildSettings = { + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + GCC_PREFIX_HEADER = "Target Support Files/SPStorkController/SPStorkController-prefix.pch"; + INFOPLIST_FILE = "Target Support Files/SPStorkController/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MODULEMAP_FILE = "Target Support Files/SPStorkController/SPStorkController.modulemap"; + PRODUCT_MODULE_NAME = SPStorkController; + PRODUCT_NAME = SPStorkController; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) "; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Release; + }; + ED2FA016634303AC113EB890061CCF0E /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 827640F1C8D3D726EF4EFDFDBF853DBF /* Pods-pro-serviceUITests.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGN_IDENTITY = ""; + "CODE_SIGN_IDENTITY[sdk=appletvos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = ""; + "CODE_SIGN_IDENTITY[sdk=watchos*]" = ""; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + INFOPLIST_FILE = "Target Support Files/Pods-pro-serviceUITests/Info.plist"; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + IPHONEOS_DEPLOYMENT_TARGET = 10.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + MACH_O_TYPE = staticlib; + MODULEMAP_FILE = "Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests.modulemap"; + OTHER_LDFLAGS = ""; + OTHER_LIBTOOLFLAGS = ""; + PODS_ROOT = "$(SRCROOT)"; + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.${PRODUCT_NAME:rfc1034identifier}"; + PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 16CB1A9EB87C68770618FC6C8C691614 /* Build configuration list for PBXNativeTarget "Pods-pro-serviceUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + ED2FA016634303AC113EB890061CCF0E /* Debug */, + 8993A6CDE948E4921080844F4C3CC9CA /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 2D8E8EC45A3A1A1D94AE762CB5028504 /* Build configuration list for PBXProject "Pods" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 553022A828EE1991F07D2D73F565AEF8 /* Debug */, + 58CE816B060A41D32CEC095441D0E3E0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4ADD88BFC2372F007AF2FCE0E98AA401 /* Build configuration list for PBXNativeTarget "FSCalendar+Persian" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + DCE9C796F0B86F18C88EB3D774D6FEC9 /* Debug */, + 065EB6ED66ADE49CF75A74056307B567 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B23EA3024A904EA0B9286700D2F0A17D /* Build configuration list for PBXNativeTarget "SPStorkController" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + C733F3E4D32580F7B820C7214B6740A4 /* Debug */, + DFF7344E3D8BF8FCE39656FEECEF15C4 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + C13341F7E83A23FC0349584F5A29F743 /* Build configuration list for PBXNativeTarget "Pods-pro-service" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9833B0D7AB29AC25615DF40EA5CEFD0E /* Debug */, + 5A1DDE4919971D8D9B952CBF117E163A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F9FF4776B50A61BD49939E6F3AB4F85F /* Build configuration list for PBXNativeTarget "Pods-pro-serviceTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9CD4D47B45FE260821AE10B47C8A1C6A /* Debug */, + 6732521AE73E3B404876A3D3626A3056 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = D41D8CD98F00B204E9800998ECF8427E /* Project object */; +} diff --git a/Pods/Pods.xcodeproj/xcuserdata/.xcuserdatad/xcschemes/FSCalendar+Persian.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/.xcuserdatad/xcschemes/FSCalendar+Persian.xcscheme new file mode 100644 index 0000000..38add8b --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/.xcuserdatad/xcschemes/FSCalendar+Persian.xcscheme @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/.xcuserdatad/xcschemes/Pods-pro-service.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/.xcuserdatad/xcschemes/Pods-pro-service.xcscheme new file mode 100644 index 0000000..e63abe9 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/.xcuserdatad/xcschemes/Pods-pro-service.xcscheme @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/.xcuserdatad/xcschemes/Pods-pro-serviceTests.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/.xcuserdatad/xcschemes/Pods-pro-serviceTests.xcscheme new file mode 100644 index 0000000..67fbe87 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/.xcuserdatad/xcschemes/Pods-pro-serviceTests.xcscheme @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/.xcuserdatad/xcschemes/Pods-pro-serviceUITests.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/.xcuserdatad/xcschemes/Pods-pro-serviceUITests.xcscheme new file mode 100644 index 0000000..3f8a789 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/.xcuserdatad/xcschemes/Pods-pro-serviceUITests.xcscheme @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/.xcuserdatad/xcschemes/SPStorkController.xcscheme b/Pods/Pods.xcodeproj/xcuserdata/.xcuserdatad/xcschemes/SPStorkController.xcscheme new file mode 100644 index 0000000..6e75ef3 --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/.xcuserdatad/xcschemes/SPStorkController.xcscheme @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/.xcuserdatad/xcschemes/xcschememanagement.plist b/Pods/Pods.xcodeproj/xcuserdata/.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..7768c1c --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,36 @@ + + + + + SchemeUserState + + FSCalendar+Persian.xcscheme + + isShown + + + Pods-pro-service.xcscheme + + isShown + + + Pods-pro-serviceTests.xcscheme + + isShown + + + Pods-pro-serviceUITests.xcscheme + + isShown + + + SPStorkController.xcscheme + + isShown + + + + SuppressBuildableAutocreation + + + diff --git a/Pods/Pods.xcodeproj/xcuserdata/alex.xcuserdatad/xcschemes/xcschememanagement.plist b/Pods/Pods.xcodeproj/xcuserdata/alex.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..99c268c --- /dev/null +++ b/Pods/Pods.xcodeproj/xcuserdata/alex.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,34 @@ + + + + + SchemeUserState + + FSCalendar+Persian.xcscheme_^#shared#^_ + + orderHint + 1 + + Pods-pro-service.xcscheme_^#shared#^_ + + orderHint + 2 + + Pods-pro-serviceTests.xcscheme_^#shared#^_ + + orderHint + 3 + + Pods-pro-serviceUITests.xcscheme_^#shared#^_ + + orderHint + 4 + + SPStorkController.xcscheme_^#shared#^_ + + orderHint + 5 + + + + diff --git a/Pods/SPStorkController/LICENSE b/Pods/SPStorkController/LICENSE new file mode 100644 index 0000000..bf03898 --- /dev/null +++ b/Pods/SPStorkController/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2018 Ivan Vorobei + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Pods/SPStorkController/README.md b/Pods/SPStorkController/README.md new file mode 100644 index 0000000..63320b4 --- /dev/null +++ b/Pods/SPStorkController/README.md @@ -0,0 +1,332 @@ +# SPStorkController + +Very similar to the modal **controller displayed in Apple Music, Podcasts and Mail** apps. Customizable height of view. Check scroll's bounce for more interactive. Simple adding close button and centering arrow indicator. You can download example [Debts - Spending tracker](https://itunes.apple.com/app/id1446635818) or [Code - Learn Swift & Design](https://itunes.apple.com/app/id1453325619) apps from AppStore. If you like the project, do not forget to **put star ★** + +### Preview + + + +Alert you can find in [SPAlert](https://github.com/IvanVorobei/SPAlert) project. If you want to **buy source code** of app in preview, please, go to [xcode-shop.com](https://xcode-shop.com). + +## Navigate + +- [Requirements](#requirements) +- [Installation](#installation) +- [Quick Start](#quick-start) +- [Usage](#usage) + - [Light StatusBar](#light-statusbar) + - [Custom Height](#custom-height) + - [Close Button](#close-button) + - [Indicator](#indicator) + - [Dismissing](#dismissing) + - [Corner Radius](#corner-radius) + - [Haptic](#haptic) + - [Snapshots](#snapshots) + - [Add Navigation Bar](#add-navigation-bar) + - [Working with UIScrollView](#working-with-uiscrollview) + - [UITableView & UICollectionView](#working-with-uitableview--uicollectionview) + - [Delegate](#delegate) +- [Video Tutorial](#video-tutorial) +- [Other Projects (+gif)](#my-projects) + - [SPAlert](#spalert) + - [SPLarkController](#splarkcontroller) + - [SPPermission](#sppermission) + - [Xcode Shop](#xcode-shop) +- [License](#license) +- [Contact or Order Develop](#contact) + +## Requirements + +Swift 4.2 & **5.0**. Ready for use on iOS 10+ + +## Installation + +### CocoaPods: + +[CocoaPods](https://cocoapods.org) is a dependency manager for Cocoa projects. For usage and installation instructions, visit their website. To integrate `SPStorkController` into your Xcode project using CocoaPods, specify it in your `Podfile`: + +```ruby +pod 'SPStorkController' +``` + +### Carthage + +[Carthage](https://github.com/Carthage/Carthage) is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks. To integrate `SPStorkController` into your Xcode project using Carthage, specify it in your `Cartfile`: + +```ogdl +github "IvanVorobei/SPStorkController" +``` + +### Manually + +If you prefer not to use any of the aforementioned dependency managers, you can integrate `SPStorkController` into your project manually. Put `Source/SPStorkController` folder in your Xcode project. Make sure to enable `Copy items if needed` and `Create groups`. + +## Quick Start + +Create controller and call func `presentAsStork`: + +```swift +import UIKit +import SPStorkController + +class ViewController: UIViewController { + + override func viewDidAppear(_ animated: Bool) { + super.viewDidAppear(animated) + + let controller = UIViewController() + self.presentAsStork(controller) + } +} +``` + +If you want customize controller (remove indicator, set custom height and other), create controller and set `transitioningDelegate` to `SPStorkTransitioningDelegate` object. Use `present` or `dismiss` functions: + +```swift +let controller = UIViewController() +let transitionDelegate = SPStorkTransitioningDelegate() +controller.transitioningDelegate = transitionDelegate +controller.modalPresentationStyle = .custom +controller.modalPresentationCapturesStatusBarAppearance = true +self.present(controller, animated: true, completion: nil) +``` + +Please, do not init `SPStorkTransitioningDelegate` like this: + +```swift +controller.transitioningDelegate = SPStorkTransitioningDelegate() +``` + +You will get an error about weak property. + +## Usage + +### Light StatusBar + +To set light status bar for presented controller, use `preferredStatusBarStyle` property. Also set `modalPresentationCapturesStatusBarAppearance`. See example: + +```swift +import UIKit + +class ModalViewController: UIViewController { + + override var preferredStatusBarStyle: UIStatusBarStyle { + return .lightContent + } +} +``` + +### Custom Height + +Property `customHeight` sets custom height for controller. Default is `nil`: + +```swift +transitionDelegate.customHeight = 350 +``` + +### Close Button + +Property `showCloseButton` added circle button with dismiss action. Default is `false`: +```swift +transitionDelegate.showCloseButton = false +``` + +### Indicator + +On the top of controller you can add arrow indicator with animatable states. It simple configure. +Property `showIndicator` shows or hides top arrow indicator. Default is `true`: + +```swift +transitionDelegate.showIndicator = true +``` + +Property Parameter `indicatorColor` for customize color of arrow. Default is `gray`: + +```swift +transitionDelegate.indicatorColor = UIColor.white +``` + +Property `hideIndicatorWhenScroll` shows or hides indicator when scrolling. Default is `false`: + +```swift +transitionDelegate.hideIndicatorWhenScroll = true +``` + +### Dismissing + +You can also configure events that will dimiss the controller. +Property `swipeToDismissEnabled` enables dismissal by swipe gesture. Default is `true`: + +```swift +transitionDelegate.swipeToDismissEnabled = true +``` + +Property `translateForDismiss` sets how much need to swipe down to close the controller. Work only if `swipeToDismissEnabled` is true. Default is `240`: + +```swift +transitionDelegate.translateForDismiss = 100 +``` + +Property `tapAroundToDismissEnabled` enables dismissal by tapping parent controller. Default is `true`: + +```swift +transitionDelegate.tapAroundToDismissEnabled = true +``` + +### Corner Radius + +Property `cornerRadius` for customize corner radius of controller's view. Default is `10`: + +```swift +transitionDelegate.cornerRadius = 10 +``` + +### Haptic + +Property `hapticMoments` allow add taptic feedback for some moments. Default is `.willDismissIfRelease`: + +```swift +transitionDelegate.hapticMoments = [.willPresent, .willDismiss] +``` + +### Snapshots + +The project uses a snapshot of the screen in order to avoid compatibility and customisation issues. Before controller presentation, a snapshot of the parent view is made, and size and position are changed for the snapshot. Sometimes you will need to update the screenshot of the parent view, for that use static func: + +```swift +SPStorkController.updatePresentingController(modal: controller) +``` + +and pass the controller, which is modal and uses `SPStorkTransitioningDelegate`. + +### Add Navigation Bar + +You may want to add a navigation bar to your modal controller. Since it became impossible to change or customize the native controller in swift 4 (I couldn’t even find a way to change the height of the bar), I had to recreate navigation bar from the ground up. Visually it looks real, but it doesn’t execute the necessary functions: + +```swift +import UIKit +import SPFakeBar + +class ModalController: UIViewController { + + let navBar = SPFakeBarView(style: .stork) + + override func viewDidLoad() { + super.viewDidLoad() + + self.view.backgroundColor = UIColor.white + + self.navBar.titleLabel.text = "Title" + self.navBar.leftButton.setTitle("Cancel", for: .normal) + self.navBar.leftButton.addTarget(self, action: #selector(self.dismissAction), for: .touchUpInside) + + self.view.addSubview(self.navBar) + } +} +``` + +You only need to add a navigation bar to the main view, it will automatically layout. Use style `.stork` in init of `SPFakeBarView`. Here is visual preview with Navigation Bar and without it: + + + +To use it, you need to install [SPFakeBar](https://github.com/IvanVorobei/SPFakeBar) pod: + +```ruby +pod 'SPFakeBar' +``` + +### Working with UIScrollView + +If you use `UIScrollView` (or UITableView & UICollectionView) on controller, I recommend making it more interactive. When scrolling reaches the top position, the controller will interactively drag down, simulating a closing animation. Also available close controller by drag down on `UIScrollView`. To do this, set the delegate and in the function `scrollViewDidScroll` call: + +```swift +func scrollViewDidScroll(_ scrollView: UIScrollView) { + SPStorkController.scrollViewDidScroll(scrollView) +} +``` + +### Working with UITableView & UICollectionView + +Working with a collections classes is not difficult. In the `Example` folder you can find an implementation. However, I will give a couple of tips for making the table look better. + +Firstly, if you use `SPFakeBarView`, don't forget to set top insets for content & scroll indicator. Also, I recommend setting bottom insets (it optional): + +```swift +tableView.contentInset.top = self.navBar.height +tableView.scrollIndicatorInsets.top = self.navBar.height +``` + +Please, also use `SPStorkController.scrollViewDidScroll` function in scroll delegate for more interactiveness with your collection or table view. + +### Delegate + +You can check events by implement `SPStorkControllerDelegate` and set delegate for `transitionDelegate`: + +```swift +transitionDelegate.storkDelegate = self +``` + +Delagate has this functions: + +```swift +protocol SPStorkControllerDelegate: class { + + optional func didDismissStorkBySwipe() + + optional func didDismissStorkByTap() +} +``` + +### Modal presentation of other controller + +If you want to present modal controller on SPStorkController, please set: + +```swift +controller.modalPresentationStyle = .custom +``` + +It’s needed for correct presentation and dismissal of all modal controllers. + +## Video Tutorial + +You can see how to use `SPStorkController` and how to customize it [in this video](https://youtu.be/wOTNGswT2-0). For English speakers I’ve added subtitles, don’t forget to turn them on: + +[![Tutorial on YouTube](https://github.com/IvanVorobei/SPStorkController/blob/master/Resources/YouTube.jpg)](https://youtu.be/wOTNGswT2-0) + +## My projects + +### SPAlert + +Native popup [SPAlert](https://github.com/IvanVorobei/SPAlert) is **similar to Apple Music or Feedback in AppStore** app. Support animations. I tried to repeat Apple alert as much as possible. + +

+ + + +

+ +You can download example app [Debts - Spending tracker](https://itunes.apple.com/app/id1446635818) from AppStore. If you want to **buy source code** of example apps, please, go to [xcode-shop.com](https://xcode-shop.com). + +### SPLarkController + +[SPLarkController](https://github.com/IvanVorobei/SPLarkController) make **settings screen** for your application. You can add **buttons and switches**. The amount cells is not limited. You can start using project with just two lines of code and easy customisation. + + + +You can download [Code - Learn Swift & Design](https://itunes.apple.com/app/id1453325619) app, which uses `SPLarkController`. Also you can **buy source code** of this app on [xcode-shop.com](https://xcode-shop.com). + +### SPPermission + +[SPPermission](https://github.com/IvanVorobei/SPPermission) allow request permissions **with native dialog** UI and interactive animations. Also you can request permissions without dialog. Check state any permission. You can start using this project with just two lines of code and easy customisation. + + + +### Xcode Shop + +If you want **buy apps with source code**, you can visit my [xcode-shop.com](https://xcode-shop.com). Here I am sale apps, modules, 3D elements and other. In applications you can find many cool UI that will be useful for your projects. Also by buying, **you support me** and my free GitHub development. + +## License +`SPStorkController` is released under the MIT license. Check `LICENSE.md` for details. + +## Contact +If you need any application or UI to be developed, message me at hello@ivanvorobei.by or via [telegram](https://t.me/ivanvorobei). I develop iOS apps and designs. I use `swift` for development. To request more functionality, you should create a new issue. You can see my [apps in AppStore](https://itunes.apple.com/developer/id1446635817). diff --git a/Pods/SPStorkController/Source/SPStorkController/CodeDraw/SPStorkCodeDraw.swift b/Pods/SPStorkController/Source/SPStorkController/CodeDraw/SPStorkCodeDraw.swift new file mode 100644 index 0000000..6209263 --- /dev/null +++ b/Pods/SPStorkController/Source/SPStorkController/CodeDraw/SPStorkCodeDraw.swift @@ -0,0 +1,88 @@ +import UIKit + +class SPStorkCodeDraw : NSObject { + + private struct Cache { + static let gradient: CGGradient = CGGradient(colorsSpace: nil, colors: [UIColor.red.cgColor, UIColor.red.cgColor] as CFArray, locations: [0, 1])! + } + + @objc dynamic class var gradient: CGGradient { return Cache.gradient } + + @objc dynamic class func drawClose(frame targetFrame: CGRect = CGRect(x: 0, y: 0, width: 100, height: 100), resizing: ResizingBehavior = .aspectFit, color: UIColor = UIColor(red: 0.000, green: 0.000, blue: 0.000, alpha: 1.000)) { + + let context = UIGraphicsGetCurrentContext()! + + context.saveGState() + let resizedFrame: CGRect = resizing.apply(rect: CGRect(x: 0, y: 0, width: 100, height: 100), target: targetFrame) + context.translateBy(x: resizedFrame.minX, y: resizedFrame.minY) + context.scaleBy(x: resizedFrame.width / 100, y: resizedFrame.height / 100) + + let bezierPath = UIBezierPath() + bezierPath.move(to: CGPoint(x: 92.02, y: 22.92)) + bezierPath.addLine(to: CGPoint(x: 64.42, y: 50.52)) + bezierPath.addLine(to: CGPoint(x: 92.02, y: 78.13)) + bezierPath.addCurve(to: CGPoint(x: 92.02, y: 92.99), controlPoint1: CGPoint(x: 96.13, y: 82.23), controlPoint2: CGPoint(x: 96.13, y: 88.89)) + bezierPath.addCurve(to: CGPoint(x: 84.59, y: 96.07), controlPoint1: CGPoint(x: 89.97, y: 95.05), controlPoint2: CGPoint(x: 87.28, y: 96.07)) + bezierPath.addCurve(to: CGPoint(x: 77.16, y: 92.99), controlPoint1: CGPoint(x: 81.9, y: 96.07), controlPoint2: CGPoint(x: 79.22, y: 95.05)) + bezierPath.addLine(to: CGPoint(x: 49.55, y: 65.38)) + bezierPath.addLine(to: CGPoint(x: 21.95, y: 92.99)) + bezierPath.addCurve(to: CGPoint(x: 14.51, y: 96.07), controlPoint1: CGPoint(x: 19.89, y: 95.05), controlPoint2: CGPoint(x: 17.2, y: 96.07)) + bezierPath.addCurve(to: CGPoint(x: 7.08, y: 92.99), controlPoint1: CGPoint(x: 11.82, y: 96.07), controlPoint2: CGPoint(x: 9.13, y: 95.05)) + bezierPath.addCurve(to: CGPoint(x: 7.08, y: 78.13), controlPoint1: CGPoint(x: 2.97, y: 88.89), controlPoint2: CGPoint(x: 2.97, y: 82.23)) + bezierPath.addLine(to: CGPoint(x: 34.69, y: 50.52)) + bezierPath.addLine(to: CGPoint(x: 7.08, y: 22.92)) + bezierPath.addCurve(to: CGPoint(x: 7.08, y: 8.04), controlPoint1: CGPoint(x: 2.97, y: 18.8), controlPoint2: CGPoint(x: 2.97, y: 12.15)) + bezierPath.addCurve(to: CGPoint(x: 21.94, y: 8.04), controlPoint1: CGPoint(x: 11.18, y: 3.94), controlPoint2: CGPoint(x: 17.84, y: 3.94)) + bezierPath.addLine(to: CGPoint(x: 49.55, y: 35.65)) + bezierPath.addLine(to: CGPoint(x: 77.16, y: 8.04)) + bezierPath.addCurve(to: CGPoint(x: 92.02, y: 8.04), controlPoint1: CGPoint(x: 81.26, y: 3.94), controlPoint2: CGPoint(x: 87.92, y: 3.94)) + bezierPath.addCurve(to: CGPoint(x: 92.02, y: 22.92), controlPoint1: CGPoint(x: 96.13, y: 12.15), controlPoint2: CGPoint(x: 96.13, y: 18.8)) + bezierPath.close() + color.setFill() + bezierPath.fill() + + context.restoreGState() + + } + + @objc(StyleKitNameResizingBehavior) + enum ResizingBehavior: Int { + case aspectFit + case aspectFill + case stretch + case center + + func apply(rect: CGRect, target: CGRect) -> CGRect { + if rect == target || target == CGRect.zero { + return rect + } + + var scales = CGSize.zero + scales.width = abs(target.width / rect.width) + scales.height = abs(target.height / rect.height) + + switch self { + case .aspectFit: + scales.width = min(scales.width, scales.height) + scales.height = scales.width + case .aspectFill: + scales.width = max(scales.width, scales.height) + scales.height = scales.width + case .stretch: + break + case .center: + scales.width = 1 + scales.height = 1 + } + + var result = rect.standardized + result.size.width *= scales.width + result.size.height *= scales.height + result.origin.x = target.minX + (target.width - result.width) / 2 + result.origin.y = target.minY + (target.height - result.height) / 2 + return result + } + } + + private override init() {} +} diff --git a/Pods/SPStorkController/Source/SPStorkController/Extenshion/SPStorkViewControllerExtenshion.swift b/Pods/SPStorkController/Source/SPStorkController/Extenshion/SPStorkViewControllerExtenshion.swift new file mode 100755 index 0000000..e34f465 --- /dev/null +++ b/Pods/SPStorkController/Source/SPStorkController/Extenshion/SPStorkViewControllerExtenshion.swift @@ -0,0 +1,51 @@ +// The MIT License (MIT) +// Copyright © 2017 Ivan Vorobei (hello@ivanvorobei.by) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import UIKit + +extension UIViewController { + + public var isPresentedAsStork: Bool { + return transitioningDelegate is SPStorkTransitioningDelegate + && modalPresentationStyle == .custom + && presentingViewController != nil + } + + public func presentAsStork(_ controller: UIViewController, height: CGFloat? = nil) { + let transitionDelegate = SPStorkTransitioningDelegate() + transitionDelegate.customHeight = height + controller.transitioningDelegate = transitionDelegate + controller.modalPresentationStyle = .custom + controller.modalPresentationCapturesStatusBarAppearance = true + self.present(controller, animated: true, completion: nil) + } + + public func presentAsStork(_ controller: UIViewController, height: CGFloat?, showIndicator: Bool, showCloseButton: Bool, complection: (() -> Void)? = nil) { + let transitionDelegate = SPStorkTransitioningDelegate() + transitionDelegate.customHeight = height + transitionDelegate.showCloseButton = showCloseButton + transitionDelegate.showIndicator = showIndicator + controller.transitioningDelegate = transitionDelegate + controller.modalPresentationStyle = .custom + controller.modalPresentationCapturesStatusBarAppearance = true + self.present(controller, animated: true, completion: complection) + } +} diff --git a/Pods/SPStorkController/Source/SPStorkController/Models/SPStorkHaptic.swift b/Pods/SPStorkController/Source/SPStorkController/Models/SPStorkHaptic.swift new file mode 100644 index 0000000..22ed10b --- /dev/null +++ b/Pods/SPStorkController/Source/SPStorkController/Models/SPStorkHaptic.swift @@ -0,0 +1,29 @@ +// The MIT License (MIT) +// Copyright © 2017 Ivan Vorobei (hello@ivanvorobei.by) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import UIKit + +public enum SPStorkHapticMoments { + + case willPresent + case willDismiss + case willDismissIfRelease +} diff --git a/Pods/SPStorkController/Source/SPStorkController/Protocols/SPStorkControllerDelegate.swift b/Pods/SPStorkController/Source/SPStorkController/Protocols/SPStorkControllerDelegate.swift new file mode 100644 index 0000000..9c1c681 --- /dev/null +++ b/Pods/SPStorkController/Source/SPStorkController/Protocols/SPStorkControllerDelegate.swift @@ -0,0 +1,29 @@ +// The MIT License (MIT) +// Copyright © 2017 Ivan Vorobei (hello@ivanvorobei.by) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import UIKit + +@objc public protocol SPStorkControllerDelegate: class { + + @objc optional func didDismissStorkBySwipe() + + @objc optional func didDismissStorkByTap() +} diff --git a/Pods/SPStorkController/Source/SPStorkController/SPStorkController.swift b/Pods/SPStorkController/Source/SPStorkController/SPStorkController.swift new file mode 100755 index 0000000..f417606 --- /dev/null +++ b/Pods/SPStorkController/Source/SPStorkController/SPStorkController.swift @@ -0,0 +1,86 @@ +// The MIT License (MIT) +// Copyright © 2017 Ivan Vorobei (hello@ivanvorobei.by) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import UIKit + +public struct SPStorkController { + + static public func scrollViewDidScroll(_ scrollView: UIScrollView) { + if let controller = self.controller(for: scrollView) { + if let presentationController = controller.presentationController as? SPStorkPresentationController { + let translation = -(scrollView.contentOffset.y + scrollView.contentInset.top) + if translation >= 0 { + if controller.isBeingPresented { return } + scrollView.subviews.forEach { + $0.transform = CGAffineTransform(translationX: 0, y: -translation) + } + presentationController.setIndicator(style: scrollView.isTracking ? .line : .arrow) + if translation >= presentationController.translateForDismiss * 0.4 { + if !scrollView.isTracking && !scrollView.isDragging { + presentationController.presentedViewController.dismiss(animated: true, completion: { + presentationController.storkDelegate?.didDismissStorkBySwipe?() + }) + return + } + } + if presentationController.pan?.state != UIGestureRecognizer.State.changed { + presentationController.scrollViewDidScroll(translation * 2) + } + } else { + presentationController.setIndicator(style: .arrow) + presentationController.scrollViewDidScroll(0) + } + + if translation < -5 { + presentationController.setIndicator(visible: false, forse: (translation < -50)) + } else { + presentationController.setIndicator(visible: true, forse: false) + } + } + } + } + + static public var topScrollIndicatorInset: CGFloat { + return 6 + } + + static public func updatePresentingController(parent controller: UIViewController) { + if let presentationController = controller.presentedViewController?.presentationController as? SPStorkPresentationController { + presentationController.updatePresentingController() + } + } + + static public func updatePresentingController(modal controller: UIViewController) { + if let presentationController = controller.presentationController as? SPStorkPresentationController { + presentationController.updatePresentingController() + } + } + + static private func controller(for view: UIView) -> UIViewController? { + var nextResponder = view.next + while nextResponder != nil && !(nextResponder! is UIViewController) { + nextResponder = nextResponder!.next + } + return nextResponder as? UIViewController + } + + private init() {} +} diff --git a/Pods/SPStorkController/Source/SPStorkController/TransitioningDelegate/SPStorkDismissingAnimationController.swift b/Pods/SPStorkController/Source/SPStorkController/TransitioningDelegate/SPStorkDismissingAnimationController.swift new file mode 100755 index 0000000..9e13701 --- /dev/null +++ b/Pods/SPStorkController/Source/SPStorkController/TransitioningDelegate/SPStorkDismissingAnimationController.swift @@ -0,0 +1,54 @@ +// The MIT License (MIT) +// Copyright © 2017 Ivan Vorobei (hello@ivanvorobei.by) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import UIKit + +final class SPStorkDismissingAnimationController: NSObject, UIViewControllerAnimatedTransitioning { + + func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { + + guard let presentedViewController = transitionContext.viewController(forKey: .from) else { + return + } + + let finalFrameForPresentedView = transitionContext.finalFrame(for: presentedViewController) + + let containerView = transitionContext.containerView + let offscreenFrame = CGRect(x: 0, y: containerView.bounds.height, width: finalFrameForPresentedView.width, height: finalFrameForPresentedView.height) + + UIView.animate( + withDuration: transitionDuration(using: transitionContext), + delay: 0, + usingSpringWithDamping: 1, + initialSpringVelocity: 1, + options: .curveEaseIn, + animations: { + presentedViewController.view.frame = offscreenFrame + }) { finished in + transitionContext.completeTransition(finished) + } + } + + func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { + return 0.6 + } +} + diff --git a/Pods/SPStorkController/Source/SPStorkController/TransitioningDelegate/SPStorkPresentationController.swift b/Pods/SPStorkController/Source/SPStorkController/TransitioningDelegate/SPStorkPresentationController.swift new file mode 100755 index 0000000..9a51d6c --- /dev/null +++ b/Pods/SPStorkController/Source/SPStorkController/TransitioningDelegate/SPStorkPresentationController.swift @@ -0,0 +1,525 @@ +// The MIT License (MIT) +// Copyright © 2017 Ivan Vorobei (hello@ivanvorobei.by) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import UIKit + +class SPStorkPresentationController: UIPresentationController, UIGestureRecognizerDelegate { + + var swipeToDismissEnabled: Bool = true + var tapAroundToDismissEnabled: Bool = true + var showCloseButton: Bool = false + var showIndicator: Bool = true + var indicatorColor: UIColor = UIColor.init(red: 202/255, green: 201/255, blue: 207/255, alpha: 1) + var hideIndicatorWhenScroll: Bool = false + var customHeight: CGFloat? = nil + var translateForDismiss: CGFloat = 200 + var hapticMoments: [SPStorkHapticMoments] = [.willDismissIfRelease] + + var transitioningDelegate: SPStorkTransitioningDelegate? + weak var storkDelegate: SPStorkControllerDelegate? + + var pan: UIPanGestureRecognizer? + var tap: UITapGestureRecognizer? + + private var closeButton = SPStorkCloseButton() + private var indicatorView = SPStorkIndicatorView() + private var gradeView: UIView = UIView() + private let snapshotViewContainer = UIView() + private var snapshotView: UIView? + private let backgroundView = UIView() + + private var snapshotViewTopConstraint: NSLayoutConstraint? + private var snapshotViewWidthConstraint: NSLayoutConstraint? + private var snapshotViewAspectRatioConstraint: NSLayoutConstraint? + + private var workGester: Bool = false + private var startDismissing: Bool = false + private var afterReleaseDismissing: Bool = false + + private var topSpace: CGFloat { + let statusBarHeight: CGFloat = UIApplication.shared.statusBarFrame.height + return (statusBarHeight < 25) ? 30 : statusBarHeight + } + + private let alpha: CGFloat = 0.51 + var cornerRadius: CGFloat = 10 + + private var scaleForPresentingView: CGFloat { + guard let containerView = containerView else { return 0 } + let factor = 1 - ((self.cornerRadius + 3) * 2 / containerView.frame.width) + return factor + } + + private var feedbackGenerator: UIImpactFeedbackGenerator = UIImpactFeedbackGenerator(style: .light) + + override var presentedView: UIView? { + let view = self.presentedViewController.view + if view?.frame.origin == CGPoint.zero { + view?.frame = self.frameOfPresentedViewInContainerView + } + return view + } + + override var frameOfPresentedViewInContainerView: CGRect { + guard let containerView = containerView else { return .zero } + let baseY: CGFloat = self.topSpace + 13 + let maxHeight: CGFloat = containerView.bounds.height - baseY + var height: CGFloat = maxHeight + + if let customHeight = self.customHeight { + if customHeight < maxHeight { + height = customHeight + } else { + print("SPStorkController - Custom height change to default value. Your height more maximum value") + } + } + return CGRect(x: 0, y: containerView.bounds.height - height, width: containerView.bounds.width, height: height) + } + + override func presentationTransitionWillBegin() { + super.presentationTransitionWillBegin() + + if !self.hapticMoments.isEmpty { + self.feedbackGenerator.prepare() + } + + guard let containerView = self.containerView, let presentedView = self.presentedView, let window = containerView.window else { return } + + if self.showIndicator { + self.indicatorView.color = self.indicatorColor + let tap = UITapGestureRecognizer.init(target: self, action: #selector(self.dismissAction)) + tap.cancelsTouchesInView = false + self.indicatorView.addGestureRecognizer(tap) + presentedView.addSubview(self.indicatorView) + } + self.updateLayoutIndicator() + self.indicatorView.style = .arrow + self.gradeView.alpha = 0 + + if self.showCloseButton { + self.closeButton.addTarget(self, action: #selector(self.dismissAction), for: .touchUpInside) + presentedView.addSubview(self.closeButton) + } + self.updateLayoutCloseButton() + + let initialFrame: CGRect = presentingViewController.isPresentedAsStork ? presentingViewController.view.frame : containerView.bounds + + containerView.insertSubview(self.snapshotViewContainer, belowSubview: presentedViewController.view) + self.snapshotViewContainer.frame = initialFrame + self.updateSnapshot() + self.snapshotView?.layer.cornerRadius = 0 + self.backgroundView.backgroundColor = UIColor.black + self.backgroundView.translatesAutoresizingMaskIntoConstraints = false + containerView.insertSubview(self.backgroundView, belowSubview: self.snapshotViewContainer) + NSLayoutConstraint.activate([ + self.backgroundView.topAnchor.constraint(equalTo: window.topAnchor), + self.backgroundView.leftAnchor.constraint(equalTo: window.leftAnchor), + self.backgroundView.rightAnchor.constraint(equalTo: window.rightAnchor), + self.backgroundView.bottomAnchor.constraint(equalTo: window.bottomAnchor) + ]) + + let transformForSnapshotView = CGAffineTransform.identity + .translatedBy(x: 0, y: -snapshotViewContainer.frame.origin.y) + .translatedBy(x: 0, y: self.topSpace) + .translatedBy(x: 0, y: -snapshotViewContainer.frame.height / 2) + .scaledBy(x: scaleForPresentingView, y: scaleForPresentingView) + .translatedBy(x: 0, y: snapshotViewContainer.frame.height / 2) + + self.addCornerRadiusAnimation(for: self.snapshotView, cornerRadius: self.cornerRadius, duration: 0.6) + self.snapshotView?.layer.masksToBounds = true + if #available(iOS 11.0, *) { + presentedView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] + } + presentedView.layer.cornerRadius = self.cornerRadius + presentedView.layer.masksToBounds = true + + var rootSnapshotView: UIView? + var rootSnapshotRoundedView: UIView? + + if presentingViewController.isPresentedAsStork { + guard let rootController = presentingViewController.presentingViewController, let snapshotView = rootController.view.snapshotView(afterScreenUpdates: false) else { return } + + containerView.insertSubview(snapshotView, aboveSubview: self.backgroundView) + snapshotView.frame = initialFrame + snapshotView.transform = transformForSnapshotView + snapshotView.alpha = 1 - self.alpha + snapshotView.layer.cornerRadius = self.cornerRadius + snapshotView.contentMode = .top + snapshotView.layer.masksToBounds = true + rootSnapshotView = snapshotView + + let snapshotRoundedView = UIView() + snapshotRoundedView.layer.cornerRadius = self.cornerRadius + snapshotRoundedView.layer.masksToBounds = true + containerView.insertSubview(snapshotRoundedView, aboveSubview: snapshotView) + snapshotRoundedView.frame = initialFrame + snapshotRoundedView.transform = transformForSnapshotView + rootSnapshotRoundedView = snapshotRoundedView + } + + presentedViewController.transitionCoordinator?.animate( + alongsideTransition: { [weak self] context in + guard let `self` = self else { return } + self.snapshotView?.transform = transformForSnapshotView + self.gradeView.alpha = self.alpha + }, completion: { _ in + self.snapshotView?.transform = .identity + rootSnapshotView?.removeFromSuperview() + rootSnapshotRoundedView?.removeFromSuperview() + }) + + if self.hapticMoments.contains(.willPresent) { + self.feedbackGenerator.impactOccurred() + } + } + + override func presentationTransitionDidEnd(_ completed: Bool) { + super.presentationTransitionDidEnd(completed) + guard let containerView = containerView else { return } + self.updateSnapshot() + self.presentedViewController.view.frame = self.frameOfPresentedViewInContainerView + self.snapshotViewContainer.transform = .identity + self.snapshotViewContainer.translatesAutoresizingMaskIntoConstraints = false + self.snapshotViewContainer.centerXAnchor.constraint(equalTo: containerView.centerXAnchor).isActive = true + self.updateSnapshotAspectRatio() + + if self.tapAroundToDismissEnabled { + self.tap = UITapGestureRecognizer.init(target: self, action: #selector(self.dismissAction)) + self.tap?.cancelsTouchesInView = false + self.snapshotViewContainer.addGestureRecognizer(self.tap!) + } + + if self.swipeToDismissEnabled { + self.pan = UIPanGestureRecognizer(target: self, action: #selector(self.handlePan)) + self.pan!.delegate = self + self.pan!.maximumNumberOfTouches = 1 + self.pan!.cancelsTouchesInView = false + self.presentedViewController.view.addGestureRecognizer(self.pan!) + } + } + + @objc func dismissAction() { + self.presentingViewController.view.endEditing(true) + self.presentedViewController.view.endEditing(true) + self.presentedViewController.dismiss(animated: true, completion: { + self.storkDelegate?.didDismissStorkByTap?() + }) + } + + override func dismissalTransitionWillBegin() { + super.dismissalTransitionWillBegin() + guard let containerView = containerView else { return } + self.startDismissing = true + + let initialFrame: CGRect = presentingViewController.isPresentedAsStork ? presentingViewController.view.frame : containerView.bounds + + let initialTransform = CGAffineTransform.identity + .translatedBy(x: 0, y: -initialFrame.origin.y) + .translatedBy(x: 0, y: self.topSpace) + .translatedBy(x: 0, y: -initialFrame.height / 2) + .scaledBy(x: scaleForPresentingView, y: scaleForPresentingView) + .translatedBy(x: 0, y: initialFrame.height / 2) + + self.snapshotViewTopConstraint?.isActive = false + self.snapshotViewWidthConstraint?.isActive = false + self.snapshotViewAspectRatioConstraint?.isActive = false + self.snapshotViewContainer.translatesAutoresizingMaskIntoConstraints = true + self.snapshotViewContainer.frame = initialFrame + self.snapshotViewContainer.transform = initialTransform + + let finalCornerRadius = presentingViewController.isPresentedAsStork ? self.cornerRadius : 0 + let finalTransform: CGAffineTransform = .identity + + self.addCornerRadiusAnimation(for: self.snapshotView, cornerRadius: finalCornerRadius, duration: 0.6) + + var rootSnapshotView: UIView? + var rootSnapshotRoundedView: UIView? + + if presentingViewController.isPresentedAsStork { + guard let rootController = presentingViewController.presentingViewController, let snapshotView = rootController.view.snapshotView(afterScreenUpdates: false) else { return } + + containerView.insertSubview(snapshotView, aboveSubview: backgroundView) + snapshotView.frame = initialFrame + snapshotView.transform = initialTransform + snapshotView.contentMode = .top + rootSnapshotView = snapshotView + snapshotView.layer.cornerRadius = self.cornerRadius + snapshotView.layer.masksToBounds = true + + let snapshotRoundedView = UIView() + snapshotRoundedView.layer.cornerRadius = self.cornerRadius + snapshotRoundedView.layer.masksToBounds = true + snapshotRoundedView.backgroundColor = UIColor.black.withAlphaComponent(self.alpha) + containerView.insertSubview(snapshotRoundedView, aboveSubview: snapshotView) + snapshotRoundedView.frame = initialFrame + snapshotRoundedView.transform = initialTransform + rootSnapshotRoundedView = snapshotRoundedView + } + + presentedViewController.transitionCoordinator?.animate( + alongsideTransition: { [weak self] context in + guard let `self` = self else { return } + self.snapshotView?.transform = .identity + self.snapshotViewContainer.transform = finalTransform + self.gradeView.alpha = 0 + if self.hapticMoments.contains(.willDismiss) { + self.feedbackGenerator.impactOccurred() + } + }, completion: { _ in + rootSnapshotView?.removeFromSuperview() + rootSnapshotRoundedView?.removeFromSuperview() + }) + } + + override func dismissalTransitionDidEnd(_ completed: Bool) { + super.dismissalTransitionDidEnd(completed) + guard let containerView = containerView else { return } + + self.backgroundView.removeFromSuperview() + self.snapshotView?.removeFromSuperview() + self.snapshotViewContainer.removeFromSuperview() + self.indicatorView.removeFromSuperview() + self.closeButton.removeFromSuperview() + + let offscreenFrame = CGRect(x: 0, y: containerView.bounds.height, width: containerView.bounds.width, height: containerView.bounds.height) + presentedViewController.view.frame = offscreenFrame + presentedViewController.view.transform = .identity + } +} + +extension SPStorkPresentationController { + + @objc func handlePan(gestureRecognizer: UIPanGestureRecognizer) { + guard gestureRecognizer.isEqual(self.pan), self.swipeToDismissEnabled else { return } + + switch gestureRecognizer.state { + case .began: + self.workGester = true + self.indicatorView.style = .line + self.presentingViewController.view.layer.removeAllAnimations() + self.presentingViewController.view.endEditing(true) + self.presentedViewController.view.endEditing(true) + gestureRecognizer.setTranslation(CGPoint(x: 0, y: 0), in: containerView) + case .changed: + self.workGester = true + let translation = gestureRecognizer.translation(in: presentedView) + if self.swipeToDismissEnabled { + self.updatePresentedViewForTranslation(inVerticalDirection: translation.y) + } else { + gestureRecognizer.setTranslation(.zero, in: presentedView) + } + case .ended: + self.workGester = false + let translation = gestureRecognizer.translation(in: presentedView).y + if translation >= self.translateForDismiss { + self.presentedViewController.dismiss(animated: true, completion: { + self.storkDelegate?.didDismissStorkBySwipe?() + }) + } else { + self.indicatorView.style = .arrow + UIView.animate( + withDuration: 0.6, + delay: 0, + usingSpringWithDamping: 1, + initialSpringVelocity: 1, + options: [.curveEaseOut, .allowUserInteraction], + animations: { + self.snapshotView?.transform = .identity + self.presentedView?.transform = .identity + self.gradeView.alpha = self.alpha + }) + } + default: + break + } + } + + func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool { + if let gester = gestureRecognizer as? UIPanGestureRecognizer { + let velocity = gester.velocity(in: self.presentedViewController.view) + return abs(velocity.y) > abs(velocity.x) + } + return true + } + + func scrollViewDidScroll(_ translation: CGFloat) { + if !self.workGester { + self.updatePresentedViewForTranslation(inVerticalDirection: translation) + } + } + + func updatePresentingController() { + if self.startDismissing { return } + self.updateSnapshot() + } + + func setIndicator(style: SPStorkIndicatorView.Style) { + self.indicatorView.style = style + } + + func setIndicator(visible: Bool, forse: Bool) { + guard self.hideIndicatorWhenScroll else { return } + let newAlpha: CGFloat = visible ? 1 : 0 + if forse { + self.indicatorView.layer.removeAllAnimations() + self.indicatorView.alpha = newAlpha + return + } + if self.indicatorView.alpha == newAlpha { + return + } + UIView.animate(withDuration: 0.18, animations: { + self.indicatorView.alpha = newAlpha + }) + } + + private func updatePresentedViewForTranslation(inVerticalDirection translation: CGFloat) { + if self.startDismissing { return } + + let elasticThreshold: CGFloat = 120 + let translationFactor: CGFloat = 1 / 2 + + if translation >= 0 { + let translationForModal: CGFloat = { + if translation >= elasticThreshold { + let frictionLength = translation - elasticThreshold + let frictionTranslation = 30 * atan(frictionLength / 120) + frictionLength / 10 + return frictionTranslation + (elasticThreshold * translationFactor) + } else { + return translation * translationFactor + } + }() + + self.presentedView?.transform = CGAffineTransform(translationX: 0, y: translationForModal) + + let scaleFactor = 1 + (translationForModal / 5000) + self.snapshotView?.transform = CGAffineTransform.init(scaleX: scaleFactor, y: scaleFactor) + let gradeFactor = 1 + (translationForModal / 7000) + self.gradeView.alpha = self.alpha - ((gradeFactor - 1) * 15) + } else { + self.presentedView?.transform = CGAffineTransform.identity + } + + if self.swipeToDismissEnabled { + let afterRealseDismissing = (translation >= self.translateForDismiss) + if afterRealseDismissing != self.afterReleaseDismissing { + self.afterReleaseDismissing = afterRealseDismissing + if self.hapticMoments.contains(.willDismissIfRelease) { + self.feedbackGenerator.impactOccurred() + } + } + } + } +} + +extension SPStorkPresentationController { + + override func containerViewWillLayoutSubviews() { + super.containerViewWillLayoutSubviews() + guard let containerView = containerView else { return } + self.updateSnapshotAspectRatio() + if presentedViewController.view.isDescendant(of: containerView) { + self.presentedViewController.view.frame = self.frameOfPresentedViewInContainerView + } + } + + override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { + super.viewWillTransition(to: size, with: coordinator) + coordinator.animate(alongsideTransition: { contex in + self.updateLayoutIndicator() + self.updateLayoutCloseButton() + }, completion: { [weak self] _ in + self?.updateSnapshotAspectRatio() + self?.updateSnapshot() + }) + } + + private func updateLayoutIndicator() { + guard let presentedView = self.presentedView else { return } + self.indicatorView.style = .line + self.indicatorView.sizeToFit() + self.indicatorView.frame.origin.y = 12 + self.indicatorView.center.x = presentedView.frame.width / 2 + } + + private func updateLayoutCloseButton() { + guard let presentedView = self.presentedView else { return } + self.closeButton.sizeToFit() + self.closeButton.layout(bottomX: presentedView.frame.width - 19, y: 19) + } + + private func updateSnapshot() { + guard let currentSnapshotView = presentingViewController.view.snapshotView(afterScreenUpdates: true) else { return } + self.snapshotView?.removeFromSuperview() + self.snapshotViewContainer.addSubview(currentSnapshotView) + self.constraints(view: currentSnapshotView, to: self.snapshotViewContainer) + self.snapshotView = currentSnapshotView + self.snapshotView?.layer.cornerRadius = self.cornerRadius + self.snapshotView?.layer.masksToBounds = true + if #available(iOS 11.0, *) { + snapshotView?.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] + } + self.gradeView.removeFromSuperview() + self.gradeView.backgroundColor = UIColor.black + self.snapshotView!.addSubview(self.gradeView) + self.constraints(view: self.gradeView, to: self.snapshotView!) + } + + private func updateSnapshotAspectRatio() { + guard let containerView = containerView, snapshotViewContainer.translatesAutoresizingMaskIntoConstraints == false else { return } + + self.snapshotViewTopConstraint?.isActive = false + self.snapshotViewWidthConstraint?.isActive = false + self.snapshotViewAspectRatioConstraint?.isActive = false + + let snapshotReferenceSize = presentingViewController.view.frame.size + let aspectRatio = snapshotReferenceSize.width / snapshotReferenceSize.height + + self.snapshotViewTopConstraint = snapshotViewContainer.topAnchor.constraint(equalTo: containerView.topAnchor, constant: self.topSpace) + self.snapshotViewWidthConstraint = snapshotViewContainer.widthAnchor.constraint(equalTo: containerView.widthAnchor, multiplier: scaleForPresentingView) + self.snapshotViewAspectRatioConstraint = snapshotViewContainer.widthAnchor.constraint(equalTo: snapshotViewContainer.heightAnchor, multiplier: aspectRatio) + + self.snapshotViewTopConstraint?.isActive = true + self.snapshotViewWidthConstraint?.isActive = true + self.snapshotViewAspectRatioConstraint?.isActive = true + } + + private func constraints(view: UIView, to superView: UIView) { + view.translatesAutoresizingMaskIntoConstraints = false + NSLayoutConstraint.activate([ + view.topAnchor.constraint(equalTo: superView.topAnchor), + view.leftAnchor.constraint(equalTo: superView.leftAnchor), + view.rightAnchor.constraint(equalTo: superView.rightAnchor), + view.bottomAnchor.constraint(equalTo: superView.bottomAnchor) + ]) + } + + private func addCornerRadiusAnimation(for view: UIView?, cornerRadius: CGFloat, duration: CFTimeInterval) { + guard let view = view else { return } + let animation = CABasicAnimation(keyPath:"cornerRadius") + animation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeOut) + animation.fromValue = view.layer.cornerRadius + animation.toValue = cornerRadius + animation.duration = duration + view.layer.add(animation, forKey: "cornerRadius") + view.layer.cornerRadius = cornerRadius + } +} diff --git a/Pods/SPStorkController/Source/SPStorkController/TransitioningDelegate/SPStorkPresentingAnimationController.swift b/Pods/SPStorkController/Source/SPStorkController/TransitioningDelegate/SPStorkPresentingAnimationController.swift new file mode 100755 index 0000000..edeb78b --- /dev/null +++ b/Pods/SPStorkController/Source/SPStorkController/TransitioningDelegate/SPStorkPresentingAnimationController.swift @@ -0,0 +1,54 @@ +// The MIT License (MIT) +// Copyright © 2017 Ivan Vorobei (hello@ivanvorobei.by) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import UIKit + +final class SPStorkPresentingAnimationController: NSObject, UIViewControllerAnimatedTransitioning { + + func animateTransition(using transitionContext: UIViewControllerContextTransitioning) { + + guard let presentedViewController = transitionContext.viewController(forKey: .to) else { return } + + let containerView = transitionContext.containerView + containerView.addSubview(presentedViewController.view) + + let finalFrameForPresentedView = transitionContext.finalFrame(for: presentedViewController) + presentedViewController.view.frame = finalFrameForPresentedView + presentedViewController.view.frame.origin.y = containerView.bounds.height + + UIView.animate( + withDuration: transitionDuration(using: transitionContext), + delay: 0, + usingSpringWithDamping: 1, + initialSpringVelocity: 1, + options: .curveEaseOut, + animations: { + presentedViewController.view.frame = finalFrameForPresentedView + }, completion: { finished in + transitionContext.completeTransition(finished) + }) + } + + func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval { + return 0.6 + } +} + diff --git a/Pods/SPStorkController/Source/SPStorkController/TransitioningDelegate/SPStorkTransitioningDelegate.swift b/Pods/SPStorkController/Source/SPStorkController/TransitioningDelegate/SPStorkTransitioningDelegate.swift new file mode 100755 index 0000000..3e402ed --- /dev/null +++ b/Pods/SPStorkController/Source/SPStorkController/TransitioningDelegate/SPStorkTransitioningDelegate.swift @@ -0,0 +1,62 @@ +// The MIT License (MIT) +// Copyright © 2017 Ivan Vorobei (hello@ivanvorobei.by) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import UIKit + +public final class SPStorkTransitioningDelegate: NSObject, UIViewControllerTransitioningDelegate { + + public var swipeToDismissEnabled: Bool = true + public var tapAroundToDismissEnabled: Bool = true + public var showCloseButton: Bool = false + public var showIndicator: Bool = true + public var indicatorColor: UIColor = UIColor.init(red: 202/255, green: 201/255, blue: 207/255, alpha: 1) + public var hideIndicatorWhenScroll: Bool = false + public var customHeight: CGFloat? = nil + public var translateForDismiss: CGFloat = 200 + public var cornerRadius: CGFloat = 10 + public var hapticMoments: [SPStorkHapticMoments] = [.willDismissIfRelease] + public weak var storkDelegate: SPStorkControllerDelegate? = nil + + public func presentationController(forPresented presented: UIViewController, presenting: UIViewController?, source: UIViewController) -> UIPresentationController? { + let controller = SPStorkPresentationController(presentedViewController: presented, presenting: presenting) + controller.swipeToDismissEnabled = self.swipeToDismissEnabled + controller.tapAroundToDismissEnabled = self.tapAroundToDismissEnabled + controller.showCloseButton = self.showCloseButton + controller.showIndicator = self.showIndicator + controller.indicatorColor = self.indicatorColor + controller.hideIndicatorWhenScroll = self.hideIndicatorWhenScroll + controller.customHeight = self.customHeight + controller.translateForDismiss = self.translateForDismiss + controller.cornerRadius = self.cornerRadius + controller.hapticMoments = self.hapticMoments + controller.transitioningDelegate = self + controller.storkDelegate = self.storkDelegate + return controller + } + + public func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? { + return SPStorkPresentingAnimationController() + } + + public func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { + return SPStorkDismissingAnimationController() + } +} diff --git a/Pods/SPStorkController/Source/SPStorkController/Views/SPStorkCloseButton.swift b/Pods/SPStorkController/Source/SPStorkController/Views/SPStorkCloseButton.swift new file mode 100644 index 0000000..ee81ae0 --- /dev/null +++ b/Pods/SPStorkController/Source/SPStorkController/Views/SPStorkCloseButton.swift @@ -0,0 +1,78 @@ +// The MIT License (MIT) +// Copyright © 2017 Ivan Vorobei (hello@ivanvorobei.by) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import UIKit + +open class SPStorkCloseButton: UIButton { + + let iconView = SPStorkCloseView() + + var widthIconFactor: CGFloat = 1 + var heightIconFactor: CGFloat = 1 + + var color = UIColor.blue { + didSet { + self.iconView.color = self.color + } + } + + override open var isHighlighted: Bool { + didSet { + self.iconView.color = self.color.withAlphaComponent(self.isHighlighted ? 0.7 : 1) + } + } + + init() { + super.init(frame: .zero) + self.commonInit() + } + + required public init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + private func commonInit() { + self.iconView.isUserInteractionEnabled = false + self.addSubview(self.iconView) + self.backgroundColor = UIColor.init(red: 239 / 255.0, green: 239 / 255.0, blue: 244 / 255.0, alpha: 1) + self.color = UIColor.init(red: 142 / 255.0, green: 142 / 255.0, blue: 147 / 255.0, alpha: 1) + self.widthIconFactor = 0.36 + self.heightIconFactor = 0.36 + } + + func layout(bottomX: CGFloat, y: CGFloat) { + self.sizeToFit() + self.frame.origin.x = bottomX - self.frame.width + self.frame.origin.y = y + } + + override open func layoutSubviews() { + super.layoutSubviews() + self.layer.cornerRadius = self.frame.width / 2 + self.iconView.frame = CGRect.init(x: 0, y: 0, width: self.frame.width * self.widthIconFactor, height: self.frame.height * self.heightIconFactor) + self.iconView.center = CGPoint.init(x: self.frame.width / 2, y: self.frame.height / 2) + } + + override open func sizeToFit() { + super.sizeToFit() + self.frame = CGRect.init(x: self.frame.origin.x, y: self.frame.origin.y, width: 30, height: 30) + } +} diff --git a/Pods/SPStorkController/Source/SPStorkController/Views/SPStorkCloseView.swift b/Pods/SPStorkController/Source/SPStorkController/Views/SPStorkCloseView.swift new file mode 100644 index 0000000..34dd5a7 --- /dev/null +++ b/Pods/SPStorkController/Source/SPStorkController/Views/SPStorkCloseView.swift @@ -0,0 +1,50 @@ +// The MIT License (MIT) +// Copyright © 2017 Ivan Vorobei (hello@ivanvorobei.by) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import UIKit + +open class SPStorkCloseView: UIView { + + var color = UIColor.blue { + didSet { + self.setNeedsDisplay() + } + } + + init() { + super.init(frame: CGRect.zero) + self.commonInit() + } + + private func commonInit() { + self.backgroundColor = UIColor.clear + } + + required public init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override open func draw(_ rect: CGRect) { + super.draw(rect) + SPStorkCodeDraw.drawClose(frame: rect, resizing: .aspectFit, color: self.color) + } +} + diff --git a/Pods/SPStorkController/Source/SPStorkController/Views/SPStorkIndicatorView.swift b/Pods/SPStorkController/Source/SPStorkController/Views/SPStorkIndicatorView.swift new file mode 100755 index 0000000..484c464 --- /dev/null +++ b/Pods/SPStorkController/Source/SPStorkController/Views/SPStorkIndicatorView.swift @@ -0,0 +1,93 @@ +// The MIT License (MIT) +// Copyright © 2017 Ivan Vorobei (hello@ivanvorobei.by) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import UIKit + +open class SPStorkIndicatorView: UIView { + + var style: Style = .line { + didSet { + switch self.style { + case .line: + self.animate { + self.leftView.transform = .identity + self.rightView.transform = .identity + } + case .arrow: + self.animate { + let angle = CGFloat(20 * Float.pi / 180) + self.leftView.transform = CGAffineTransform.init(rotationAngle: angle) + self.rightView.transform = CGAffineTransform.init(rotationAngle: -angle) + } + } + + } + } + + var color: UIColor = UIColor.init(red: 202/255, green: 201/255, blue: 207/255, alpha: 1) { + didSet { + self.leftView.backgroundColor = self.color + self.rightView.backgroundColor = self.color + } + } + + private var leftView: UIView = UIView() + private var rightView: UIView = UIView() + + init() { + super.init(frame: .zero) + self.backgroundColor = UIColor.clear + self.addSubview(self.leftView) + self.addSubview(self.rightView) + self.color = UIColor.init(red: 202/255, green: 201/255, blue: 207/255, alpha: 1) + } + + required public init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override open func sizeToFit() { + super.sizeToFit() + self.frame = CGRect.init(x: self.frame.origin.x, y: self.frame.origin.y, width: 36, height: 13) + + let height: CGFloat = 5 + let correction = height / 2 + + self.leftView.frame = CGRect.init(x: 0, y: 0, width: self.frame.width / 2 + correction, height: height) + self.leftView.center.y = self.frame.height / 2 + self.leftView.layer.cornerRadius = min(self.leftView.frame.width, self.leftView.frame.height) / 2 + + self.rightView.frame = CGRect.init(x: self.frame.width / 2 - correction, y: 0, width: self.frame.width / 2 + correction, height: height) + self.rightView.center.y = self.frame.height / 2 + self.rightView.layer.cornerRadius = min(self.leftView.frame.width, self.leftView.frame.height) / 2 + } + + private func animate(animations: @escaping (() -> Void)) { + UIView.animate(withDuration: 0.5, delay: 0, usingSpringWithDamping: 1, initialSpringVelocity: 1, options: [.beginFromCurrentState, .curveEaseOut], animations: { + animations() + }) + } + + enum Style { + case arrow + case line + } +} diff --git a/Pods/Target Support Files/FSCalendar+Persian/FSCalendar+Persian-dummy.m b/Pods/Target Support Files/FSCalendar+Persian/FSCalendar+Persian-dummy.m new file mode 100644 index 0000000..9e41334 --- /dev/null +++ b/Pods/Target Support Files/FSCalendar+Persian/FSCalendar+Persian-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_FSCalendar_Persian : NSObject +@end +@implementation PodsDummy_FSCalendar_Persian +@end diff --git a/Pods/Target Support Files/FSCalendar+Persian/FSCalendar+Persian-prefix.pch b/Pods/Target Support Files/FSCalendar+Persian/FSCalendar+Persian-prefix.pch new file mode 100644 index 0000000..beb2a24 --- /dev/null +++ b/Pods/Target Support Files/FSCalendar+Persian/FSCalendar+Persian-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/Pods/Target Support Files/FSCalendar+Persian/FSCalendar+Persian-umbrella.h b/Pods/Target Support Files/FSCalendar+Persian/FSCalendar+Persian-umbrella.h new file mode 100644 index 0000000..ea723b8 --- /dev/null +++ b/Pods/Target Support Files/FSCalendar+Persian/FSCalendar+Persian-umbrella.h @@ -0,0 +1,34 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "FSCalendar.h" +#import "FSCalendarAppearance.h" +#import "FSCalendarCalculator.h" +#import "FSCalendarCell.h" +#import "FSCalendarCollectionView.h" +#import "FSCalendarCollectionViewLayout.h" +#import "FSCalendarConstants.h" +#import "FSCalendarDelegationFactory.h" +#import "FSCalendarDelegationProxy.h" +#import "FSCalendarDynamicHeader.h" +#import "FSCalendarExtensions.h" +#import "FSCalendarHeaderView.h" +#import "FSCalendarScopeHandle.h" +#import "FSCalendarStickyHeader.h" +#import "FSCalendarTransitionCoordinator.h" +#import "FSCalendarWeekdayView.h" +#import "NSLocale+Category.h" +#import "NSString+Category.h" + +FOUNDATION_EXPORT double FSCalendar_PersianVersionNumber; +FOUNDATION_EXPORT const unsigned char FSCalendar_PersianVersionString[]; + diff --git a/Pods/Target Support Files/FSCalendar+Persian/FSCalendar+Persian.modulemap b/Pods/Target Support Files/FSCalendar+Persian/FSCalendar+Persian.modulemap new file mode 100644 index 0000000..e69113a --- /dev/null +++ b/Pods/Target Support Files/FSCalendar+Persian/FSCalendar+Persian.modulemap @@ -0,0 +1,6 @@ +framework module FSCalendar_Persian { + umbrella header "FSCalendar+Persian-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/FSCalendar+Persian/FSCalendar+Persian.xcconfig b/Pods/Target Support Files/FSCalendar+Persian/FSCalendar+Persian.xcconfig new file mode 100644 index 0000000..2b39fbf --- /dev/null +++ b/Pods/Target Support Files/FSCalendar+Persian/FSCalendar+Persian.xcconfig @@ -0,0 +1,9 @@ +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/FSCalendar+Persian +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_LDFLAGS = -framework "QuartzCore" -framework "UIKit" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/FSCalendar+Persian +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES diff --git a/Pods/Target Support Files/FSCalendar+Persian/Info.plist b/Pods/Target Support Files/FSCalendar+Persian/Info.plist new file mode 100644 index 0000000..f1c636a --- /dev/null +++ b/Pods/Target Support Files/FSCalendar+Persian/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 2.9.2 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/Pods-pro-service/Info.plist b/Pods/Target Support Files/Pods-pro-service/Info.plist new file mode 100644 index 0000000..2243fe6 --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-service/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/Pods-pro-service/Pods-pro-service-acknowledgements.markdown b/Pods/Target Support Files/Pods-pro-service/Pods-pro-service-acknowledgements.markdown new file mode 100644 index 0000000..edcd771 --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-service/Pods-pro-service-acknowledgements.markdown @@ -0,0 +1,51 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## FSCalendar+Persian + +Copyright (c) 2013-2016 FSCalendar (https://github.com/WenchaoD/FSCalendar) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +## SPStorkController + +MIT License + +Copyright (c) 2018 Ivan Vorobei + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + +Generated by CocoaPods - https://cocoapods.org diff --git a/Pods/Target Support Files/Pods-pro-service/Pods-pro-service-acknowledgements.plist b/Pods/Target Support Files/Pods-pro-service/Pods-pro-service-acknowledgements.plist new file mode 100644 index 0000000..64b8681 --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-service/Pods-pro-service-acknowledgements.plist @@ -0,0 +1,89 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2013-2016 FSCalendar (https://github.com/WenchaoD/FSCalendar) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + License + MIT + Title + FSCalendar+Persian + Type + PSGroupSpecifier + + + FooterText + MIT License + +Copyright (c) 2018 Ivan Vorobei + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + + License + MIT + Title + SPStorkController + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/Pods/Target Support Files/Pods-pro-service/Pods-pro-service-dummy.m b/Pods/Target Support Files/Pods-pro-service/Pods-pro-service-dummy.m new file mode 100644 index 0000000..90e3a39 --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-service/Pods-pro-service-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_pro_service : NSObject +@end +@implementation PodsDummy_Pods_pro_service +@end diff --git a/Pods/Target Support Files/Pods-pro-service/Pods-pro-service-frameworks.sh b/Pods/Target Support Files/Pods-pro-service/Pods-pro-service-frameworks.sh new file mode 100755 index 0000000..9eececf --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-service/Pods-pro-service-frameworks.sh @@ -0,0 +1,155 @@ +#!/bin/sh +set -e +set -u +set -o pipefail + +if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then + # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy + # frameworks to, so exit 0 (signalling the script phase was successful). + exit 0 +fi + +echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + +COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" +SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" + +# Used as a return value for each invocation of `strip_invalid_archs` function. +STRIP_BINARY_RETVAL=0 + +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + +# Copies and strips a vendored framework +install_framework() +{ + if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then + local source="${BUILT_PRODUCTS_DIR}/$1" + elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then + local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" + elif [ -r "$1" ]; then + local source="$1" + fi + + local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + if [ -L "${source}" ]; then + echo "Symlinked..." + source="$(readlink "${source}")" + fi + + # Use filter instead of exclude so missing patterns don't throw errors. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + + local basename + basename="$(basename -s .framework "$1")" + binary="${destination}/${basename}.framework/${basename}" + if ! [ -r "$binary" ]; then + binary="${destination}/${basename}" + fi + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then + strip_invalid_archs "$binary" + fi + + # Resign the code if required by the build settings to avoid unstable apps + code_sign_if_enabled "${destination}/$(basename "$1")" + + # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. + if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then + local swift_runtime_libs + swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) + for lib in $swift_runtime_libs; do + echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" + rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" + code_sign_if_enabled "${destination}/${lib}" + done + fi +} + +# Copies and strips a vendored dSYM +install_dsym() { + local source="$1" + if [ -r "$source" ]; then + # Copy the dSYM into a the targets temp dir. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" + + local basename + basename="$(basename -s .framework.dSYM "$source")" + binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then + strip_invalid_archs "$binary" + fi + + if [[ $STRIP_BINARY_RETVAL == 1 ]]; then + # Move the stripped file into its final destination. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}" + else + # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. + touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" + fi + fi +} + +# Signs a framework with the provided identity +code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identitiy + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" + + if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + code_sign_cmd="$code_sign_cmd &" + fi + echo "$code_sign_cmd" + eval "$code_sign_cmd" + fi +} + +# Strip invalid architectures +strip_invalid_archs() { + binary="$1" + # Get architectures for current target binary + binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" + # Intersect them with the architectures we are building for + intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" + # If there are no archs supported by this binary then warn the user + if [[ -z "$intersected_archs" ]]; then + echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." + STRIP_BINARY_RETVAL=0 + return + fi + stripped="" + for arch in $binary_archs; do + if ! [[ "${ARCHS}" == *"$arch"* ]]; then + # Strip non-valid architectures in-place + lipo -remove "$arch" -output "$binary" "$binary" || exit 1 + stripped="$stripped $arch" + fi + done + if [[ "$stripped" ]]; then + echo "Stripped $binary of architectures:$stripped" + fi + STRIP_BINARY_RETVAL=1 +} + + +if [[ "$CONFIGURATION" == "Debug" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/FSCalendar+Persian/FSCalendar_Persian.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SPStorkController/SPStorkController.framework" +fi +if [[ "$CONFIGURATION" == "Release" ]]; then + install_framework "${BUILT_PRODUCTS_DIR}/FSCalendar+Persian/FSCalendar_Persian.framework" + install_framework "${BUILT_PRODUCTS_DIR}/SPStorkController/SPStorkController.framework" +fi +if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + wait +fi diff --git a/Pods/Target Support Files/Pods-pro-service/Pods-pro-service-resources.sh b/Pods/Target Support Files/Pods-pro-service/Pods-pro-service-resources.sh new file mode 100755 index 0000000..345301f --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-service/Pods-pro-service-resources.sh @@ -0,0 +1,118 @@ +#!/bin/sh +set -e +set -u +set -o pipefail + +if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then + # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy + # resources to, so exit 0 (signalling the script phase was successful). + exit 0 +fi + +mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + +RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt +> "$RESOURCES_TO_COPY" + +XCASSET_FILES=() + +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + +case "${TARGETED_DEVICE_FAMILY:-}" in + 1,2) + TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" + ;; + 1) + TARGET_DEVICE_ARGS="--target-device iphone" + ;; + 2) + TARGET_DEVICE_ARGS="--target-device ipad" + ;; + 3) + TARGET_DEVICE_ARGS="--target-device tv" + ;; + 4) + TARGET_DEVICE_ARGS="--target-device watch" + ;; + *) + TARGET_DEVICE_ARGS="--target-device mac" + ;; +esac + +install_resource() +{ + if [[ "$1" = /* ]] ; then + RESOURCE_PATH="$1" + else + RESOURCE_PATH="${PODS_ROOT}/$1" + fi + if [[ ! -e "$RESOURCE_PATH" ]] ; then + cat << EOM +error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. +EOM + exit 1 + fi + case $RESOURCE_PATH in + *.storyboard) + 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 + 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} + ;; + *.xib) + 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 + 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} + ;; + *.framework) + echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true + mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + ;; + *.xcdatamodel) + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true + xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" + ;; + *.xcdatamodeld) + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true + xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" + ;; + *.xcmappingmodel) + echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true + xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" + ;; + *.xcassets) + ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" + XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") + ;; + *) + echo "$RESOURCE_PATH" || true + echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" + ;; + esac +} + +mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then + mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi +rm -f "$RESOURCES_TO_COPY" + +if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ] +then + # Find all other xcassets (this unfortunately includes those of path pods and other targets). + OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) + while read line; do + if [[ $line != "${PODS_ROOT}*" ]]; then + XCASSET_FILES+=("$line") + fi + done <<<"$OTHER_XCASSETS" + + if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then + 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}" + else + 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}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist" + fi +fi diff --git a/Pods/Target Support Files/Pods-pro-service/Pods-pro-service-umbrella.h b/Pods/Target Support Files/Pods-pro-service/Pods-pro-service-umbrella.h new file mode 100644 index 0000000..651da81 --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-service/Pods-pro-service-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double Pods_pro_serviceVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_pro_serviceVersionString[]; + diff --git a/Pods/Target Support Files/Pods-pro-service/Pods-pro-service.debug.xcconfig b/Pods/Target Support Files/Pods-pro-service/Pods-pro-service.debug.xcconfig new file mode 100644 index 0000000..81f4ff2 --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-service/Pods-pro-service.debug.xcconfig @@ -0,0 +1,11 @@ +EMBEDDED_CONTENT_CONTAINS_SWIFT = YES +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FSCalendar+Persian" "${PODS_CONFIGURATION_BUILD_DIR}/SPStorkController" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/FSCalendar+Persian/FSCalendar_Persian.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/SPStorkController/SPStorkController.framework/Headers" +OTHER_LDFLAGS = $(inherited) -framework "FSCalendar_Persian" -framework "SPStorkController" +OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods diff --git a/Pods/Target Support Files/Pods-pro-service/Pods-pro-service.modulemap b/Pods/Target Support Files/Pods-pro-service/Pods-pro-service.modulemap new file mode 100644 index 0000000..98c2502 --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-service/Pods-pro-service.modulemap @@ -0,0 +1,6 @@ +framework module Pods_pro_service { + umbrella header "Pods-pro-service-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/Pods-pro-service/Pods-pro-service.release.xcconfig b/Pods/Target Support Files/Pods-pro-service/Pods-pro-service.release.xcconfig new file mode 100644 index 0000000..81f4ff2 --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-service/Pods-pro-service.release.xcconfig @@ -0,0 +1,11 @@ +EMBEDDED_CONTENT_CONTAINS_SWIFT = YES +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FSCalendar+Persian" "${PODS_CONFIGURATION_BUILD_DIR}/SPStorkController" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/FSCalendar+Persian/FSCalendar_Persian.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/SPStorkController/SPStorkController.framework/Headers" +OTHER_LDFLAGS = $(inherited) -framework "FSCalendar_Persian" -framework "SPStorkController" +OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods diff --git a/Pods/Target Support Files/Pods-pro-serviceTests/Info.plist b/Pods/Target Support Files/Pods-pro-serviceTests/Info.plist new file mode 100644 index 0000000..2243fe6 --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-serviceTests/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests-acknowledgements.markdown b/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests-acknowledgements.markdown new file mode 100644 index 0000000..102af75 --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests-acknowledgements.markdown @@ -0,0 +1,3 @@ +# Acknowledgements +This application makes use of the following third party libraries: +Generated by CocoaPods - https://cocoapods.org diff --git a/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests-acknowledgements.plist b/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests-acknowledgements.plist new file mode 100644 index 0000000..7acbad1 --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests-acknowledgements.plist @@ -0,0 +1,29 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests-dummy.m b/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests-dummy.m new file mode 100644 index 0000000..72353d6 --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_pro_serviceTests : NSObject +@end +@implementation PodsDummy_Pods_pro_serviceTests +@end diff --git a/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests-frameworks.sh b/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests-frameworks.sh new file mode 100755 index 0000000..08e3eaa --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests-frameworks.sh @@ -0,0 +1,146 @@ +#!/bin/sh +set -e +set -u +set -o pipefail + +if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then + # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy + # frameworks to, so exit 0 (signalling the script phase was successful). + exit 0 +fi + +echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + +COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" +SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" + +# Used as a return value for each invocation of `strip_invalid_archs` function. +STRIP_BINARY_RETVAL=0 + +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + +# Copies and strips a vendored framework +install_framework() +{ + if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then + local source="${BUILT_PRODUCTS_DIR}/$1" + elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then + local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" + elif [ -r "$1" ]; then + local source="$1" + fi + + local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + if [ -L "${source}" ]; then + echo "Symlinked..." + source="$(readlink "${source}")" + fi + + # Use filter instead of exclude so missing patterns don't throw errors. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + + local basename + basename="$(basename -s .framework "$1")" + binary="${destination}/${basename}.framework/${basename}" + if ! [ -r "$binary" ]; then + binary="${destination}/${basename}" + fi + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then + strip_invalid_archs "$binary" + fi + + # Resign the code if required by the build settings to avoid unstable apps + code_sign_if_enabled "${destination}/$(basename "$1")" + + # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. + if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then + local swift_runtime_libs + swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) + for lib in $swift_runtime_libs; do + echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" + rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" + code_sign_if_enabled "${destination}/${lib}" + done + fi +} + +# Copies and strips a vendored dSYM +install_dsym() { + local source="$1" + if [ -r "$source" ]; then + # Copy the dSYM into a the targets temp dir. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" + + local basename + basename="$(basename -s .framework.dSYM "$source")" + binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then + strip_invalid_archs "$binary" + fi + + if [[ $STRIP_BINARY_RETVAL == 1 ]]; then + # Move the stripped file into its final destination. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}" + else + # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. + touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" + fi + fi +} + +# Signs a framework with the provided identity +code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identitiy + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" + + if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + code_sign_cmd="$code_sign_cmd &" + fi + echo "$code_sign_cmd" + eval "$code_sign_cmd" + fi +} + +# Strip invalid architectures +strip_invalid_archs() { + binary="$1" + # Get architectures for current target binary + binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" + # Intersect them with the architectures we are building for + intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" + # If there are no archs supported by this binary then warn the user + if [[ -z "$intersected_archs" ]]; then + echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." + STRIP_BINARY_RETVAL=0 + return + fi + stripped="" + for arch in $binary_archs; do + if ! [[ "${ARCHS}" == *"$arch"* ]]; then + # Strip non-valid architectures in-place + lipo -remove "$arch" -output "$binary" "$binary" || exit 1 + stripped="$stripped $arch" + fi + done + if [[ "$stripped" ]]; then + echo "Stripped $binary of architectures:$stripped" + fi + STRIP_BINARY_RETVAL=1 +} + +if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + wait +fi diff --git a/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests-resources.sh b/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests-resources.sh new file mode 100755 index 0000000..345301f --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests-resources.sh @@ -0,0 +1,118 @@ +#!/bin/sh +set -e +set -u +set -o pipefail + +if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then + # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy + # resources to, so exit 0 (signalling the script phase was successful). + exit 0 +fi + +mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + +RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt +> "$RESOURCES_TO_COPY" + +XCASSET_FILES=() + +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + +case "${TARGETED_DEVICE_FAMILY:-}" in + 1,2) + TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" + ;; + 1) + TARGET_DEVICE_ARGS="--target-device iphone" + ;; + 2) + TARGET_DEVICE_ARGS="--target-device ipad" + ;; + 3) + TARGET_DEVICE_ARGS="--target-device tv" + ;; + 4) + TARGET_DEVICE_ARGS="--target-device watch" + ;; + *) + TARGET_DEVICE_ARGS="--target-device mac" + ;; +esac + +install_resource() +{ + if [[ "$1" = /* ]] ; then + RESOURCE_PATH="$1" + else + RESOURCE_PATH="${PODS_ROOT}/$1" + fi + if [[ ! -e "$RESOURCE_PATH" ]] ; then + cat << EOM +error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. +EOM + exit 1 + fi + case $RESOURCE_PATH in + *.storyboard) + 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 + 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} + ;; + *.xib) + 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 + 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} + ;; + *.framework) + echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true + mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + ;; + *.xcdatamodel) + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true + xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" + ;; + *.xcdatamodeld) + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true + xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" + ;; + *.xcmappingmodel) + echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true + xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" + ;; + *.xcassets) + ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" + XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") + ;; + *) + echo "$RESOURCE_PATH" || true + echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" + ;; + esac +} + +mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then + mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi +rm -f "$RESOURCES_TO_COPY" + +if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ] +then + # Find all other xcassets (this unfortunately includes those of path pods and other targets). + OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) + while read line; do + if [[ $line != "${PODS_ROOT}*" ]]; then + XCASSET_FILES+=("$line") + fi + done <<<"$OTHER_XCASSETS" + + if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then + 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}" + else + 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}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist" + fi +fi diff --git a/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests-umbrella.h b/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests-umbrella.h new file mode 100644 index 0000000..6e18562 --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double Pods_pro_serviceTestsVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_pro_serviceTestsVersionString[]; + diff --git a/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests.debug.xcconfig b/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests.debug.xcconfig new file mode 100644 index 0000000..47b7d27 --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests.debug.xcconfig @@ -0,0 +1,8 @@ +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FSCalendar+Persian" "${PODS_CONFIGURATION_BUILD_DIR}/SPStorkController" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/FSCalendar+Persian/FSCalendar_Persian.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/SPStorkController/SPStorkController.framework/Headers" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods diff --git a/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests.modulemap b/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests.modulemap new file mode 100644 index 0000000..a4e5dda --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests.modulemap @@ -0,0 +1,6 @@ +framework module Pods_pro_serviceTests { + umbrella header "Pods-pro-serviceTests-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests.release.xcconfig b/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests.release.xcconfig new file mode 100644 index 0000000..47b7d27 --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests.release.xcconfig @@ -0,0 +1,8 @@ +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FSCalendar+Persian" "${PODS_CONFIGURATION_BUILD_DIR}/SPStorkController" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/FSCalendar+Persian/FSCalendar_Persian.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/SPStorkController/SPStorkController.framework/Headers" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods diff --git a/Pods/Target Support Files/Pods-pro-serviceUITests/Info.plist b/Pods/Target Support Files/Pods-pro-serviceUITests/Info.plist new file mode 100644 index 0000000..2243fe6 --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-serviceUITests/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0.0 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests-acknowledgements.markdown b/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests-acknowledgements.markdown new file mode 100644 index 0000000..102af75 --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests-acknowledgements.markdown @@ -0,0 +1,3 @@ +# Acknowledgements +This application makes use of the following third party libraries: +Generated by CocoaPods - https://cocoapods.org diff --git a/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests-acknowledgements.plist b/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests-acknowledgements.plist new file mode 100644 index 0000000..7acbad1 --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests-acknowledgements.plist @@ -0,0 +1,29 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - https://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests-dummy.m b/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests-dummy.m new file mode 100644 index 0000000..a8c40b3 --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_pro_serviceUITests : NSObject +@end +@implementation PodsDummy_Pods_pro_serviceUITests +@end diff --git a/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests-frameworks.sh b/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests-frameworks.sh new file mode 100755 index 0000000..08e3eaa --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests-frameworks.sh @@ -0,0 +1,146 @@ +#!/bin/sh +set -e +set -u +set -o pipefail + +if [ -z ${FRAMEWORKS_FOLDER_PATH+x} ]; then + # If FRAMEWORKS_FOLDER_PATH is not set, then there's nowhere for us to copy + # frameworks to, so exit 0 (signalling the script phase was successful). + exit 0 +fi + +echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" +mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + +COCOAPODS_PARALLEL_CODE_SIGN="${COCOAPODS_PARALLEL_CODE_SIGN:-false}" +SWIFT_STDLIB_PATH="${DT_TOOLCHAIN_DIR}/usr/lib/swift/${PLATFORM_NAME}" + +# Used as a return value for each invocation of `strip_invalid_archs` function. +STRIP_BINARY_RETVAL=0 + +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + +# Copies and strips a vendored framework +install_framework() +{ + if [ -r "${BUILT_PRODUCTS_DIR}/$1" ]; then + local source="${BUILT_PRODUCTS_DIR}/$1" + elif [ -r "${BUILT_PRODUCTS_DIR}/$(basename "$1")" ]; then + local source="${BUILT_PRODUCTS_DIR}/$(basename "$1")" + elif [ -r "$1" ]; then + local source="$1" + fi + + local destination="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + + if [ -L "${source}" ]; then + echo "Symlinked..." + source="$(readlink "${source}")" + fi + + # Use filter instead of exclude so missing patterns don't throw errors. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${destination}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${destination}" + + local basename + basename="$(basename -s .framework "$1")" + binary="${destination}/${basename}.framework/${basename}" + if ! [ -r "$binary" ]; then + binary="${destination}/${basename}" + fi + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"dynamically linked shared library"* ]]; then + strip_invalid_archs "$binary" + fi + + # Resign the code if required by the build settings to avoid unstable apps + code_sign_if_enabled "${destination}/$(basename "$1")" + + # Embed linked Swift runtime libraries. No longer necessary as of Xcode 7. + if [ "${XCODE_VERSION_MAJOR}" -lt 7 ]; then + local swift_runtime_libs + swift_runtime_libs=$(xcrun otool -LX "$binary" | grep --color=never @rpath/libswift | sed -E s/@rpath\\/\(.+dylib\).*/\\1/g | uniq -u && exit ${PIPESTATUS[0]}) + for lib in $swift_runtime_libs; do + echo "rsync -auv \"${SWIFT_STDLIB_PATH}/${lib}\" \"${destination}\"" + rsync -auv "${SWIFT_STDLIB_PATH}/${lib}" "${destination}" + code_sign_if_enabled "${destination}/${lib}" + done + fi +} + +# Copies and strips a vendored dSYM +install_dsym() { + local source="$1" + if [ -r "$source" ]; then + # Copy the dSYM into a the targets temp dir. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${source}\" \"${DERIVED_FILES_DIR}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${source}" "${DERIVED_FILES_DIR}" + + local basename + basename="$(basename -s .framework.dSYM "$source")" + binary="${DERIVED_FILES_DIR}/${basename}.framework.dSYM/Contents/Resources/DWARF/${basename}" + + # Strip invalid architectures so "fat" simulator / device frameworks work on device + if [[ "$(file "$binary")" == *"Mach-O dSYM companion"* ]]; then + strip_invalid_archs "$binary" + fi + + if [[ $STRIP_BINARY_RETVAL == 1 ]]; then + # Move the stripped file into its final destination. + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter \"- CVS/\" --filter \"- .svn/\" --filter \"- .git/\" --filter \"- .hg/\" --filter \"- Headers\" --filter \"- PrivateHeaders\" --filter \"- Modules\" \"${DERIVED_FILES_DIR}/${basename}.framework.dSYM\" \"${DWARF_DSYM_FOLDER_PATH}\"" + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" --filter "- CVS/" --filter "- .svn/" --filter "- .git/" --filter "- .hg/" --filter "- Headers" --filter "- PrivateHeaders" --filter "- Modules" "${DERIVED_FILES_DIR}/${basename}.framework.dSYM" "${DWARF_DSYM_FOLDER_PATH}" + else + # The dSYM was not stripped at all, in this case touch a fake folder so the input/output paths from Xcode do not reexecute this script because the file is missing. + touch "${DWARF_DSYM_FOLDER_PATH}/${basename}.framework.dSYM" + fi + fi +} + +# Signs a framework with the provided identity +code_sign_if_enabled() { + if [ -n "${EXPANDED_CODE_SIGN_IDENTITY}" -a "${CODE_SIGNING_REQUIRED:-}" != "NO" -a "${CODE_SIGNING_ALLOWED}" != "NO" ]; then + # Use the current code_sign_identitiy + echo "Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}" + local code_sign_cmd="/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} ${OTHER_CODE_SIGN_FLAGS:-} --preserve-metadata=identifier,entitlements '$1'" + + if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + code_sign_cmd="$code_sign_cmd &" + fi + echo "$code_sign_cmd" + eval "$code_sign_cmd" + fi +} + +# Strip invalid architectures +strip_invalid_archs() { + binary="$1" + # Get architectures for current target binary + binary_archs="$(lipo -info "$binary" | rev | cut -d ':' -f1 | awk '{$1=$1;print}' | rev)" + # Intersect them with the architectures we are building for + intersected_archs="$(echo ${ARCHS[@]} ${binary_archs[@]} | tr ' ' '\n' | sort | uniq -d)" + # If there are no archs supported by this binary then warn the user + if [[ -z "$intersected_archs" ]]; then + echo "warning: [CP] Vendored binary '$binary' contains architectures ($binary_archs) none of which match the current build architectures ($ARCHS)." + STRIP_BINARY_RETVAL=0 + return + fi + stripped="" + for arch in $binary_archs; do + if ! [[ "${ARCHS}" == *"$arch"* ]]; then + # Strip non-valid architectures in-place + lipo -remove "$arch" -output "$binary" "$binary" || exit 1 + stripped="$stripped $arch" + fi + done + if [[ "$stripped" ]]; then + echo "Stripped $binary of architectures:$stripped" + fi + STRIP_BINARY_RETVAL=1 +} + +if [ "${COCOAPODS_PARALLEL_CODE_SIGN}" == "true" ]; then + wait +fi diff --git a/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests-resources.sh b/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests-resources.sh new file mode 100755 index 0000000..345301f --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests-resources.sh @@ -0,0 +1,118 @@ +#!/bin/sh +set -e +set -u +set -o pipefail + +if [ -z ${UNLOCALIZED_RESOURCES_FOLDER_PATH+x} ]; then + # If UNLOCALIZED_RESOURCES_FOLDER_PATH is not set, then there's nowhere for us to copy + # resources to, so exit 0 (signalling the script phase was successful). + exit 0 +fi + +mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + +RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt +> "$RESOURCES_TO_COPY" + +XCASSET_FILES=() + +# This protects against multiple targets copying the same framework dependency at the same time. The solution +# was originally proposed here: https://lists.samba.org/archive/rsync/2008-February/020158.html +RSYNC_PROTECT_TMP_FILES=(--filter "P .*.??????") + +case "${TARGETED_DEVICE_FAMILY:-}" in + 1,2) + TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" + ;; + 1) + TARGET_DEVICE_ARGS="--target-device iphone" + ;; + 2) + TARGET_DEVICE_ARGS="--target-device ipad" + ;; + 3) + TARGET_DEVICE_ARGS="--target-device tv" + ;; + 4) + TARGET_DEVICE_ARGS="--target-device watch" + ;; + *) + TARGET_DEVICE_ARGS="--target-device mac" + ;; +esac + +install_resource() +{ + if [[ "$1" = /* ]] ; then + RESOURCE_PATH="$1" + else + RESOURCE_PATH="${PODS_ROOT}/$1" + fi + if [[ ! -e "$RESOURCE_PATH" ]] ; then + cat << EOM +error: Resource "$RESOURCE_PATH" not found. Run 'pod install' to update the copy resources script. +EOM + exit 1 + fi + case $RESOURCE_PATH in + *.storyboard) + 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 + 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} + ;; + *.xib) + 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 + 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} + ;; + *.framework) + echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true + mkdir -p "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" $RESOURCE_PATH ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" || true + rsync --delete -av "${RSYNC_PROTECT_TMP_FILES[@]}" "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + ;; + *.xcdatamodel) + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH"`.mom\"" || true + xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodel`.mom" + ;; + *.xcdatamodeld) + echo "xcrun momc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd\"" || true + xcrun momc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcdatamodeld`.momd" + ;; + *.xcmappingmodel) + echo "xcrun mapc \"$RESOURCE_PATH\" \"${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm\"" || true + xcrun mapc "$RESOURCE_PATH" "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$RESOURCE_PATH" .xcmappingmodel`.cdm" + ;; + *.xcassets) + ABSOLUTE_XCASSET_FILE="$RESOURCE_PATH" + XCASSET_FILES+=("$ABSOLUTE_XCASSET_FILE") + ;; + *) + echo "$RESOURCE_PATH" || true + echo "$RESOURCE_PATH" >> "$RESOURCES_TO_COPY" + ;; + esac +} + +mkdir -p "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +if [[ "${ACTION}" == "install" ]] && [[ "${SKIP_INSTALL}" == "NO" ]]; then + mkdir -p "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi +rm -f "$RESOURCES_TO_COPY" + +if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ -n "${XCASSET_FILES:-}" ] +then + # Find all other xcassets (this unfortunately includes those of path pods and other targets). + OTHER_XCASSETS=$(find "$PWD" -iname "*.xcassets" -type d) + while read line; do + if [[ $line != "${PODS_ROOT}*" ]]; then + XCASSET_FILES+=("$line") + fi + done <<<"$OTHER_XCASSETS" + + if [ -z ${ASSETCATALOG_COMPILER_APPICON_NAME+x} ]; then + 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}" + else + 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}" --app-icon "${ASSETCATALOG_COMPILER_APPICON_NAME}" --output-partial-info-plist "${TARGET_TEMP_DIR}/assetcatalog_generated_info_cocoapods.plist" + fi +fi diff --git a/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests-umbrella.h b/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests-umbrella.h new file mode 100644 index 0000000..16cadfa --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double Pods_pro_serviceUITestsVersionNumber; +FOUNDATION_EXPORT const unsigned char Pods_pro_serviceUITestsVersionString[]; + diff --git a/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests.debug.xcconfig b/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests.debug.xcconfig new file mode 100644 index 0000000..47b7d27 --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests.debug.xcconfig @@ -0,0 +1,8 @@ +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FSCalendar+Persian" "${PODS_CONFIGURATION_BUILD_DIR}/SPStorkController" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/FSCalendar+Persian/FSCalendar_Persian.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/SPStorkController/SPStorkController.framework/Headers" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods diff --git a/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests.modulemap b/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests.modulemap new file mode 100644 index 0000000..0a5284a --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests.modulemap @@ -0,0 +1,6 @@ +framework module Pods_pro_serviceUITests { + umbrella header "Pods-pro-serviceUITests-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests.release.xcconfig b/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests.release.xcconfig new file mode 100644 index 0000000..47b7d27 --- /dev/null +++ b/Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests.release.xcconfig @@ -0,0 +1,8 @@ +FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/FSCalendar+Persian" "${PODS_CONFIGURATION_BUILD_DIR}/SPStorkController" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' +OTHER_CFLAGS = $(inherited) -iquote "${PODS_CONFIGURATION_BUILD_DIR}/FSCalendar+Persian/FSCalendar_Persian.framework/Headers" -iquote "${PODS_CONFIGURATION_BUILD_DIR}/SPStorkController/SPStorkController.framework/Headers" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_PODFILE_DIR_PATH = ${SRCROOT}/. +PODS_ROOT = ${SRCROOT}/Pods diff --git a/Pods/Target Support Files/SPStorkController/Info.plist b/Pods/Target Support Files/SPStorkController/Info.plist new file mode 100644 index 0000000..509b5d9 --- /dev/null +++ b/Pods/Target Support Files/SPStorkController/Info.plist @@ -0,0 +1,26 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + ${EXECUTABLE_NAME} + CFBundleIdentifier + ${PRODUCT_BUNDLE_IDENTIFIER} + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + ${PRODUCT_NAME} + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.6.5 + CFBundleSignature + ???? + CFBundleVersion + ${CURRENT_PROJECT_VERSION} + NSPrincipalClass + + + diff --git a/Pods/Target Support Files/SPStorkController/SPStorkController-dummy.m b/Pods/Target Support Files/SPStorkController/SPStorkController-dummy.m new file mode 100644 index 0000000..a075fd2 --- /dev/null +++ b/Pods/Target Support Files/SPStorkController/SPStorkController-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_SPStorkController : NSObject +@end +@implementation PodsDummy_SPStorkController +@end diff --git a/Pods/Target Support Files/SPStorkController/SPStorkController-prefix.pch b/Pods/Target Support Files/SPStorkController/SPStorkController-prefix.pch new file mode 100644 index 0000000..beb2a24 --- /dev/null +++ b/Pods/Target Support Files/SPStorkController/SPStorkController-prefix.pch @@ -0,0 +1,12 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + diff --git a/Pods/Target Support Files/SPStorkController/SPStorkController-umbrella.h b/Pods/Target Support Files/SPStorkController/SPStorkController-umbrella.h new file mode 100644 index 0000000..04306d3 --- /dev/null +++ b/Pods/Target Support Files/SPStorkController/SPStorkController-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#import +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + + +FOUNDATION_EXPORT double SPStorkControllerVersionNumber; +FOUNDATION_EXPORT const unsigned char SPStorkControllerVersionString[]; + diff --git a/Pods/Target Support Files/SPStorkController/SPStorkController.modulemap b/Pods/Target Support Files/SPStorkController/SPStorkController.modulemap new file mode 100644 index 0000000..f3feb58 --- /dev/null +++ b/Pods/Target Support Files/SPStorkController/SPStorkController.modulemap @@ -0,0 +1,6 @@ +framework module SPStorkController { + umbrella header "SPStorkController-umbrella.h" + + export * + module * { export * } +} diff --git a/Pods/Target Support Files/SPStorkController/SPStorkController.xcconfig b/Pods/Target Support Files/SPStorkController/SPStorkController.xcconfig new file mode 100644 index 0000000..c2b0244 --- /dev/null +++ b/Pods/Target Support Files/SPStorkController/SPStorkController.xcconfig @@ -0,0 +1,10 @@ +CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SPStorkController +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +OTHER_LDFLAGS = -framework "UIKit" +OTHER_SWIFT_FLAGS = $(inherited) "-D" "COCOAPODS" +PODS_BUILD_DIR = ${BUILD_DIR} +PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) +PODS_ROOT = ${SRCROOT} +PODS_TARGET_SRCROOT = ${PODS_ROOT}/SPStorkController +PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} +SKIP_INSTALL = YES diff --git a/pro-service.xcodeproj/project.pbxproj b/pro-service.xcodeproj/project.pbxproj new file mode 100644 index 0000000..33852ea --- /dev/null +++ b/pro-service.xcodeproj/project.pbxproj @@ -0,0 +1,1053 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 35943836CF0B4AF2F6E43797 /* Pods_pro_serviceUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 05C08B0D6D9C3740DDE349E1 /* Pods_pro_serviceUITests.framework */; }; + D93C58F3689579B7FE9CB614 /* Pods_pro_serviceTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 64B80F5FFAE6482A713F6A7C /* Pods_pro_serviceTests.framework */; }; + DCFCBCA1034496A1F4653AD3 /* Pods_pro_service.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B5C5A81DBD109C41DCBDDD4 /* Pods_pro_service.framework */; }; + FA2D946C2290C7EB0011D063 /* SearchViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FA2D946B2290C7EB0011D063 /* SearchViewController.m */; }; + FA2D94B42290F8020011D063 /* SearchTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = FA2D94B22290F8020011D063 /* SearchTableViewCell.m */; }; + FA2D94B52290F8020011D063 /* SearchTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = FA2D94B32290F8020011D063 /* SearchTableViewCell.xib */; }; + FA3EC880229600D700D74B8C /* EventViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FA3EC87F229600D700D74B8C /* EventViewController.m */; }; + FA3EC888229605ED00D74B8C /* HeaderEventTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = FA3EC886229605ED00D74B8C /* HeaderEventTableViewCell.m */; }; + FA3EC889229605ED00D74B8C /* HeaderEventTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = FA3EC887229605ED00D74B8C /* HeaderEventTableViewCell.xib */; }; + FA3EC88E2296099E00D74B8C /* ImagesEventTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = FA3EC88C2296099E00D74B8C /* ImagesEventTableViewCell.m */; }; + FA3EC88F2296099E00D74B8C /* ImagesEventTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = FA3EC88D2296099E00D74B8C /* ImagesEventTableViewCell.xib */; }; + FA3EC89422960B2E00D74B8C /* FooterEventTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = FA3EC89222960B2E00D74B8C /* FooterEventTableViewCell.m */; }; + FA3EC89522960B2E00D74B8C /* FooterEventTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = FA3EC89322960B2E00D74B8C /* FooterEventTableViewCell.xib */; }; + FA3EC89A2296131900D74B8C /* ImageEventCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = FA3EC8982296131900D74B8C /* ImageEventCollectionViewCell.m */; }; + FA3EC89B2296131900D74B8C /* ImageEventCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = FA3EC8992296131900D74B8C /* ImageEventCollectionViewCell.xib */; }; + FA3EC8A622961CBF00D74B8C /* PlugEventTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = FA3EC8A422961CBF00D74B8C /* PlugEventTableViewCell.m */; }; + FA3EC8A722961CBF00D74B8C /* PlugEventTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = FA3EC8A522961CBF00D74B8C /* PlugEventTableViewCell.xib */; }; + FA553D0C2296DFBC00F6912F /* CalendarViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FA553D0B2296DFBC00F6912F /* CalendarViewController.m */; }; + FA74F4AA228B208200DDF9E4 /* MainCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = FA74F4A8228B208200DDF9E4 /* MainCollectionViewCell.m */; }; + FA74F4AB228B208200DDF9E4 /* MainCollectionViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = FA74F4A9228B208200DDF9E4 /* MainCollectionViewCell.xib */; }; + FA74F4B3228B263B00DDF9E4 /* CategoryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FA74F4B2228B263B00DDF9E4 /* CategoryViewController.m */; }; + FA74F4B8228B274200DDF9E4 /* CategoryTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = FA74F4B6228B274200DDF9E4 /* CategoryTableViewCell.m */; }; + FA74F4B9228B274200DDF9E4 /* CategoryTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = FA74F4B7228B274200DDF9E4 /* CategoryTableViewCell.xib */; }; + FA8BBD9622945CF500DB52BA /* EventListViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FA8BBD9522945CF500DB52BA /* EventListViewController.m */; }; + FA98C367228A33C6002D49AF /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = FA98C366228A33C6002D49AF /* AppDelegate.m */; }; + FA98C36D228A33C6002D49AF /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA98C36B228A33C6002D49AF /* Main.storyboard */; }; + FA98C36F228A33C8002D49AF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FA98C36E228A33C8002D49AF /* Assets.xcassets */; }; + FA98C372228A33C8002D49AF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA98C370228A33C8002D49AF /* LaunchScreen.storyboard */; }; + FA98C375228A33C8002D49AF /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = FA98C374228A33C8002D49AF /* main.m */; }; + FA98C37F228A33C9002D49AF /* pro_serviceTests.m in Sources */ = {isa = PBXBuildFile; fileRef = FA98C37E228A33C9002D49AF /* pro_serviceTests.m */; }; + FA98C38A228A33C9002D49AF /* pro_serviceUITests.m in Sources */ = {isa = PBXBuildFile; fileRef = FA98C389228A33C9002D49AF /* pro_serviceUITests.m */; }; + FA98C399228A3436002D49AF /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FA98C398228A3436002D49AF /* MainViewController.m */; }; + FA98C39D228A4C1C002D49AF /* MainTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = FA98C39B228A4C1C002D49AF /* MainTableViewCell.m */; }; + FA98C39E228A4C1C002D49AF /* MainTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = FA98C39C228A4C1C002D49AF /* MainTableViewCell.xib */; }; + FAEBC3DA2293084400A4D033 /* DateViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FAEBC3D92293084400A4D033 /* DateViewController.m */; }; + FAEBC3DE2293649400A4D033 /* SearchCategoryViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FAEBC3DD2293649400A4D033 /* SearchCategoryViewController.m */; }; + FAEBC3E22293776600A4D033 /* Event.m in Sources */ = {isa = PBXBuildFile; fileRef = FAEBC3E12293776600A4D033 /* Event.m */; }; + FAEBC3E72293795A00A4D033 /* Calendar.m in Sources */ = {isa = PBXBuildFile; fileRef = FAEBC3E62293795A00A4D033 /* Calendar.m */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + FA98C37B228A33C9002D49AF /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FA98C35A228A33C6002D49AF /* Project object */; + proxyType = 1; + remoteGlobalIDString = FA98C361228A33C6002D49AF; + remoteInfo = "pro-service"; + }; + FA98C386228A33C9002D49AF /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = FA98C35A228A33C6002D49AF /* Project object */; + proxyType = 1; + remoteGlobalIDString = FA98C361228A33C6002D49AF; + remoteInfo = "pro-service"; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 05C08B0D6D9C3740DDE349E1 /* Pods_pro_serviceUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_pro_serviceUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 353B757899117F1651679105 /* Pods-pro-serviceUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-pro-serviceUITests.release.xcconfig"; path = "Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests.release.xcconfig"; sourceTree = ""; }; + 3B5C5A81DBD109C41DCBDDD4 /* Pods_pro_service.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_pro_service.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 3D4C77CBF6B87B9FAC3EF320 /* Pods-pro-serviceUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-pro-serviceUITests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-pro-serviceUITests/Pods-pro-serviceUITests.debug.xcconfig"; sourceTree = ""; }; + 3D7AA8BBFF14424812C3B62D /* Pods-pro-service.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-pro-service.debug.xcconfig"; path = "Pods/Target Support Files/Pods-pro-service/Pods-pro-service.debug.xcconfig"; sourceTree = ""; }; + 64B80F5FFAE6482A713F6A7C /* Pods_pro_serviceTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_pro_serviceTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 6F38EFE0F9BF2B4313AC1B09 /* Pods-pro-serviceTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-pro-serviceTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests.debug.xcconfig"; sourceTree = ""; }; + B147E7AD79F38B84EEFFC47D /* Pods-pro-serviceTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-pro-serviceTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-pro-serviceTests/Pods-pro-serviceTests.release.xcconfig"; sourceTree = ""; }; + EB6D1A5980287675EC91E918 /* Pods-pro-service.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-pro-service.release.xcconfig"; path = "Pods/Target Support Files/Pods-pro-service/Pods-pro-service.release.xcconfig"; sourceTree = ""; }; + FA2D946A2290C7EB0011D063 /* SearchViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SearchViewController.h; sourceTree = ""; }; + FA2D946B2290C7EB0011D063 /* SearchViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SearchViewController.m; sourceTree = ""; }; + FA2D946E2290C89A0011D063 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/Main.strings; sourceTree = ""; }; + FA2D946F2290C89A0011D063 /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = ru.lproj/LaunchScreen.strings; sourceTree = ""; }; + FA2D94B12290F8020011D063 /* SearchTableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SearchTableViewCell.h; sourceTree = ""; }; + FA2D94B22290F8020011D063 /* SearchTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SearchTableViewCell.m; sourceTree = ""; }; + FA2D94B32290F8020011D063 /* SearchTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = SearchTableViewCell.xib; sourceTree = ""; }; + FA3EC87E229600D700D74B8C /* EventViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EventViewController.h; sourceTree = ""; }; + FA3EC87F229600D700D74B8C /* EventViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EventViewController.m; sourceTree = ""; }; + FA3EC885229605ED00D74B8C /* HeaderEventTableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = HeaderEventTableViewCell.h; sourceTree = ""; }; + FA3EC886229605ED00D74B8C /* HeaderEventTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = HeaderEventTableViewCell.m; sourceTree = ""; }; + FA3EC887229605ED00D74B8C /* HeaderEventTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HeaderEventTableViewCell.xib; sourceTree = ""; }; + FA3EC88B2296099E00D74B8C /* ImagesEventTableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImagesEventTableViewCell.h; sourceTree = ""; }; + FA3EC88C2296099E00D74B8C /* ImagesEventTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ImagesEventTableViewCell.m; sourceTree = ""; }; + FA3EC88D2296099E00D74B8C /* ImagesEventTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ImagesEventTableViewCell.xib; sourceTree = ""; }; + FA3EC89122960B2E00D74B8C /* FooterEventTableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FooterEventTableViewCell.h; sourceTree = ""; }; + FA3EC89222960B2E00D74B8C /* FooterEventTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FooterEventTableViewCell.m; sourceTree = ""; }; + FA3EC89322960B2E00D74B8C /* FooterEventTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = FooterEventTableViewCell.xib; sourceTree = ""; }; + FA3EC8972296131900D74B8C /* ImageEventCollectionViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImageEventCollectionViewCell.h; sourceTree = ""; }; + FA3EC8982296131900D74B8C /* ImageEventCollectionViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ImageEventCollectionViewCell.m; sourceTree = ""; }; + FA3EC8992296131900D74B8C /* ImageEventCollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ImageEventCollectionViewCell.xib; sourceTree = ""; }; + FA3EC8A322961CBF00D74B8C /* PlugEventTableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PlugEventTableViewCell.h; sourceTree = ""; }; + FA3EC8A422961CBF00D74B8C /* PlugEventTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = PlugEventTableViewCell.m; sourceTree = ""; }; + FA3EC8A522961CBF00D74B8C /* PlugEventTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = PlugEventTableViewCell.xib; sourceTree = ""; }; + FA553D0A2296DFBB00F6912F /* CalendarViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CalendarViewController.h; sourceTree = ""; }; + FA553D0B2296DFBC00F6912F /* CalendarViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CalendarViewController.m; sourceTree = ""; }; + FA67DB1C228CC365001E5655 /* Defines.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Defines.h; sourceTree = ""; }; + FA67DB1E228CC472001E5655 /* PrefixHeader.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PrefixHeader.pch; sourceTree = ""; }; + FA74F4A7228B208200DDF9E4 /* MainCollectionViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MainCollectionViewCell.h; sourceTree = ""; }; + FA74F4A8228B208200DDF9E4 /* MainCollectionViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MainCollectionViewCell.m; sourceTree = ""; }; + FA74F4A9228B208200DDF9E4 /* MainCollectionViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainCollectionViewCell.xib; sourceTree = ""; }; + FA74F4B1228B263B00DDF9E4 /* CategoryViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CategoryViewController.h; sourceTree = ""; }; + FA74F4B2228B263B00DDF9E4 /* CategoryViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CategoryViewController.m; sourceTree = ""; }; + FA74F4B5228B274200DDF9E4 /* CategoryTableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CategoryTableViewCell.h; sourceTree = ""; }; + FA74F4B6228B274200DDF9E4 /* CategoryTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CategoryTableViewCell.m; sourceTree = ""; }; + FA74F4B7228B274200DDF9E4 /* CategoryTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CategoryTableViewCell.xib; sourceTree = ""; }; + FA8BBD9422945CF500DB52BA /* EventListViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = EventListViewController.h; sourceTree = ""; }; + FA8BBD9522945CF500DB52BA /* EventListViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = EventListViewController.m; sourceTree = ""; }; + FA98C362228A33C6002D49AF /* pro-service.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "pro-service.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + FA98C365228A33C6002D49AF /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + FA98C366228A33C6002D49AF /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + FA98C36C228A33C6002D49AF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + FA98C36E228A33C8002D49AF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + FA98C371228A33C8002D49AF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + FA98C373228A33C8002D49AF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + FA98C374228A33C8002D49AF /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + FA98C37A228A33C9002D49AF /* pro-serviceTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "pro-serviceTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + FA98C37E228A33C9002D49AF /* pro_serviceTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = pro_serviceTests.m; sourceTree = ""; }; + FA98C380228A33C9002D49AF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + FA98C385228A33C9002D49AF /* pro-serviceUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "pro-serviceUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; + FA98C389228A33C9002D49AF /* pro_serviceUITests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = pro_serviceUITests.m; sourceTree = ""; }; + FA98C38B228A33C9002D49AF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + FA98C397228A3436002D49AF /* MainViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MainViewController.h; sourceTree = ""; }; + FA98C398228A3436002D49AF /* MainViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MainViewController.m; sourceTree = ""; }; + FA98C39A228A4C1C002D49AF /* MainTableViewCell.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MainTableViewCell.h; sourceTree = ""; }; + FA98C39B228A4C1C002D49AF /* MainTableViewCell.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MainTableViewCell.m; sourceTree = ""; }; + FA98C39C228A4C1C002D49AF /* MainTableViewCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainTableViewCell.xib; sourceTree = ""; }; + FAEBC3D82293084400A4D033 /* DateViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DateViewController.h; sourceTree = ""; }; + FAEBC3D92293084400A4D033 /* DateViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DateViewController.m; sourceTree = ""; }; + FAEBC3DC2293649400A4D033 /* SearchCategoryViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SearchCategoryViewController.h; sourceTree = ""; }; + FAEBC3DD2293649400A4D033 /* SearchCategoryViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SearchCategoryViewController.m; sourceTree = ""; }; + FAEBC3E02293776600A4D033 /* Event.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Event.h; sourceTree = ""; }; + FAEBC3E12293776600A4D033 /* Event.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Event.m; sourceTree = ""; }; + FAEBC3E52293795A00A4D033 /* Calendar.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Calendar.h; sourceTree = ""; }; + FAEBC3E62293795A00A4D033 /* Calendar.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Calendar.m; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + FA98C35F228A33C6002D49AF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + DCFCBCA1034496A1F4653AD3 /* Pods_pro_service.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FA98C377228A33C9002D49AF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + D93C58F3689579B7FE9CB614 /* Pods_pro_serviceTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FA98C382228A33C9002D49AF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 35943836CF0B4AF2F6E43797 /* Pods_pro_serviceUITests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + E2BFD8D5A29B2869FDE500A5 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 3B5C5A81DBD109C41DCBDDD4 /* Pods_pro_service.framework */, + 64B80F5FFAE6482A713F6A7C /* Pods_pro_serviceTests.framework */, + 05C08B0D6D9C3740DDE349E1 /* Pods_pro_serviceUITests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + FA2D946D2290C7EE0011D063 /* SearchViewController */ = { + isa = PBXGroup; + children = ( + FA2D946A2290C7EB0011D063 /* SearchViewController.h */, + FA2D946B2290C7EB0011D063 /* SearchViewController.m */, + ); + path = SearchViewController; + sourceTree = ""; + }; + FA2D94B62290F8040011D063 /* SearchTableViewCell */ = { + isa = PBXGroup; + children = ( + FA2D94B12290F8020011D063 /* SearchTableViewCell.h */, + FA2D94B22290F8020011D063 /* SearchTableViewCell.m */, + FA2D94B32290F8020011D063 /* SearchTableViewCell.xib */, + ); + path = SearchTableViewCell; + sourceTree = ""; + }; + FA3EC881229600DA00D74B8C /* EventViewController */ = { + isa = PBXGroup; + children = ( + FA3EC87E229600D700D74B8C /* EventViewController.h */, + FA3EC87F229600D700D74B8C /* EventViewController.m */, + ); + path = EventViewController; + sourceTree = ""; + }; + FA3EC88A229605F000D74B8C /* HeaderEventTableViewCell */ = { + isa = PBXGroup; + children = ( + FA3EC885229605ED00D74B8C /* HeaderEventTableViewCell.h */, + FA3EC886229605ED00D74B8C /* HeaderEventTableViewCell.m */, + FA3EC887229605ED00D74B8C /* HeaderEventTableViewCell.xib */, + ); + path = HeaderEventTableViewCell; + sourceTree = ""; + }; + FA3EC890229609A100D74B8C /* ImagesEventTableViewCell */ = { + isa = PBXGroup; + children = ( + FA3EC88B2296099E00D74B8C /* ImagesEventTableViewCell.h */, + FA3EC88C2296099E00D74B8C /* ImagesEventTableViewCell.m */, + FA3EC88D2296099E00D74B8C /* ImagesEventTableViewCell.xib */, + ); + path = ImagesEventTableViewCell; + sourceTree = ""; + }; + FA3EC89622960B3100D74B8C /* FooterEventTableViewCell */ = { + isa = PBXGroup; + children = ( + FA3EC89122960B2E00D74B8C /* FooterEventTableViewCell.h */, + FA3EC89222960B2E00D74B8C /* FooterEventTableViewCell.m */, + FA3EC89322960B2E00D74B8C /* FooterEventTableViewCell.xib */, + ); + path = FooterEventTableViewCell; + sourceTree = ""; + }; + FA3EC89C2296131C00D74B8C /* ImageEventCollectionViewCell */ = { + isa = PBXGroup; + children = ( + FA3EC8972296131900D74B8C /* ImageEventCollectionViewCell.h */, + FA3EC8982296131900D74B8C /* ImageEventCollectionViewCell.m */, + FA3EC8992296131900D74B8C /* ImageEventCollectionViewCell.xib */, + ); + path = ImageEventCollectionViewCell; + sourceTree = ""; + }; + FA3EC8A822961CC300D74B8C /* PlugEventTableViewCell */ = { + isa = PBXGroup; + children = ( + FA3EC8A322961CBF00D74B8C /* PlugEventTableViewCell.h */, + FA3EC8A422961CBF00D74B8C /* PlugEventTableViewCell.m */, + FA3EC8A522961CBF00D74B8C /* PlugEventTableViewCell.xib */, + ); + path = PlugEventTableViewCell; + sourceTree = ""; + }; + FA553D0D2296DFC100F6912F /* CalendarViewController */ = { + isa = PBXGroup; + children = ( + FA553D0A2296DFBB00F6912F /* CalendarViewController.h */, + FA553D0B2296DFBC00F6912F /* CalendarViewController.m */, + ); + path = CalendarViewController; + sourceTree = ""; + }; + FA67DB1D228CC376001E5655 /* Supporting */ = { + isa = PBXGroup; + children = ( + FA67DB1E228CC472001E5655 /* PrefixHeader.pch */, + FA67DB1C228CC365001E5655 /* Defines.h */, + FA98C373228A33C8002D49AF /* Info.plist */, + FA98C374228A33C8002D49AF /* main.m */, + ); + path = Supporting; + sourceTree = ""; + }; + FA74F4AC228B25ED00DDF9E4 /* MainCollectionViewCell */ = { + isa = PBXGroup; + children = ( + FA74F4A7228B208200DDF9E4 /* MainCollectionViewCell.h */, + FA74F4A8228B208200DDF9E4 /* MainCollectionViewCell.m */, + FA74F4A9228B208200DDF9E4 /* MainCollectionViewCell.xib */, + ); + path = MainCollectionViewCell; + sourceTree = ""; + }; + FA74F4AD228B25F900DDF9E4 /* MainTableViewCell */ = { + isa = PBXGroup; + children = ( + FA98C39A228A4C1C002D49AF /* MainTableViewCell.h */, + FA98C39B228A4C1C002D49AF /* MainTableViewCell.m */, + FA98C39C228A4C1C002D49AF /* MainTableViewCell.xib */, + ); + path = MainTableViewCell; + sourceTree = ""; + }; + FA74F4AE228B25FE00DDF9E4 /* View */ = { + isa = PBXGroup; + children = ( + FA74F4AC228B25ED00DDF9E4 /* MainCollectionViewCell */, + FA74F4AD228B25F900DDF9E4 /* MainTableViewCell */, + FA74F4BA228B274500DDF9E4 /* CategoryTableViewCell */, + FA2D94B62290F8040011D063 /* SearchTableViewCell */, + FA3EC88A229605F000D74B8C /* HeaderEventTableViewCell */, + FA3EC890229609A100D74B8C /* ImagesEventTableViewCell */, + FA3EC89622960B3100D74B8C /* FooterEventTableViewCell */, + FA3EC89C2296131C00D74B8C /* ImageEventCollectionViewCell */, + FA3EC8A822961CC300D74B8C /* PlugEventTableViewCell */, + ); + path = View; + sourceTree = ""; + }; + FA74F4AF228B260500DDF9E4 /* Controller */ = { + isa = PBXGroup; + children = ( + FA74F4B0228B261200DDF9E4 /* MainViewController */, + FA553D0D2296DFC100F6912F /* CalendarViewController */, + FA74F4B4228B263F00DDF9E4 /* CategoryViewController */, + FA2D946D2290C7EE0011D063 /* SearchViewController */, + FAEBC3DF2293649900A4D033 /* SearchCategoryViewController */, + FAEBC3DB2293084700A4D033 /* DateViewController */, + FA8BBD9722945CF900DB52BA /* EventListViewController */, + FA3EC881229600DA00D74B8C /* EventViewController */, + ); + path = Controller; + sourceTree = ""; + }; + FA74F4B0228B261200DDF9E4 /* MainViewController */ = { + isa = PBXGroup; + children = ( + FA98C397228A3436002D49AF /* MainViewController.h */, + FA98C398228A3436002D49AF /* MainViewController.m */, + ); + path = MainViewController; + sourceTree = ""; + }; + FA74F4B4228B263F00DDF9E4 /* CategoryViewController */ = { + isa = PBXGroup; + children = ( + FA74F4B1228B263B00DDF9E4 /* CategoryViewController.h */, + FA74F4B2228B263B00DDF9E4 /* CategoryViewController.m */, + ); + path = CategoryViewController; + sourceTree = ""; + }; + FA74F4BA228B274500DDF9E4 /* CategoryTableViewCell */ = { + isa = PBXGroup; + children = ( + FA74F4B5228B274200DDF9E4 /* CategoryTableViewCell.h */, + FA74F4B6228B274200DDF9E4 /* CategoryTableViewCell.m */, + FA74F4B7228B274200DDF9E4 /* CategoryTableViewCell.xib */, + ); + path = CategoryTableViewCell; + sourceTree = ""; + }; + FA8BBD9722945CF900DB52BA /* EventListViewController */ = { + isa = PBXGroup; + children = ( + FA8BBD9422945CF500DB52BA /* EventListViewController.h */, + FA8BBD9522945CF500DB52BA /* EventListViewController.m */, + ); + path = EventListViewController; + sourceTree = ""; + }; + FA98C359228A33C6002D49AF = { + isa = PBXGroup; + children = ( + FA98C364228A33C6002D49AF /* pro-service */, + FA98C37D228A33C9002D49AF /* pro-serviceTests */, + FA98C388228A33C9002D49AF /* pro-serviceUITests */, + FA98C363228A33C6002D49AF /* Products */, + FF9BBBB72CD18273CAABDF6F /* Pods */, + E2BFD8D5A29B2869FDE500A5 /* Frameworks */, + ); + sourceTree = ""; + }; + FA98C363228A33C6002D49AF /* Products */ = { + isa = PBXGroup; + children = ( + FA98C362228A33C6002D49AF /* pro-service.app */, + FA98C37A228A33C9002D49AF /* pro-serviceTests.xctest */, + FA98C385228A33C9002D49AF /* pro-serviceUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + FA98C364228A33C6002D49AF /* pro-service */ = { + isa = PBXGroup; + children = ( + FA98C365228A33C6002D49AF /* AppDelegate.h */, + FA98C366228A33C6002D49AF /* AppDelegate.m */, + FAEBC3E42293777400A4D033 /* Model */, + FA74F4AE228B25FE00DDF9E4 /* View */, + FA74F4AF228B260500DDF9E4 /* Controller */, + FA98C36B228A33C6002D49AF /* Main.storyboard */, + FA98C370228A33C8002D49AF /* LaunchScreen.storyboard */, + FA98C36E228A33C8002D49AF /* Assets.xcassets */, + FA67DB1D228CC376001E5655 /* Supporting */, + ); + path = "pro-service"; + sourceTree = ""; + }; + FA98C37D228A33C9002D49AF /* pro-serviceTests */ = { + isa = PBXGroup; + children = ( + FA98C37E228A33C9002D49AF /* pro_serviceTests.m */, + FA98C380228A33C9002D49AF /* Info.plist */, + ); + path = "pro-serviceTests"; + sourceTree = ""; + }; + FA98C388228A33C9002D49AF /* pro-serviceUITests */ = { + isa = PBXGroup; + children = ( + FA98C389228A33C9002D49AF /* pro_serviceUITests.m */, + FA98C38B228A33C9002D49AF /* Info.plist */, + ); + path = "pro-serviceUITests"; + sourceTree = ""; + }; + FAEBC3DB2293084700A4D033 /* DateViewController */ = { + isa = PBXGroup; + children = ( + FAEBC3D82293084400A4D033 /* DateViewController.h */, + FAEBC3D92293084400A4D033 /* DateViewController.m */, + ); + path = DateViewController; + sourceTree = ""; + }; + FAEBC3DF2293649900A4D033 /* SearchCategoryViewController */ = { + isa = PBXGroup; + children = ( + FAEBC3DC2293649400A4D033 /* SearchCategoryViewController.h */, + FAEBC3DD2293649400A4D033 /* SearchCategoryViewController.m */, + ); + path = SearchCategoryViewController; + sourceTree = ""; + }; + FAEBC3E32293776F00A4D033 /* Event */ = { + isa = PBXGroup; + children = ( + FAEBC3E02293776600A4D033 /* Event.h */, + FAEBC3E12293776600A4D033 /* Event.m */, + ); + path = Event; + sourceTree = ""; + }; + FAEBC3E42293777400A4D033 /* Model */ = { + isa = PBXGroup; + children = ( + FAEBC3E32293776F00A4D033 /* Event */, + FAEBC3E82293795D00A4D033 /* Calendar */, + ); + path = Model; + sourceTree = ""; + }; + FAEBC3E82293795D00A4D033 /* Calendar */ = { + isa = PBXGroup; + children = ( + FAEBC3E52293795A00A4D033 /* Calendar.h */, + FAEBC3E62293795A00A4D033 /* Calendar.m */, + ); + path = Calendar; + sourceTree = ""; + }; + FF9BBBB72CD18273CAABDF6F /* Pods */ = { + isa = PBXGroup; + children = ( + 3D7AA8BBFF14424812C3B62D /* Pods-pro-service.debug.xcconfig */, + EB6D1A5980287675EC91E918 /* Pods-pro-service.release.xcconfig */, + 6F38EFE0F9BF2B4313AC1B09 /* Pods-pro-serviceTests.debug.xcconfig */, + B147E7AD79F38B84EEFFC47D /* Pods-pro-serviceTests.release.xcconfig */, + 3D4C77CBF6B87B9FAC3EF320 /* Pods-pro-serviceUITests.debug.xcconfig */, + 353B757899117F1651679105 /* Pods-pro-serviceUITests.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + FA98C361228A33C6002D49AF /* pro-service */ = { + isa = PBXNativeTarget; + buildConfigurationList = FA98C38E228A33C9002D49AF /* Build configuration list for PBXNativeTarget "pro-service" */; + buildPhases = ( + DEF1D069989979090D9477BF /* [CP] Check Pods Manifest.lock */, + FA98C35E228A33C6002D49AF /* Sources */, + FA98C35F228A33C6002D49AF /* Frameworks */, + FA98C360228A33C6002D49AF /* Resources */, + 26D22EE384B6AC480E5AA9D2 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "pro-service"; + productName = "pro-service"; + productReference = FA98C362228A33C6002D49AF /* pro-service.app */; + productType = "com.apple.product-type.application"; + }; + FA98C379228A33C9002D49AF /* pro-serviceTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = FA98C391228A33C9002D49AF /* Build configuration list for PBXNativeTarget "pro-serviceTests" */; + buildPhases = ( + 4BCE0D660F7CCC8720D80ECA /* [CP] Check Pods Manifest.lock */, + FA98C376228A33C9002D49AF /* Sources */, + FA98C377228A33C9002D49AF /* Frameworks */, + FA98C378228A33C9002D49AF /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + FA98C37C228A33C9002D49AF /* PBXTargetDependency */, + ); + name = "pro-serviceTests"; + productName = "pro-serviceTests"; + productReference = FA98C37A228A33C9002D49AF /* pro-serviceTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + FA98C384228A33C9002D49AF /* pro-serviceUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = FA98C394228A33C9002D49AF /* Build configuration list for PBXNativeTarget "pro-serviceUITests" */; + buildPhases = ( + 22934A1D69FFEEE4AB85E465 /* [CP] Check Pods Manifest.lock */, + FA98C381228A33C9002D49AF /* Sources */, + FA98C382228A33C9002D49AF /* Frameworks */, + FA98C383228A33C9002D49AF /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + FA98C387228A33C9002D49AF /* PBXTargetDependency */, + ); + name = "pro-serviceUITests"; + productName = "pro-serviceUITests"; + productReference = FA98C385228A33C9002D49AF /* pro-serviceUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + FA98C35A228A33C6002D49AF /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1010; + ORGANIZATIONNAME = "Александр Мишаков"; + TargetAttributes = { + FA98C361228A33C6002D49AF = { + CreatedOnToolsVersion = 10.1; + }; + FA98C379228A33C9002D49AF = { + CreatedOnToolsVersion = 10.1; + TestTargetID = FA98C361228A33C6002D49AF; + }; + FA98C384228A33C9002D49AF = { + CreatedOnToolsVersion = 10.1; + TestTargetID = FA98C361228A33C6002D49AF; + }; + }; + }; + buildConfigurationList = FA98C35D228A33C6002D49AF /* Build configuration list for PBXProject "pro-service" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = FA98C359228A33C6002D49AF; + productRefGroup = FA98C363228A33C6002D49AF /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + FA98C361228A33C6002D49AF /* pro-service */, + FA98C379228A33C9002D49AF /* pro-serviceTests */, + FA98C384228A33C9002D49AF /* pro-serviceUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + FA98C360228A33C6002D49AF /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FA3EC889229605ED00D74B8C /* HeaderEventTableViewCell.xib in Resources */, + FA3EC88F2296099E00D74B8C /* ImagesEventTableViewCell.xib in Resources */, + FA3EC8A722961CBF00D74B8C /* PlugEventTableViewCell.xib in Resources */, + FA2D94B52290F8020011D063 /* SearchTableViewCell.xib in Resources */, + FA74F4B9228B274200DDF9E4 /* CategoryTableViewCell.xib in Resources */, + FA74F4AB228B208200DDF9E4 /* MainCollectionViewCell.xib in Resources */, + FA98C372228A33C8002D49AF /* LaunchScreen.storyboard in Resources */, + FA98C36F228A33C8002D49AF /* Assets.xcassets in Resources */, + FA3EC89522960B2E00D74B8C /* FooterEventTableViewCell.xib in Resources */, + FA98C39E228A4C1C002D49AF /* MainTableViewCell.xib in Resources */, + FA3EC89B2296131900D74B8C /* ImageEventCollectionViewCell.xib in Resources */, + FA98C36D228A33C6002D49AF /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FA98C378228A33C9002D49AF /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FA98C383228A33C9002D49AF /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 22934A1D69FFEEE4AB85E465 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-pro-serviceUITests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 26D22EE384B6AC480E5AA9D2 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-pro-service/Pods-pro-service-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/FSCalendar+Persian/FSCalendar_Persian.framework", + "${BUILT_PRODUCTS_DIR}/SPStorkController/SPStorkController.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FSCalendar_Persian.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SPStorkController.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-pro-service/Pods-pro-service-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 4BCE0D660F7CCC8720D80ECA /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-pro-serviceTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + DEF1D069989979090D9477BF /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-pro-service-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + FA98C35E228A33C6002D49AF /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FA98C375228A33C8002D49AF /* main.m in Sources */, + FA3EC888229605ED00D74B8C /* HeaderEventTableViewCell.m in Sources */, + FA3EC880229600D700D74B8C /* EventViewController.m in Sources */, + FA3EC89422960B2E00D74B8C /* FooterEventTableViewCell.m in Sources */, + FAEBC3DA2293084400A4D033 /* DateViewController.m in Sources */, + FA3EC89A2296131900D74B8C /* ImageEventCollectionViewCell.m in Sources */, + FA3EC8A622961CBF00D74B8C /* PlugEventTableViewCell.m in Sources */, + FAEBC3E22293776600A4D033 /* Event.m in Sources */, + FA98C367228A33C6002D49AF /* AppDelegate.m in Sources */, + FA74F4AA228B208200DDF9E4 /* MainCollectionViewCell.m in Sources */, + FA2D946C2290C7EB0011D063 /* SearchViewController.m in Sources */, + FAEBC3E72293795A00A4D033 /* Calendar.m in Sources */, + FA74F4B8228B274200DDF9E4 /* CategoryTableViewCell.m in Sources */, + FA553D0C2296DFBC00F6912F /* CalendarViewController.m in Sources */, + FA98C39D228A4C1C002D49AF /* MainTableViewCell.m in Sources */, + FA8BBD9622945CF500DB52BA /* EventListViewController.m in Sources */, + FAEBC3DE2293649400A4D033 /* SearchCategoryViewController.m in Sources */, + FA3EC88E2296099E00D74B8C /* ImagesEventTableViewCell.m in Sources */, + FA74F4B3228B263B00DDF9E4 /* CategoryViewController.m in Sources */, + FA98C399228A3436002D49AF /* MainViewController.m in Sources */, + FA2D94B42290F8020011D063 /* SearchTableViewCell.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FA98C376228A33C9002D49AF /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FA98C37F228A33C9002D49AF /* pro_serviceTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + FA98C381228A33C9002D49AF /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + FA98C38A228A33C9002D49AF /* pro_serviceUITests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + FA98C37C228A33C9002D49AF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = FA98C361228A33C6002D49AF /* pro-service */; + targetProxy = FA98C37B228A33C9002D49AF /* PBXContainerItemProxy */; + }; + FA98C387228A33C9002D49AF /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = FA98C361228A33C6002D49AF /* pro-service */; + targetProxy = FA98C386228A33C9002D49AF /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + FA98C36B228A33C6002D49AF /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + FA98C36C228A33C6002D49AF /* Base */, + FA2D946E2290C89A0011D063 /* ru */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + FA98C370228A33C8002D49AF /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + FA98C371228A33C8002D49AF /* Base */, + FA2D946F2290C89A0011D063 /* ru */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + FA98C38C228A33C9002D49AF /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + FA98C38D228A33C9002D49AF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + FA98C38F228A33C9002D49AF /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3D7AA8BBFF14424812C3B62D /* Pods-pro-service.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = NF5Y2R3TMJ; + GCC_PREFIX_HEADER = "pro-service/Supporting/PrefixHeader.pch"; + INFOPLIST_FILE = "pro-service/Supporting/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.ab.pro-service"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Debug; + }; + FA98C390228A33C9002D49AF /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = EB6D1A5980287675EC91E918 /* Pods-pro-service.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = NF5Y2R3TMJ; + GCC_PREFIX_HEADER = "pro-service/Supporting/PrefixHeader.pch"; + INFOPLIST_FILE = "pro-service/Supporting/Info.plist"; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.ab.pro-service"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Release; + }; + FA98C392228A33C9002D49AF /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 6F38EFE0F9BF2B4313AC1B09 /* Pods-pro-serviceTests.debug.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 5WY752BKP8; + INFOPLIST_FILE = "pro-serviceTests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.ab.pro-serviceTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/pro-service.app/pro-service"; + }; + name = Debug; + }; + FA98C393228A33C9002D49AF /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B147E7AD79F38B84EEFFC47D /* Pods-pro-serviceTests.release.xcconfig */; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 5WY752BKP8; + INFOPLIST_FILE = "pro-serviceTests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.ab.pro-serviceTests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/pro-service.app/pro-service"; + }; + name = Release; + }; + FA98C395228A33C9002D49AF /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3D4C77CBF6B87B9FAC3EF320 /* Pods-pro-serviceUITests.debug.xcconfig */; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 5WY752BKP8; + INFOPLIST_FILE = "pro-serviceUITests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.ab.pro-serviceUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "pro-service"; + }; + name = Debug; + }; + FA98C396228A33C9002D49AF /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 353B757899117F1651679105 /* Pods-pro-serviceUITests.release.xcconfig */; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 5WY752BKP8; + INFOPLIST_FILE = "pro-serviceUITests/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@loader_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = "com.ab.pro-serviceUITests"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = "pro-service"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + FA98C35D228A33C6002D49AF /* Build configuration list for PBXProject "pro-service" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FA98C38C228A33C9002D49AF /* Debug */, + FA98C38D228A33C9002D49AF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + FA98C38E228A33C9002D49AF /* Build configuration list for PBXNativeTarget "pro-service" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FA98C38F228A33C9002D49AF /* Debug */, + FA98C390228A33C9002D49AF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + FA98C391228A33C9002D49AF /* Build configuration list for PBXNativeTarget "pro-serviceTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FA98C392228A33C9002D49AF /* Debug */, + FA98C393228A33C9002D49AF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + FA98C394228A33C9002D49AF /* Build configuration list for PBXNativeTarget "pro-serviceUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + FA98C395228A33C9002D49AF /* Debug */, + FA98C396228A33C9002D49AF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = FA98C35A228A33C6002D49AF /* Project object */; +} diff --git a/pro-service.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/pro-service.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..7166546 --- /dev/null +++ b/pro-service.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/pro-service.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/pro-service.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/pro-service.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/pro-service.xcodeproj/project.xcworkspace/xcuserdata/alex.xcuserdatad/UserInterfaceState.xcuserstate b/pro-service.xcodeproj/project.xcworkspace/xcuserdata/alex.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..93fa3ed Binary files /dev/null and b/pro-service.xcodeproj/project.xcworkspace/xcuserdata/alex.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/pro-service.xcodeproj/xcuserdata/alex.xcuserdatad/xcschemes/xcschememanagement.plist b/pro-service.xcodeproj/xcuserdata/alex.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..e841518 --- /dev/null +++ b/pro-service.xcodeproj/xcuserdata/alex.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + pro-service.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/pro-service.xcworkspace/contents.xcworkspacedata b/pro-service.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..ca9f7b2 --- /dev/null +++ b/pro-service.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/pro-service.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/pro-service.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/pro-service.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/pro-service.xcworkspace/xcuserdata/alex.xcuserdatad/UserInterfaceState.xcuserstate b/pro-service.xcworkspace/xcuserdata/alex.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..f4c4917 Binary files /dev/null and b/pro-service.xcworkspace/xcuserdata/alex.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/pro-service.xcworkspace/xcuserdata/alex.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist b/pro-service.xcworkspace/xcuserdata/alex.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist new file mode 100644 index 0000000..ed9a9b4 --- /dev/null +++ b/pro-service.xcworkspace/xcuserdata/alex.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist @@ -0,0 +1,5 @@ + + + diff --git a/pro-service/AppDelegate.h b/pro-service/AppDelegate.h new file mode 100644 index 0000000..7aa4cd1 --- /dev/null +++ b/pro-service/AppDelegate.h @@ -0,0 +1,17 @@ +// +// AppDelegate.h +// pro-service +// +// Created by Александр Мишаков on 14/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import + +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; + + +@end + diff --git a/pro-service/AppDelegate.m b/pro-service/AppDelegate.m new file mode 100644 index 0000000..b7ca984 --- /dev/null +++ b/pro-service/AppDelegate.m @@ -0,0 +1,54 @@ +// +// AppDelegate.m +// pro-service +// +// Created by Александр Мишаков on 14/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import "AppDelegate.h" + +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + + self.window.backgroundColor = [UIColor whiteColor]; + + return YES; +} + + +- (void)applicationWillResignActive:(UIApplication *)application { + // 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. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. +} + + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // 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. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // 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. +} + + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // 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. +} + + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + + +@end diff --git a/pro-service/Assets.xcassets/AppIcon.appiconset/Contents.json b/pro-service/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/pro-service/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/pro-service/Assets.xcassets/Contents.json b/pro-service/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/pro-service/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/pro-service/Assets.xcassets/Graphics - Tab Bar Icons - Gray - Today.imageset/Contents.json b/pro-service/Assets.xcassets/Graphics - Tab Bar Icons - Gray - Today.imageset/Contents.json new file mode 100644 index 0000000..c0e4eb3 --- /dev/null +++ b/pro-service/Assets.xcassets/Graphics - Tab Bar Icons - Gray - Today.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Graphics - Tab Bar Icons - Gray - Today.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Graphics - Tab Bar Icons - Gray - Today@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "Graphics - Tab Bar Icons - Gray - Today@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/pro-service/Assets.xcassets/Graphics - Tab Bar Icons - Gray - Today.imageset/Graphics - Tab Bar Icons - Gray - Today.png b/pro-service/Assets.xcassets/Graphics - Tab Bar Icons - Gray - Today.imageset/Graphics - Tab Bar Icons - Gray - Today.png new file mode 100644 index 0000000..e30235b Binary files /dev/null and b/pro-service/Assets.xcassets/Graphics - Tab Bar Icons - Gray - Today.imageset/Graphics - Tab Bar Icons - Gray - Today.png differ diff --git a/pro-service/Assets.xcassets/Graphics - Tab Bar Icons - Gray - Today.imageset/Graphics - Tab Bar Icons - Gray - Today@2x.png b/pro-service/Assets.xcassets/Graphics - Tab Bar Icons - Gray - Today.imageset/Graphics - Tab Bar Icons - Gray - Today@2x.png new file mode 100644 index 0000000..a7a6d2f Binary files /dev/null and b/pro-service/Assets.xcassets/Graphics - Tab Bar Icons - Gray - Today.imageset/Graphics - Tab Bar Icons - Gray - Today@2x.png differ diff --git a/pro-service/Assets.xcassets/Graphics - Tab Bar Icons - Gray - Today.imageset/Graphics - Tab Bar Icons - Gray - Today@3x.png b/pro-service/Assets.xcassets/Graphics - Tab Bar Icons - Gray - Today.imageset/Graphics - Tab Bar Icons - Gray - Today@3x.png new file mode 100644 index 0000000..277529c Binary files /dev/null and b/pro-service/Assets.xcassets/Graphics - Tab Bar Icons - Gray - Today.imageset/Graphics - Tab Bar Icons - Gray - Today@3x.png differ diff --git a/pro-service/Assets.xcassets/Search Icon.imageset/Contents.json b/pro-service/Assets.xcassets/Search Icon.imageset/Contents.json new file mode 100644 index 0000000..3c63bfe --- /dev/null +++ b/pro-service/Assets.xcassets/Search Icon.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Search Icon.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Search Icon@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "Search Icon@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/pro-service/Assets.xcassets/Search Icon.imageset/Search Icon.png b/pro-service/Assets.xcassets/Search Icon.imageset/Search Icon.png new file mode 100644 index 0000000..ac4a918 Binary files /dev/null and b/pro-service/Assets.xcassets/Search Icon.imageset/Search Icon.png differ diff --git a/pro-service/Assets.xcassets/Search Icon.imageset/Search Icon@2x.png b/pro-service/Assets.xcassets/Search Icon.imageset/Search Icon@2x.png new file mode 100644 index 0000000..b7b04b1 Binary files /dev/null and b/pro-service/Assets.xcassets/Search Icon.imageset/Search Icon@2x.png differ diff --git a/pro-service/Assets.xcassets/Search Icon.imageset/Search Icon@3x.png b/pro-service/Assets.xcassets/Search Icon.imageset/Search Icon@3x.png new file mode 100644 index 0000000..6ab92d8 Binary files /dev/null and b/pro-service/Assets.xcassets/Search Icon.imageset/Search Icon@3x.png differ diff --git a/pro-service/Assets.xcassets/Userpic Icon.imageset/Contents.json b/pro-service/Assets.xcassets/Userpic Icon.imageset/Contents.json new file mode 100644 index 0000000..12302d7 --- /dev/null +++ b/pro-service/Assets.xcassets/Userpic Icon.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Userpic Icon.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "Userpic Icon@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "Userpic Icon@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/pro-service/Assets.xcassets/Userpic Icon.imageset/Userpic Icon.png b/pro-service/Assets.xcassets/Userpic Icon.imageset/Userpic Icon.png new file mode 100644 index 0000000..af1b468 Binary files /dev/null and b/pro-service/Assets.xcassets/Userpic Icon.imageset/Userpic Icon.png differ diff --git a/pro-service/Assets.xcassets/Userpic Icon.imageset/Userpic Icon@2x.png b/pro-service/Assets.xcassets/Userpic Icon.imageset/Userpic Icon@2x.png new file mode 100644 index 0000000..0091ed3 Binary files /dev/null and b/pro-service/Assets.xcassets/Userpic Icon.imageset/Userpic Icon@2x.png differ diff --git a/pro-service/Assets.xcassets/Userpic Icon.imageset/Userpic Icon@3x.png b/pro-service/Assets.xcassets/Userpic Icon.imageset/Userpic Icon@3x.png new file mode 100644 index 0000000..f76cc6b Binary files /dev/null and b/pro-service/Assets.xcassets/Userpic Icon.imageset/Userpic Icon@3x.png differ diff --git a/pro-service/Assets.xcassets/albums.imageset/Contents.json b/pro-service/Assets.xcassets/albums.imageset/Contents.json new file mode 100644 index 0000000..0118d26 --- /dev/null +++ b/pro-service/Assets.xcassets/albums.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "albums.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "albums@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "albums@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/pro-service/Assets.xcassets/albums.imageset/albums.png b/pro-service/Assets.xcassets/albums.imageset/albums.png new file mode 100644 index 0000000..86af0db Binary files /dev/null and b/pro-service/Assets.xcassets/albums.imageset/albums.png differ diff --git a/pro-service/Assets.xcassets/albums.imageset/albums@2x.png b/pro-service/Assets.xcassets/albums.imageset/albums@2x.png new file mode 100644 index 0000000..b67ad4a Binary files /dev/null and b/pro-service/Assets.xcassets/albums.imageset/albums@2x.png differ diff --git a/pro-service/Assets.xcassets/albums.imageset/albums@3x.png b/pro-service/Assets.xcassets/albums.imageset/albums@3x.png new file mode 100644 index 0000000..6297816 Binary files /dev/null and b/pro-service/Assets.xcassets/albums.imageset/albums@3x.png differ diff --git a/pro-service/Assets.xcassets/clear.imageset/Contents.json b/pro-service/Assets.xcassets/clear.imageset/Contents.json new file mode 100644 index 0000000..5ede011 --- /dev/null +++ b/pro-service/Assets.xcassets/clear.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "clear.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "clear@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "clear@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/pro-service/Assets.xcassets/clear.imageset/clear.png b/pro-service/Assets.xcassets/clear.imageset/clear.png new file mode 100644 index 0000000..2a22654 Binary files /dev/null and b/pro-service/Assets.xcassets/clear.imageset/clear.png differ diff --git a/pro-service/Assets.xcassets/clear.imageset/clear@2x.png b/pro-service/Assets.xcassets/clear.imageset/clear@2x.png new file mode 100644 index 0000000..6d0aad7 Binary files /dev/null and b/pro-service/Assets.xcassets/clear.imageset/clear@2x.png differ diff --git a/pro-service/Assets.xcassets/clear.imageset/clear@3x.png b/pro-service/Assets.xcassets/clear.imageset/clear@3x.png new file mode 100644 index 0000000..9900631 Binary files /dev/null and b/pro-service/Assets.xcassets/clear.imageset/clear@3x.png differ diff --git a/pro-service/Assets.xcassets/clouse-button.imageset/Contents.json b/pro-service/Assets.xcassets/clouse-button.imageset/Contents.json new file mode 100644 index 0000000..1bd86cb --- /dev/null +++ b/pro-service/Assets.xcassets/clouse-button.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "clouse-button.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "clouse-button@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "clouse-button@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/pro-service/Assets.xcassets/clouse-button.imageset/clouse-button.png b/pro-service/Assets.xcassets/clouse-button.imageset/clouse-button.png new file mode 100644 index 0000000..435a015 Binary files /dev/null and b/pro-service/Assets.xcassets/clouse-button.imageset/clouse-button.png differ diff --git a/pro-service/Assets.xcassets/clouse-button.imageset/clouse-button@2x.png b/pro-service/Assets.xcassets/clouse-button.imageset/clouse-button@2x.png new file mode 100644 index 0000000..882bc93 Binary files /dev/null and b/pro-service/Assets.xcassets/clouse-button.imageset/clouse-button@2x.png differ diff --git a/pro-service/Assets.xcassets/clouse-button.imageset/clouse-button@3x.png b/pro-service/Assets.xcassets/clouse-button.imageset/clouse-button@3x.png new file mode 100644 index 0000000..05170f6 Binary files /dev/null and b/pro-service/Assets.xcassets/clouse-button.imageset/clouse-button@3x.png differ diff --git a/pro-service/Assets.xcassets/emoji_amenities.imageset/Contents.json b/pro-service/Assets.xcassets/emoji_amenities.imageset/Contents.json new file mode 100644 index 0000000..be09c64 --- /dev/null +++ b/pro-service/Assets.xcassets/emoji_amenities.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "emoji_amenities.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "emoji_amenities@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "emoji_amenities@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/pro-service/Assets.xcassets/emoji_amenities.imageset/emoji_amenities.png b/pro-service/Assets.xcassets/emoji_amenities.imageset/emoji_amenities.png new file mode 100644 index 0000000..0d48184 Binary files /dev/null and b/pro-service/Assets.xcassets/emoji_amenities.imageset/emoji_amenities.png differ diff --git a/pro-service/Assets.xcassets/emoji_amenities.imageset/emoji_amenities@2x.png b/pro-service/Assets.xcassets/emoji_amenities.imageset/emoji_amenities@2x.png new file mode 100644 index 0000000..9fba83e Binary files /dev/null and b/pro-service/Assets.xcassets/emoji_amenities.imageset/emoji_amenities@2x.png differ diff --git a/pro-service/Assets.xcassets/emoji_amenities.imageset/emoji_amenities@3x.png b/pro-service/Assets.xcassets/emoji_amenities.imageset/emoji_amenities@3x.png new file mode 100644 index 0000000..040654f Binary files /dev/null and b/pro-service/Assets.xcassets/emoji_amenities.imageset/emoji_amenities@3x.png differ diff --git a/pro-service/Assets.xcassets/emoji_cinema.imageset/Contents.json b/pro-service/Assets.xcassets/emoji_cinema.imageset/Contents.json new file mode 100644 index 0000000..a2efd3e --- /dev/null +++ b/pro-service/Assets.xcassets/emoji_cinema.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "emoji_cinema.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "emoji_cinema@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "emoji_cinema@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/pro-service/Assets.xcassets/emoji_cinema.imageset/emoji_cinema.png b/pro-service/Assets.xcassets/emoji_cinema.imageset/emoji_cinema.png new file mode 100644 index 0000000..166341c Binary files /dev/null and b/pro-service/Assets.xcassets/emoji_cinema.imageset/emoji_cinema.png differ diff --git a/pro-service/Assets.xcassets/emoji_cinema.imageset/emoji_cinema@2x.png b/pro-service/Assets.xcassets/emoji_cinema.imageset/emoji_cinema@2x.png new file mode 100644 index 0000000..cc75763 Binary files /dev/null and b/pro-service/Assets.xcassets/emoji_cinema.imageset/emoji_cinema@2x.png differ diff --git a/pro-service/Assets.xcassets/emoji_cinema.imageset/emoji_cinema@3x.png b/pro-service/Assets.xcassets/emoji_cinema.imageset/emoji_cinema@3x.png new file mode 100644 index 0000000..2582a09 Binary files /dev/null and b/pro-service/Assets.xcassets/emoji_cinema.imageset/emoji_cinema@3x.png differ diff --git a/pro-service/Assets.xcassets/emoji_education.imageset/Contents.json b/pro-service/Assets.xcassets/emoji_education.imageset/Contents.json new file mode 100644 index 0000000..c877e25 --- /dev/null +++ b/pro-service/Assets.xcassets/emoji_education.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "emoji_education.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "emoji_education@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "emoji_education@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/pro-service/Assets.xcassets/emoji_education.imageset/emoji_education.png b/pro-service/Assets.xcassets/emoji_education.imageset/emoji_education.png new file mode 100644 index 0000000..be664e9 Binary files /dev/null and b/pro-service/Assets.xcassets/emoji_education.imageset/emoji_education.png differ diff --git a/pro-service/Assets.xcassets/emoji_education.imageset/emoji_education@2x.png b/pro-service/Assets.xcassets/emoji_education.imageset/emoji_education@2x.png new file mode 100644 index 0000000..6611bd8 Binary files /dev/null and b/pro-service/Assets.xcassets/emoji_education.imageset/emoji_education@2x.png differ diff --git a/pro-service/Assets.xcassets/emoji_education.imageset/emoji_education@3x.png b/pro-service/Assets.xcassets/emoji_education.imageset/emoji_education@3x.png new file mode 100644 index 0000000..50817c3 Binary files /dev/null and b/pro-service/Assets.xcassets/emoji_education.imageset/emoji_education@3x.png differ diff --git a/pro-service/Assets.xcassets/emoji_festival.imageset/Contents.json b/pro-service/Assets.xcassets/emoji_festival.imageset/Contents.json new file mode 100644 index 0000000..c2cd55d --- /dev/null +++ b/pro-service/Assets.xcassets/emoji_festival.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "emoji_festival.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "emoji_festival@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "emoji_festival@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/pro-service/Assets.xcassets/emoji_festival.imageset/emoji_festival.png b/pro-service/Assets.xcassets/emoji_festival.imageset/emoji_festival.png new file mode 100644 index 0000000..fcdefc3 Binary files /dev/null and b/pro-service/Assets.xcassets/emoji_festival.imageset/emoji_festival.png differ diff --git a/pro-service/Assets.xcassets/emoji_festival.imageset/emoji_festival@2x.png b/pro-service/Assets.xcassets/emoji_festival.imageset/emoji_festival@2x.png new file mode 100644 index 0000000..64e482b Binary files /dev/null and b/pro-service/Assets.xcassets/emoji_festival.imageset/emoji_festival@2x.png differ diff --git a/pro-service/Assets.xcassets/emoji_festival.imageset/emoji_festival@3x.png b/pro-service/Assets.xcassets/emoji_festival.imageset/emoji_festival@3x.png new file mode 100644 index 0000000..2ac514e Binary files /dev/null and b/pro-service/Assets.xcassets/emoji_festival.imageset/emoji_festival@3x.png differ diff --git a/pro-service/Assets.xcassets/emoji_museum.imageset/Contents.json b/pro-service/Assets.xcassets/emoji_museum.imageset/Contents.json new file mode 100644 index 0000000..a33ed39 --- /dev/null +++ b/pro-service/Assets.xcassets/emoji_museum.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "emoji_museum.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "emoji_museum@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "emoji_museum@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/pro-service/Assets.xcassets/emoji_museum.imageset/emoji_museum.png b/pro-service/Assets.xcassets/emoji_museum.imageset/emoji_museum.png new file mode 100644 index 0000000..9e590d9 Binary files /dev/null and b/pro-service/Assets.xcassets/emoji_museum.imageset/emoji_museum.png differ diff --git a/pro-service/Assets.xcassets/emoji_museum.imageset/emoji_museum@2x.png b/pro-service/Assets.xcassets/emoji_museum.imageset/emoji_museum@2x.png new file mode 100644 index 0000000..dee7639 Binary files /dev/null and b/pro-service/Assets.xcassets/emoji_museum.imageset/emoji_museum@2x.png differ diff --git a/pro-service/Assets.xcassets/emoji_museum.imageset/emoji_museum@3x.png b/pro-service/Assets.xcassets/emoji_museum.imageset/emoji_museum@3x.png new file mode 100644 index 0000000..da4805f Binary files /dev/null and b/pro-service/Assets.xcassets/emoji_museum.imageset/emoji_museum@3x.png differ diff --git a/pro-service/Assets.xcassets/emoji_music.imageset/Contents.json b/pro-service/Assets.xcassets/emoji_music.imageset/Contents.json new file mode 100644 index 0000000..0186648 --- /dev/null +++ b/pro-service/Assets.xcassets/emoji_music.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "emoji_music.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "emoji_music@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "emoji_music@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/pro-service/Assets.xcassets/emoji_music.imageset/emoji_music.png b/pro-service/Assets.xcassets/emoji_music.imageset/emoji_music.png new file mode 100644 index 0000000..7605573 Binary files /dev/null and b/pro-service/Assets.xcassets/emoji_music.imageset/emoji_music.png differ diff --git a/pro-service/Assets.xcassets/emoji_music.imageset/emoji_music@2x.png b/pro-service/Assets.xcassets/emoji_music.imageset/emoji_music@2x.png new file mode 100644 index 0000000..c64edc7 Binary files /dev/null and b/pro-service/Assets.xcassets/emoji_music.imageset/emoji_music@2x.png differ diff --git a/pro-service/Assets.xcassets/emoji_music.imageset/emoji_music@3x.png b/pro-service/Assets.xcassets/emoji_music.imageset/emoji_music@3x.png new file mode 100644 index 0000000..3c3bd6d Binary files /dev/null and b/pro-service/Assets.xcassets/emoji_music.imageset/emoji_music@3x.png differ diff --git a/pro-service/Assets.xcassets/emoji_sport.imageset/Contents.json b/pro-service/Assets.xcassets/emoji_sport.imageset/Contents.json new file mode 100644 index 0000000..31dc44d --- /dev/null +++ b/pro-service/Assets.xcassets/emoji_sport.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "emoji_sport.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "emoji_sport@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "emoji_sport@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/pro-service/Assets.xcassets/emoji_sport.imageset/emoji_sport.png b/pro-service/Assets.xcassets/emoji_sport.imageset/emoji_sport.png new file mode 100644 index 0000000..7fb951c Binary files /dev/null and b/pro-service/Assets.xcassets/emoji_sport.imageset/emoji_sport.png differ diff --git a/pro-service/Assets.xcassets/emoji_sport.imageset/emoji_sport@2x.png b/pro-service/Assets.xcassets/emoji_sport.imageset/emoji_sport@2x.png new file mode 100644 index 0000000..e7e6573 Binary files /dev/null and b/pro-service/Assets.xcassets/emoji_sport.imageset/emoji_sport@2x.png differ diff --git a/pro-service/Assets.xcassets/emoji_sport.imageset/emoji_sport@3x.png b/pro-service/Assets.xcassets/emoji_sport.imageset/emoji_sport@3x.png new file mode 100644 index 0000000..ee78df2 Binary files /dev/null and b/pro-service/Assets.xcassets/emoji_sport.imageset/emoji_sport@3x.png differ diff --git a/pro-service/Assets.xcassets/impressions.imageset/Contents.json b/pro-service/Assets.xcassets/impressions.imageset/Contents.json new file mode 100644 index 0000000..50b5b93 --- /dev/null +++ b/pro-service/Assets.xcassets/impressions.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "impressions.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "impressions@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "impressions@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/pro-service/Assets.xcassets/impressions.imageset/impressions.png b/pro-service/Assets.xcassets/impressions.imageset/impressions.png new file mode 100644 index 0000000..0381dfd Binary files /dev/null and b/pro-service/Assets.xcassets/impressions.imageset/impressions.png differ diff --git a/pro-service/Assets.xcassets/impressions.imageset/impressions@2x.png b/pro-service/Assets.xcassets/impressions.imageset/impressions@2x.png new file mode 100644 index 0000000..9696e75 Binary files /dev/null and b/pro-service/Assets.xcassets/impressions.imageset/impressions@2x.png differ diff --git a/pro-service/Assets.xcassets/impressions.imageset/impressions@3x.png b/pro-service/Assets.xcassets/impressions.imageset/impressions@3x.png new file mode 100644 index 0000000..67adcab Binary files /dev/null and b/pro-service/Assets.xcassets/impressions.imageset/impressions@3x.png differ diff --git a/pro-service/Assets.xcassets/tag.imageset/Contents.json b/pro-service/Assets.xcassets/tag.imageset/Contents.json new file mode 100644 index 0000000..e274a0c --- /dev/null +++ b/pro-service/Assets.xcassets/tag.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "tag.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "tag@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "tag@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/pro-service/Assets.xcassets/tag.imageset/tag.png b/pro-service/Assets.xcassets/tag.imageset/tag.png new file mode 100644 index 0000000..00f546c Binary files /dev/null and b/pro-service/Assets.xcassets/tag.imageset/tag.png differ diff --git a/pro-service/Assets.xcassets/tag.imageset/tag@2x.png b/pro-service/Assets.xcassets/tag.imageset/tag@2x.png new file mode 100644 index 0000000..b63e84a Binary files /dev/null and b/pro-service/Assets.xcassets/tag.imageset/tag@2x.png differ diff --git a/pro-service/Assets.xcassets/tag.imageset/tag@3x.png b/pro-service/Assets.xcassets/tag.imageset/tag@3x.png new file mode 100644 index 0000000..aa216c1 Binary files /dev/null and b/pro-service/Assets.xcassets/tag.imageset/tag@3x.png differ diff --git a/pro-service/Base.lproj/LaunchScreen.storyboard b/pro-service/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..bfa3612 --- /dev/null +++ b/pro-service/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pro-service/Base.lproj/Main.storyboard b/pro-service/Base.lproj/Main.storyboard new file mode 100644 index 0000000..b1ec0ac --- /dev/null +++ b/pro-service/Base.lproj/Main.storyboard @@ -0,0 +1,887 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pro-service/Controller/CalendarViewController/CalendarViewController.h b/pro-service/Controller/CalendarViewController/CalendarViewController.h new file mode 100644 index 0000000..2952e75 --- /dev/null +++ b/pro-service/Controller/CalendarViewController/CalendarViewController.h @@ -0,0 +1,17 @@ +// +// CalendarViewController.h +// pro-service +// +// Created by Александр Мишаков on 16/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface CalendarViewController : UIViewController + +@end + +NS_ASSUME_NONNULL_END diff --git a/pro-service/Controller/CalendarViewController/CalendarViewController.m b/pro-service/Controller/CalendarViewController/CalendarViewController.m new file mode 100644 index 0000000..25375ee --- /dev/null +++ b/pro-service/Controller/CalendarViewController/CalendarViewController.m @@ -0,0 +1,174 @@ +// +// CalendarViewController.m +// pro-service +// +// Created by Александр Мишаков on 16/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import "CalendarViewController.h" +#import "FSCalendar.h" +#import "Calendar.h" +#import "EventListViewController.h" + +@interface CalendarViewController () +{ + CGFloat navHeight; + Calendar *calendarModel; + NSDate *selectDate; +} + +@property (weak, nonatomic) IBOutlet FSCalendar *calendar; + +@property (strong, nonatomic) NSCalendar *gregorian; +@property (strong, nonatomic) NSDateFormatter *dateFormatter; +@property (strong, nonatomic) NSDate *minimumDate; +@property (strong, nonatomic) NSDate *maximumDate; +@property (weak, nonatomic) IBOutlet UIView *header; + + +@end + +@implementation CalendarViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + calendarModel = [[Calendar alloc] init]; + [calendarModel loadAllDay]; + + self.calendar.backgroundColor = [UIColor whiteColor]; + self.calendar.dataSource = self; + self.calendar.delegate = self; + self.calendar.pagingEnabled = NO; + self.calendar.firstWeekday = 2; + self.calendar.placeholderType = FSCalendarPlaceholderTypeNone; + self.calendar.weekdayHeight = 0; + self.calendar.locale = [NSLocale localeWithLocaleIdentifier:@"ru-RU"]; + self.calendar.headerHeight = 50; + self.calendar.rowHeight = 50; + self.calendar.appearance.headerTitleColor = COLOR_MAIN; + self.calendar.appearance.headerTitleFont = [UIFont boldSystemFontOfSize:20]; + self.calendar.appearance.titleFont = [UIFont systemFontOfSize:17]; + self.calendar.appearance.selectionColor = [UIColor colorWithRed:1 green:1 blue:1 alpha:0.7]; + self.calendar.appearance.titleSelectionColor = [UIColor blackColor]; + self.calendar.appearance.todayColor = COLOR_MAIN; + self.calendar.appearance.headerDateFormat = @"MMMM yyyy"; + self.calendar.appearance.eventDefaultColor = COLOR_MAIN; + + + self.gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; + + self.dateFormatter = [[NSDateFormatter alloc] init]; + self.dateFormatter.dateFormat = @"yyyy-MM-dd"; + + self.minimumDate = [NSDate date]; + self.maximumDate = [NSDate date]; + if (calendarModel.allDay.count != 0) + { + self.maximumDate = [self.dateFormatter dateFromString:calendarModel.allDay[calendarModel.allDay.count-1]]; + } + + navHeight = self.navigationController.navigationBar.frame.size.height; + [self headerScroll]; +} + +- (void)viewWillAppear:(BOOL)animated +{ + [self.navigationController.navigationBar setValue:@(YES) forKeyPath:@"hidesShadow"]; + self.navigationController.navigationBar.prefersLargeTitles = true; +} + +// MARK: FSCalendarDataSource + +- (NSDate *)minimumDateForCalendar:(FSCalendar *)calendar +{ + return self.minimumDate; +} + +- (NSDate *)maximumDateForCalendar:(FSCalendar *)calendar +{ + return self.maximumDate; +} + +// MARK: FSCalendarDelegate + +- (void)calendar:(FSCalendar *)calendar didSelectDate:(NSDate *)date atMonthPosition:(FSCalendarMonthPosition)monthPosition +{ + DLog(@"did select %@", [self.dateFormatter stringFromDate:date]); + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.05 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [self.calendar deselectDate:date]; + }); + + selectDate = date; + + if ([calendarModel.allDay containsObject:[self.dateFormatter stringFromDate:date]]) + { + [self performSegueWithIdentifier:@"eventToDate" sender:nil]; + } + else + { + NSLog(@"no date"); + } +} + +- (void)scrollViewDidScroll:(UIScrollView *)scrollView +{ + DLog(@"scrollView: %f", scrollView.contentOffset.y); +} + +- (NSInteger)calendar:(FSCalendar *)calendar numberOfEventsForDate:(NSDate *)date +{ + NSString *dateString = [self.dateFormatter stringFromDate:date]; + if ([calendarModel.allDay containsObject:dateString]) + { + return 1; + } + + return 0; +} + +// ???: Костыль, но работает +// Рекурсивная функция которая проверяет высоту навБара +// и подстаривае дни недели при скролле +- (void)headerScroll +{ +// DLog(@"size: %f", self.navigationController.navigationBar.frame.size.height); + + CGRect frame = self.header.frame; + frame.origin.y = 0; + + if (self.navigationController.navigationBar.frame.size.height > navHeight) + { + frame.origin.y = self.navigationController.navigationBar.frame.size.height-navHeight; + } + + self.header.frame = frame; + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.001 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [self headerScroll]; + }); +} + +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender +{ + if ([segue.identifier isEqualToString:@"eventToDate"]) + { + EventListViewController *vc = segue.destinationViewController; + + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + dateFormatter.dateFormat = @"dd MMMM yyyy"; + [calendarModel loadFromDate:selectDate]; + + NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; + dateFormat.dateFormat = @"HH:mm"; + + vc.navTitle = [dateFormatter stringFromDate:selectDate]; + vc.arrayEvent = calendarModel.today; + vc.dateFormat = dateFormat; + } +} + +@end diff --git a/pro-service/Controller/CategoryViewController/CategoryViewController.h b/pro-service/Controller/CategoryViewController/CategoryViewController.h new file mode 100644 index 0000000..de23b83 --- /dev/null +++ b/pro-service/Controller/CategoryViewController/CategoryViewController.h @@ -0,0 +1,17 @@ +// +// CategoryViewController.h +// pro-service +// +// Created by Александр Мишаков on 14/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface CategoryViewController : UIViewController + +@end + +NS_ASSUME_NONNULL_END diff --git a/pro-service/Controller/CategoryViewController/CategoryViewController.m b/pro-service/Controller/CategoryViewController/CategoryViewController.m new file mode 100644 index 0000000..4d9631d --- /dev/null +++ b/pro-service/Controller/CategoryViewController/CategoryViewController.m @@ -0,0 +1,87 @@ +// +// CategoryViewController.m +// pro-service +// +// Created by Александр Мишаков on 14/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import "CategoryViewController.h" +#import "CategoryTableViewCell.h" +#import "Event.h" +#import "EventListViewController.h" +#import "Calendar.h" + +@interface CategoryViewController () +{ + Event *event; + NSInteger rowSelectIndex; +} + +@property (weak, nonatomic) IBOutlet UITableView *tableView; + +@end + +@implementation CategoryViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + event = [[Event alloc] init]; + + self.tableView.tableFooterView = [UIView new]; +} + +- (void)viewWillAppear:(BOOL)animated +{ + [self.navigationController.navigationBar setValue:@(YES) forKeyPath:@"hidesShadow"]; + self.navigationController.navigationBar.prefersLargeTitles = true; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return event.category.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *CellIdentifier = @"CategoryTableViewCell"; + CategoryTableViewCell *cell = (CategoryTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (cell == nil) + { + NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil]; + cell = [nib objectAtIndex:0]; + } + + cell.titleLabel.text = event.category[indexPath.row][@"title"]; + cell.imageViewIcon.image = [UIImage imageNamed:event.category[indexPath.row][@"imageName"]]; + + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + rowSelectIndex = indexPath.row; + [self performSegueWithIdentifier:@"eventToCategory" sender:nil]; +} + +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender +{ + if ([segue.identifier isEqualToString:@"eventToCategory"]) + { + EventListViewController *vc = segue.destinationViewController; + NSMutableArray *arrayTag = [[NSMutableArray alloc] init]; + [arrayTag addObject:[NSString stringWithFormat:@"%@", event.category[rowSelectIndex][@"id"]]]; + DLog(@"%@", arrayTag); + + Calendar *calendar = [[Calendar alloc] init]; + [calendar loadTag:arrayTag]; + + vc.navTitle = event.category[rowSelectIndex][@"title"]; + vc.arrayEvent = calendar.today; + } +} + +@end diff --git a/pro-service/Controller/DateViewController/DateViewController.h b/pro-service/Controller/DateViewController/DateViewController.h new file mode 100644 index 0000000..c53e96a --- /dev/null +++ b/pro-service/Controller/DateViewController/DateViewController.h @@ -0,0 +1,17 @@ +// +// DateViewController.h +// pro-service +// +// Created by Александр Мишаков on 20/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface DateViewController : UIViewController + +@end + +NS_ASSUME_NONNULL_END diff --git a/pro-service/Controller/DateViewController/DateViewController.m b/pro-service/Controller/DateViewController/DateViewController.m new file mode 100644 index 0000000..a3e9f85 --- /dev/null +++ b/pro-service/Controller/DateViewController/DateViewController.m @@ -0,0 +1,146 @@ +// +// DateViewController.m +// pro-service +// +// Created by Александр Мишаков on 20/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import "DateViewController.h" +#import "Calendar.h" + +@interface DateViewController () +{ + UIPickerView *datePicker; + Calendar *calendar; + NSInteger selectedRow; +} + +@property (weak, nonatomic) UIView *wrapContent; + +@end + +@implementation DateViewController + +-(UIStatusBarStyle)preferredStatusBarStyle +{ + return UIStatusBarStyleLightContent; +} + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + calendar = [[Calendar alloc] init]; + [calendar loadAllDay]; + + self.modalPresentationCapturesStatusBarAppearance = true; + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.01 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + NSArray *viewsToRemove = [self.view subviews]; + for (UIView *v in viewsToRemove) { + [v removeFromSuperview]; + } + + [self crateViews]; + }); +} + +- (void)crateViews +{ + UIView *wrapContent = [[UIView alloc] initWithFrame:CGRectMake(0, self.view.frame.size.height-349, self.view.frame.size.width, 349)]; + wrapContent.backgroundColor = [UIColor whiteColor]; + [self.view addSubview:wrapContent]; + + UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:wrapContent.bounds byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight) cornerRadii:CGSizeMake(10, 10)]; + + CAShapeLayer *maskLayer = [CAShapeLayer layer]; + + maskLayer.frame = wrapContent.bounds; + maskLayer.path = maskPath.CGPath; + + wrapContent.layer.mask = maskLayer; + + UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(16, 16, self.view.frame.size.width-32, 27)]; + titleLabel.text = @"Выберите дату"; + [titleLabel setFont:[UIFont boldSystemFontOfSize:22]]; + + datePicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0, 43, self.view.frame.size.width, 216)]; + datePicker.delegate = self; + datePicker.dataSource = self; + [datePicker selectRow:0 inComponent:0 animated:YES]; + + UIButton *selectButton = [[UIButton alloc] initWithFrame:CGRectMake(16, 259, self.view.frame.size.width-32, 42)]; + selectButton.backgroundColor = [UIColor redColor]; + selectButton.backgroundColor = COLOR_LIGHT_MAIN; + selectButton.layer.cornerRadius = 8; + [selectButton setTitle:@"Выбрать" forState:UIControlStateNormal]; + [selectButton setTitleColor:COLOR_MAIN forState:UIControlStateNormal]; + [selectButton.titleLabel setFont:[UIFont systemFontOfSize:17.0f weight:UIFontWeightMedium]]; + [selectButton addTarget:self action:@selector(buttonTouchSelect:) forControlEvents:UIControlEventTouchUpInside]; + + UIButton *closeButton = [[UIButton alloc] initWithFrame:CGRectMake(self.view.frame.size.width-25-16, 16, 25, 25)]; + [closeButton setBackgroundImage:[UIImage imageNamed:@"clouse-button"] forState:UIControlStateNormal]; + [closeButton addTarget:self action:@selector(buttonTouchExit:) forControlEvents:UIControlEventTouchUpInside]; + + [wrapContent addSubview:titleLabel]; + [wrapContent addSubview:datePicker]; + [wrapContent addSubview:selectButton]; + [wrapContent addSubview:closeButton]; +} + +- (void)buttonTouchExit:(UIButton *)button +{ + [self dismissViewControllerAnimated:YES completion:nil]; +} + +- (void)buttonTouchSelect:(UIButton *)button +{ + DLog(@"%ld", (long)selectedRow); + + NSString *setText = @""; + if(selectedRow != 0) + { + setText = calendar.allDay[selectedRow-1]; + } + + [[NSNotificationCenter defaultCenter] postNotificationName:@"setDate" object:setText]; + [self dismissViewControllerAnimated:YES completion:nil]; +} + +- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView +{ + return 1; +} + +- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component +{ + return calendar.allDay.count+1; +} + +- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component +{ + if (row == 0) + { + return @"Не выбрано"; + } + else + { + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setDateFormat:@"yyyy-MM-dd"]; + NSDate *date = [dateFormatter dateFromString:calendar.allDay[row-1]]; + + NSDateFormatter *dateFormatter2 = [[NSDateFormatter alloc] init]; + dateFormatter2.dateFormat = @"dd MMMM yyyy"; + + return [dateFormatter2 stringFromDate:date]; + } +} + +- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component +{ + selectedRow = row; +} + + +@end diff --git a/pro-service/Controller/EventListViewController/EventListViewController.h b/pro-service/Controller/EventListViewController/EventListViewController.h new file mode 100644 index 0000000..71ca4bb --- /dev/null +++ b/pro-service/Controller/EventListViewController/EventListViewController.h @@ -0,0 +1,22 @@ +// +// EventListViewController.h +// pro-service +// +// Created by Александр Мишаков on 21/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface EventListViewController : UIViewController + +@property (nonatomic, strong) NSString *navTitle; +@property (nonatomic, strong) NSArray *arrayEvent; +@property (nonatomic, strong) NSDateFormatter *dateFormat; +@property BOOL navPrefersLargeTitles; + +@end + +NS_ASSUME_NONNULL_END diff --git a/pro-service/Controller/EventListViewController/EventListViewController.m b/pro-service/Controller/EventListViewController/EventListViewController.m new file mode 100644 index 0000000..0ed5909 --- /dev/null +++ b/pro-service/Controller/EventListViewController/EventListViewController.m @@ -0,0 +1,121 @@ +// +// EventListViewController.m +// pro-service +// +// Created by Александр Мишаков on 21/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import "EventListViewController.h" +#import "MainTableViewCell.h" +#import "Calendar.h" +#import "Event.h" +#import "EventViewController.h" +#import "PlugEventTableViewCell.h" + +@interface EventListViewController () +{ + NSInteger selectRow; +} + +@property (weak, nonatomic) IBOutlet UITableView *tableView; + +@end + +@implementation EventListViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + self.title = self.navTitle; + + [self.navigationController.navigationBar setValue:@(NO) forKeyPath:@"hidesShadow"]; + self.navigationController.navigationBar.prefersLargeTitles = !self.navPrefersLargeTitles; + + if (self.dateFormat == nil) + { + DLog(@"etst"); + self.dateFormat = [[NSDateFormatter alloc] init]; + self.dateFormat.dateFormat = @"dd MMMM yyyy в HH:mm"; + } +} + +- (void)viewWillAppear:(BOOL)animated +{ + self.navigationController.navigationBar.prefersLargeTitles = !self.navPrefersLargeTitles; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return (self.arrayEvent.count == 0) ? 1 : self.arrayEvent.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (self.arrayEvent.count == 0) + { + static NSString *CellIdentifier = @"PlugEventTableViewCell"; + PlugEventTableViewCell *cell = (PlugEventTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (cell == nil) + { + NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil]; + cell = [nib objectAtIndex:0]; + } + + return cell; + } + else + { + static NSString *CellIdentifier = @"MainTableViewCell"; + MainTableViewCell *cell = (MainTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (cell == nil) + { + NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil]; + cell = [nib objectAtIndex:0]; + } + + + Event *event = self.arrayEvent[indexPath.row]; + cell.titleLabel.text = event.title; + cell.dateLabel.text = [self.dateFormat stringFromDate:event.created_date]; + cell.catagoryLabel.text = [event.category componentsJoinedByString:@", "]; + + NSString *stringUrl = [NSString stringWithFormat:@"%@%@", DOMEN, event.main_photo]; + DLog(@"%@", stringUrl); + NSURL *urlImage = [NSURL URLWithString:stringUrl]; + NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:urlImage completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { + if (data) { + UIImage *image = [UIImage imageWithData:data]; + if (image) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (cell) cell.image.image = image; + }); + } + } + }]; + [task resume]; + + return cell; + } +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (self.arrayEvent.count != 0) + { + selectRow = indexPath.row; + [self performSegueWithIdentifier:@"selectEvent" sender:nil]; + } +} + +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender +{ + if ([segue.identifier isEqualToString:@"selectEvent"]) + { + EventViewController *vc = segue.destinationViewController; + vc.event = self.arrayEvent[selectRow]; + } +} + +@end diff --git a/pro-service/Controller/EventViewController/EventViewController.h b/pro-service/Controller/EventViewController/EventViewController.h new file mode 100644 index 0000000..ad7b3e3 --- /dev/null +++ b/pro-service/Controller/EventViewController/EventViewController.h @@ -0,0 +1,20 @@ +// +// EventViewController.h +// pro-service +// +// Created by Александр Мишаков on 23/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import +#import "Event.h" + +NS_ASSUME_NONNULL_BEGIN + +@interface EventViewController : UIViewController + +@property (nonatomic, strong) Event *event; + +@end + +NS_ASSUME_NONNULL_END diff --git a/pro-service/Controller/EventViewController/EventViewController.m b/pro-service/Controller/EventViewController/EventViewController.m new file mode 100644 index 0000000..4050646 --- /dev/null +++ b/pro-service/Controller/EventViewController/EventViewController.m @@ -0,0 +1,131 @@ +// +// EventViewController.m +// pro-service +// +// Created by Александр Мишаков on 23/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import "EventViewController.h" + +#import "HeaderEventTableViewCell.h" +#import "ImagesEventTableViewCell.h" +#import "FooterEventTableViewCell.h" + +@interface EventViewController () +{ + BOOL checkMorePhotos; +} + +@end + +@implementation EventViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + checkMorePhotos = self.event.more_photos.count != 0; + + [self.navigationController.navigationBar setValue:@(NO) forKeyPath:@"hidesShadow"]; + self.navigationController.navigationBar.prefersLargeTitles = false; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + NSInteger eventCount = checkMorePhotos ? 3 : 2; + return eventCount; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (indexPath.row == 0) + { + static NSString *CellIdentifier = @"HeaderEventTableViewCell"; + HeaderEventTableViewCell *cell = (HeaderEventTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (cell == nil) + { + NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil]; + cell = [nib objectAtIndex:0]; + } + + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + dateFormatter.dateFormat = @"dd MMMM yyyy в HH:mm"; + + cell.dateLabel.text = [dateFormatter stringFromDate:self.event.created_date]; + cell.titleLabel.text = self.event.title; + cell.categoryLabel.text = [self.event.category componentsJoinedByString:@", "]; + cell.descriptionLabel.text = [NSString stringWithFormat:@"%@\n\nВозростное ограничение: %@+", self.event.description_text, self.event.age_rating]; + + NSString *stringUrl = [NSString stringWithFormat:@"%@%@", DOMEN, self.event.main_photo]; + DLog(@"%@", stringUrl); + NSURL *urlImage = [NSURL URLWithString:stringUrl]; + NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:urlImage completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { + if (data) { + UIImage *image = [UIImage imageWithData:data]; + if (image) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (cell) cell.imageImageView.image = image; + }); + } + } + }]; + [task resume]; + + + return cell; + } + + if (checkMorePhotos) + { + if (indexPath.row == 1) + { + static NSString *CellIdentifier = @"ImagesEventTableViewCell"; + ImagesEventTableViewCell *cell = (ImagesEventTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (cell == nil) + { + NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil]; + cell = [nib objectAtIndex:0]; + } + + cell.images = self.event.more_photos; + + return cell; + } + else if (indexPath.row == 2 && checkMorePhotos) + { + static NSString *CellIdentifier = @"FooterEventTableViewCell"; + FooterEventTableViewCell *cell = (FooterEventTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (cell == nil) + { + NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil]; + cell = [nib objectAtIndex:0]; + } + + cell.organaztionLabel.text = self.event.organization_title; + [cell setToMapSubTitle:@"ул. Нефтяников, 2А, Муравленко" letitude:55.781516 longitude:37.710277]; + + return cell; + } + } + else + { + static NSString *CellIdentifier = @"FooterEventTableViewCell"; + FooterEventTableViewCell *cell = (FooterEventTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (cell == nil) + { + NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil]; + cell = [nib objectAtIndex:0]; + } + + cell.organaztionLabel.text = self.event.organization_title; + [cell setToMapSubTitle:@"ул. Нефтяников, 2А, Муравленко" letitude:55.781516 longitude:37.710277]; + + return cell; + } + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@""]; + return cell; +} + +@end diff --git a/pro-service/Controller/MainViewController/MainViewController.h b/pro-service/Controller/MainViewController/MainViewController.h new file mode 100644 index 0000000..f6b1d16 --- /dev/null +++ b/pro-service/Controller/MainViewController/MainViewController.h @@ -0,0 +1,17 @@ +// +// MainViewController.h +// pro-service +// +// Created by Александр Мишаков on 14/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MainViewController : UIViewController + +@end + +NS_ASSUME_NONNULL_END diff --git a/pro-service/Controller/MainViewController/MainViewController.m b/pro-service/Controller/MainViewController/MainViewController.m new file mode 100644 index 0000000..799444a --- /dev/null +++ b/pro-service/Controller/MainViewController/MainViewController.m @@ -0,0 +1,254 @@ +// +// MainViewController.m +// pro-service +// +// Created by Александр Мишаков on 14/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import "MainViewController.h" +#import "MainTableViewCell.h" +#import "MainCollectionViewCell.h" +#import "Calendar.h" +#import "Event.h" +#import "EventViewController.h" +#import "PlugEventTableViewCell.h" + +@interface MainViewController () +{ + CGFloat tabelHeaderViewHeight; + UIView *sectionSeparator; + Calendar *calendar; + Event *selectEvent; +} + +@property (weak, nonatomic) IBOutlet UIView *viewSectionTopRadius; +@property (weak, nonatomic) IBOutlet UITableView *table; +@property (weak, nonatomic) IBOutlet UIView *statusViewBg; +@property (weak, nonatomic) IBOutlet UIView *tabelHeaderView; +@property (strong, nonatomic) UILabel *tabelHeaderLabel; +@property (weak, nonatomic) IBOutlet UIView *tabelHeaderViewContent; +@property (weak, nonatomic) IBOutlet UICollectionView *collectionNew; +@property (weak, nonatomic) IBOutlet UILabel *collectionPlugLabel; + +@end + +@implementation MainViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + UIBezierPath *maskPath = [UIBezierPath bezierPathWithRoundedRect:self.viewSectionTopRadius.bounds byRoundingCorners:(UIRectCornerTopLeft | UIRectCornerTopRight) cornerRadii:CGSizeMake(30, 30)]; + CAShapeLayer *maskLayer = [[CAShapeLayer alloc] init]; + maskLayer.frame = self.viewSectionTopRadius.bounds; + maskLayer.path = maskPath.CGPath; + self.viewSectionTopRadius.layer.mask = maskLayer; + + tabelHeaderViewHeight = self.tabelHeaderView.frame.size.height; + self.statusViewBg.backgroundColor = COLOR_MAIN; + self.tabelHeaderViewContent.backgroundColor = COLOR_MAIN; + self.tabelHeaderView.backgroundColor = COLOR_MAIN; + + self.collectionNew.pagingEnabled = NO; + self.collectionNew.showsVerticalScrollIndicator = false; + self.collectionNew.showsHorizontalScrollIndicator = false; + self.collectionNew.delaysContentTouches = false; + [self.collectionNew registerNib:[UINib nibWithNibName:@"MainCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:@"MainCollectionViewCell"]; + + calendar = [[Calendar alloc] init]; + [calendar loadToday]; + [calendar loadPoster]; + + self.collectionPlugLabel.hidden = true; + if (calendar.poster.count == 0) + { + self.collectionPlugLabel.hidden = false; + } +} + +// MARK: TableView + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView; +{ + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return (calendar.today.count == 0) ? 1 : calendar.today.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (calendar.today.count == 0) + { + static NSString *CellIdentifier = @"PlugEventTableViewCell"; + PlugEventTableViewCell *cell = (PlugEventTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (cell == nil) + { + NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil]; + cell = [nib objectAtIndex:0]; + } + + return cell; + } + else + { + static NSString *CellIdentifier = @"MainTableViewCell"; + MainTableViewCell *cell = (MainTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (cell == nil) + { + NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil]; + cell = [nib objectAtIndex:0]; + } + + NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; + [dateFormat setDateFormat:@"HH:mm"]; + + Event *event = calendar.today[indexPath.row]; + cell.titleLabel.text = event.title; + cell.dateLabel.text = [dateFormat stringFromDate:event.created_date]; + cell.catagoryLabel.text = [event.category componentsJoinedByString:@", "]; + + NSString *stringUrl = [NSString stringWithFormat:@"%@%@", DOMEN, event.main_photo]; + DLog(@"%@", stringUrl); + NSURL *urlImage = [NSURL URLWithString:stringUrl]; + NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:urlImage completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { + if (data) { + UIImage *image = [UIImage imageWithData:data]; + if (image) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (cell) cell.image.image = image; + }); + } + } + }]; + [task resume]; + + return cell; + } +} + +-(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section +{ + CGFloat width = tableView.frame.size.width; + UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0, 0, width, 50)]; + view.backgroundColor = [UIColor whiteColor]; + + self.tabelHeaderLabel = [[UILabel alloc] initWithFrame:CGRectMake(16, 0, width-32, 41)]; + [self.tabelHeaderLabel setFont:[UIFont systemFontOfSize:34 weight:UIFontWeightBold]]; + [self.tabelHeaderLabel setText:@"Сегодня"]; + + sectionSeparator = [[UIView alloc] initWithFrame:CGRectMake(0, 50, width, 0.5)]; + sectionSeparator.backgroundColor = [UIColor lightGrayColor]; + sectionSeparator.alpha = 0; + + [view addSubview:self.tabelHeaderLabel]; + [view addSubview:sectionSeparator]; + + return view; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + if (calendar.today.count != 0) + { + selectEvent = calendar.today[indexPath.row]; + [self performSegueWithIdentifier:@"mainSelectEvent" sender:nil]; + } +} + +- (void)scrollViewDidScroll:(UIScrollView *)scrollView +{ +// DLog(@"scrollView: %f", scrollView.contentOffset.y); + + CGRect newFrame = self.tabelHeaderViewContent.frame; + + CGAffineTransform totalTransform = CGAffineTransformMakeTranslation(0, 0); + if (scrollView.contentOffset.y < 0) + { + newFrame.size.height = tabelHeaderViewHeight-scrollView.contentOffset.y-self.viewSectionTopRadius.frame.size.height; + newFrame.origin.y = scrollView.contentOffset.y; + + CGFloat scale = 1-scrollView.contentOffset.y/2000; + CGFloat scale2 = 1-scrollView.contentOffset.y/11.5; + totalTransform = CGAffineTransformTranslate(totalTransform, scale2, 0); + totalTransform = CGAffineTransformScale(totalTransform, scale, scale); + } + else + { + newFrame.size.height = tabelHeaderViewHeight-self.viewSectionTopRadius.frame.size.height; + newFrame.origin.y = 0; + } + + self.tabelHeaderLabel.transform = totalTransform; + [self.tabelHeaderViewContent setFrame:newFrame]; + + UIColor *bg = COLOR_MAIN; + int sAlpha = 0; + if (scrollView.contentOffset.y > self.tabelHeaderView.frame.size.height-5) + { + bg = [UIColor whiteColor]; + sAlpha = 1; + } + + [UIView animateWithDuration:0.1 animations:^{ + self.statusViewBg.backgroundColor = bg; + self->sectionSeparator.alpha = sAlpha; + }]; +} + +// MARK: CollectionView + +- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section +{ + return calendar.poster.count; +} + +- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath +{ + MainCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"MainCollectionViewCell" forIndexPath:indexPath]; + + Event *event = calendar.poster[indexPath.row]; + cell.titleLabel.text = event.title; + + NSString *stringUrl = [NSString stringWithFormat:@"%@%@", DOMEN, event.main_photo]; + DLog(@"%@", stringUrl); + NSURL *urlImage = [NSURL URLWithString:stringUrl]; + NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:urlImage completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { + if (data) { + UIImage *image = [UIImage imageWithData:data]; + if (image) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (cell) cell.imageImageView.image = image; + }); + } + } + }]; + [task resume]; + + return cell; +} + +- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath +{ + return CGSizeMake(self.view.frame.size.width-32-50, 150); +} + +- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath +{ + selectEvent = calendar.poster[indexPath.row]; + [self performSegueWithIdentifier:@"mainSelectEvent" sender:nil]; +} + +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender +{ + if ([segue.identifier isEqualToString:@"mainSelectEvent"]) + { + EventViewController *vc = segue.destinationViewController; + vc.event = selectEvent; + } +} + +@end diff --git a/pro-service/Controller/SearchCategoryViewController/SearchCategoryViewController.h b/pro-service/Controller/SearchCategoryViewController/SearchCategoryViewController.h new file mode 100644 index 0000000..f7903f0 --- /dev/null +++ b/pro-service/Controller/SearchCategoryViewController/SearchCategoryViewController.h @@ -0,0 +1,17 @@ +// +// SearchCategoryViewController.h +// pro-service +// +// Created by Александр Мишаков on 21/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface SearchCategoryViewController : UIViewController + +@end + +NS_ASSUME_NONNULL_END diff --git a/pro-service/Controller/SearchCategoryViewController/SearchCategoryViewController.m b/pro-service/Controller/SearchCategoryViewController/SearchCategoryViewController.m new file mode 100644 index 0000000..2db7c58 --- /dev/null +++ b/pro-service/Controller/SearchCategoryViewController/SearchCategoryViewController.m @@ -0,0 +1,129 @@ +// +// SearchCategoryViewController.m +// pro-service +// +// Created by Александр Мишаков on 21/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import "SearchCategoryViewController.h" +#import "CategoryTableViewCell.h" +@import SPStorkController; +#import "Event.h" + +@interface SearchCategoryViewController () +{ + Event *event; + NSMutableDictionary *selectCatgory; + NSUserDefaults *UserDefaults; +} + +@end + +@implementation SearchCategoryViewController + +-(UIStatusBarStyle)preferredStatusBarStyle +{ + return UIStatusBarStyleLightContent; +} + + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + event = [[Event alloc] init]; + UserDefaults = [NSUserDefaults standardUserDefaults]; + NSData *data = [UserDefaults objectForKey:@"setCategorySearch"]; + selectCatgory = [[NSMutableDictionary alloc] initWithDictionary:[NSKeyedUnarchiver unarchiveObjectWithData:data]]; + + DLog(@"%@", selectCatgory); + DLog(@"%@", [UserDefaults objectForKey:@"setCategorySearch"]); + + self.view.backgroundColor = [UIColor whiteColor]; + self.modalPresentationCapturesStatusBarAppearance = true; + + UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(16, 24, self.view.frame.size.width-32, 27)]; + [titleLabel setFont:[UIFont boldSystemFontOfSize:22]]; + titleLabel.text = @"Категории"; + + UILabel *discripationLabel = [[UILabel alloc] initWithFrame:CGRectMake(16, 59, self.view.frame.size.width-32, 20)]; + discripationLabel.text = @"Выберите одну или несколько категорий"; + discripationLabel.textColor = [UIColor darkGrayColor]; + + UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 95, self.view.frame.size.width, self.view.frame.size.height-95)]; + tableView.dataSource = self; + tableView.delegate = self; + tableView.scrollEnabled = false; + tableView.separatorInset = UIEdgeInsetsMake(0, 70, 0, 0); + tableView.tableFooterView = [[UIView alloc] init]; + + + [self.view addSubview:titleLabel]; + [self.view addSubview:discripationLabel]; + [self.view addSubview:tableView]; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return event.category.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *CellIdentifier = @"CategoryTableViewCell"; + CategoryTableViewCell *cell = (CategoryTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (cell == nil) + { + NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil]; + cell = [nib objectAtIndex:0]; + } + + cell.titleLabel.text = event.category[indexPath.row][@"title"]; + cell.imageViewIcon.image = [UIImage imageNamed:event.category[indexPath.row][@"imageName"]]; + + if ([[selectCatgory allKeys] containsObject:event.category[indexPath.row][@"id"]]) + { + cell.accessoryType = UITableViewCellAccessoryCheckmark; + } + else + { + cell.accessoryType = UITableViewCellAccessoryNone; + } + + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + + CategoryTableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; + NSString *key = event.category[indexPath.row][@"id"]; + NSString *velue = event.category[indexPath.row][@"title"]; + + if (cell.accessoryType == UITableViewCellAccessoryCheckmark) + { + cell.accessoryType = UITableViewCellAccessoryNone; + [selectCatgory removeObjectForKey:key]; + } + else + { + cell.accessoryType = UITableViewCellAccessoryCheckmark; + [selectCatgory setObject:velue forKey:key]; + } + + DLog(@"%@", selectCatgory); + NSData *data = [NSKeyedArchiver archivedDataWithRootObject:selectCatgory]; + [UserDefaults setObject:data forKey:@"setCategorySearch"]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"setCategory" object:selectCatgory]; +} + +// TODO: close model view when tabel scroll +//- (void)scrollViewDidScroll:(UIScrollView *)scrollView +//{ +// //SPStorkController.scrollViewDidScroll(scrollView) //swift +// [SPStorkController scrollViewDidScroll:scrollView]; +//} + +@end diff --git a/pro-service/Controller/SearchViewController/SearchViewController.h b/pro-service/Controller/SearchViewController/SearchViewController.h new file mode 100644 index 0000000..273e4f8 --- /dev/null +++ b/pro-service/Controller/SearchViewController/SearchViewController.h @@ -0,0 +1,17 @@ +// +// SearchViewController.h +// pro-service +// +// Created by Александр Мишаков on 19/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface SearchViewController : UIViewController + +@end + +NS_ASSUME_NONNULL_END diff --git a/pro-service/Controller/SearchViewController/SearchViewController.m b/pro-service/Controller/SearchViewController/SearchViewController.m new file mode 100644 index 0000000..93c9bde --- /dev/null +++ b/pro-service/Controller/SearchViewController/SearchViewController.m @@ -0,0 +1,210 @@ +// +// SearchViewController.m +// pro-service +// +// Created by Александр Мишаков on 19/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import "SearchViewController.h" +#import "SearchTableViewCell.h" +#import "SearchCategoryViewController.h" +#import "DateViewController.h" +#import "EventListViewController.h" +#import "Calendar.h" +@import SPStorkController; + +@interface SearchViewController () +{ + NSArray *cellArray; + Calendar *calendar; + NSDate *selectDate; + NSMutableArray *selectCategory; + BOOL selectFree; +} + +@property (weak, nonatomic) IBOutlet UITableView *tableView; +@property (weak, nonatomic) IBOutlet UISearchBar *searchBar; + +@end + +@implementation SearchViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + selectFree = true; + selectCategory = [[NSMutableArray alloc] init]; + calendar = [[Calendar alloc] init]; + cellArray = @[@"Категория", @"Дата", @"Бесплатные"]; + + self.tableView.tableFooterView = [[UIView alloc] init]; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setCategory:) name:@"setCategory" object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(setDate:) name:@"setDate" object:nil]; +} + +// при выходе с контроллера очищаются все поля +- (void)viewWillDisappear:(BOOL)animated +{ + [[NSUserDefaults standardUserDefaults] removeObjectForKey:@"setCategorySearch"]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"setCategory" object:nil]; + [[NSNotificationCenter defaultCenter] postNotificationName:@"setDate" object:nil]; + + NSIndexPath *indexPath = [NSIndexPath indexPathForRow:2 inSection:0]; + SearchTableViewCell *cell = (SearchTableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath]; + cell.accessoryType = UITableViewCellAccessoryCheckmark; + selectFree = true; + + self.searchBar.text = @""; +} + +- (void)setCategory:(NSNotification *)notification +{ + NSMutableArray *categoryTitle = [[NSMutableArray alloc] init]; + NSDictionary *dict = [notification object]; + NSArray *keys = [dict allKeys]; + + for (int i = 0; i < keys.count; i++) + { + [categoryTitle addObject:dict[keys[i]]]; + [selectCategory addObject:keys[i]]; + } + + NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0]; + SearchTableViewCell *cell = (SearchTableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath]; + cell.supLabel.hidden = false; + cell.supLabel.text = [categoryTitle componentsJoinedByString:@", "]; + + DLog(@"%@", [notification object]); +} + +- (void)setDate:(NSNotification *)notification +{ + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setDateFormat:@"yyyy-MM-dd"]; + selectDate = [dateFormatter dateFromString:[notification object]]; + + NSDateFormatter *dateFormatter2 = [[NSDateFormatter alloc] init]; + dateFormatter2.dateFormat = @"dd MMMM yyyy"; + + NSIndexPath *indexPath = [NSIndexPath indexPathForRow:1 inSection:0]; + SearchTableViewCell *cell = (SearchTableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath]; + cell.supLabel.hidden = false; + cell.supLabel.text = [dateFormatter2 stringFromDate:selectDate]; +} + +- (void)viewWillAppear:(BOOL)animated +{ + [self.navigationController.navigationBar setValue:@(YES) forKeyPath:@"hidesShadow"]; + self.navigationController.navigationBar.prefersLargeTitles = true; +} + +// MARK: SearchController + +- (void)searchBarSearchButtonClicked:(UISearchBar *)theSearchBar +{ + [theSearchBar resignFirstResponder]; + [theSearchBar setShowsCancelButton:NO animated:YES]; +} + +- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar +{ + [searchBar setShowsCancelButton:YES animated:YES]; +} + +- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar +{ + [searchBar resignFirstResponder]; + [searchBar setShowsCancelButton:NO animated:YES]; +} + +// MARK: Table + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return cellArray.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *CellIdentifier = @"SearchTableViewCell"; + SearchTableViewCell *cell = (SearchTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; + if (cell == nil) + { + NSArray *nib = [[NSBundle mainBundle] loadNibNamed:CellIdentifier owner:self options:nil]; + cell = [nib objectAtIndex:0]; + } + + cell.titleLabel.text = cellArray[indexPath.row]; + + if (indexPath.row == 2) + { + cell.accessoryType = UITableViewCellAccessoryCheckmark; + } + else + { + cell.accessoryType = UITableViewCellAccessoryNone; + } + + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + [tableView deselectRowAtIndexPath:indexPath animated:YES]; + + if (indexPath.row == 0) + { + SearchCategoryViewController *modal = [[SearchCategoryViewController alloc] init]; + SPStorkTransitioningDelegate *transitionDelegate = [[SPStorkTransitioningDelegate alloc] init]; + + modal.transitioningDelegate = transitionDelegate; + modal.modalPresentationStyle = UIModalPresentationCustom; + [self presentViewController:modal animated:true completion:nil]; + } + else if (indexPath.row == 1) + { + DateViewController *modal = [[DateViewController alloc] init]; + SPStorkTransitioningDelegate *transitionDelegate = [[SPStorkTransitioningDelegate alloc] init]; + + modal.transitioningDelegate = transitionDelegate; + modal.modalPresentationStyle = UIModalPresentationCustom; + [self presentViewController:modal animated:true completion:nil]; + } + else if (indexPath.row == 2) + { + SearchTableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath]; + selectFree = !selectFree; + + if (cell.accessoryType == UITableViewCellAccessoryCheckmark) + { + cell.accessoryType = UITableViewCellAccessoryNone; + } + else + { + cell.accessoryType = UITableViewCellAccessoryCheckmark; + } + } +} + +- (IBAction)selectSearch:(id)sender +{ + [self performSegueWithIdentifier:@"eventToSearch" sender:nil]; +} + +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender +{ + if ([segue.identifier isEqualToString:@"eventToSearch"]) + { + EventListViewController *vc = segue.destinationViewController; + + [calendar searchTag:selectCategory date:selectDate free:selectFree text:self.searchBar.text]; + + vc.navPrefersLargeTitles = true; + vc.arrayEvent = calendar.today; + } +} + +@end diff --git a/pro-service/Model/Calendar/Calendar.h b/pro-service/Model/Calendar/Calendar.h new file mode 100644 index 0000000..a8d8966 --- /dev/null +++ b/pro-service/Model/Calendar/Calendar.h @@ -0,0 +1,29 @@ +// +// Calendar.h +// pro-service +// +// Created by Александр Мишаков on 21/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface Calendar : NSObject + +@property (nonatomic) NSArray *today; +@property (nonatomic) NSArray *allDay; +@property (nonatomic) NSArray *poster; + +- (void)loadToday; +- (void)loadAllDay; +- (void)loadPoster; + +- (void)loadFromDate:(NSDate *)date; +- (void)loadTag:(NSArray *)tags; +- (void)searchTag:(nullable NSArray *)tags date:(nullable NSDate *)date free:(BOOL)free text:(nullable NSString *)text; + +@end + +NS_ASSUME_NONNULL_END diff --git a/pro-service/Model/Calendar/Calendar.m b/pro-service/Model/Calendar/Calendar.m new file mode 100644 index 0000000..2919f02 --- /dev/null +++ b/pro-service/Model/Calendar/Calendar.m @@ -0,0 +1,194 @@ +// +// Calendar.m +// pro-service +// +// Created by Александр Мишаков on 21/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import "Calendar.h" +#import "Event.h" + +@implementation Calendar + +- (instancetype)init +{ + self = [super init]; + if (self) + { + self.today = [[NSArray alloc] init]; + } + return self; +} + +- (void)loadToday +{ + NSString *StrUrl = @"/api/event.get?today=true"; + StrUrl = [DOMEN stringByAppendingString: StrUrl]; + DLog(@"StrUrl: %@", StrUrl); + NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:StrUrl]]; + NSError *error = nil; + NSDictionary *dictionary = nil; + + if (data != nil) + { + dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; + } + + if ([dictionary[@"error"] intValue] == 910 && dictionary != nil) + { + DLog(@"events: %@", dictionary[@"events"]); + NSArray *arrayEventResponse = dictionary[@"events"]; + NSMutableArray *arrayEvent = [[NSMutableArray alloc] init]; + + for (int i = 0; i < arrayEventResponse.count; i++) + { + NSDictionary *row = arrayEventResponse[i]; + Event *event = [[Event alloc] init]; + event = [event dictinaryToEvent:row]; + [arrayEvent addObject:event]; + } + + self.today = [arrayEvent copy]; + DLog(@"self.today: %@", self.today); + + } + else + { + self.today = [[NSArray alloc] init]; + } +} + +- (void)loadAllDay +{ + NSString *StrUrl = @"/api/event.getAllDate"; + StrUrl = [DOMEN stringByAppendingString: StrUrl]; + DLog(@"StrUrl: %@", StrUrl); + NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:StrUrl]]; + NSError *error = nil; + NSDictionary *dictionary = nil; + + if (data != nil) + { + dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; + } + + if ([dictionary[@"error"] intValue] == 910 && dictionary != nil) + { + DLog(@"events: %@", dictionary[@"events"]); + self.allDay = dictionary[@"events"]; + + } + else + { + self.allDay = [[NSArray alloc] init]; + } +} + +- (void)loadPoster +{ + NSString *StrUrl = @"/api/event.get?poster=true"; + StrUrl = [DOMEN stringByAppendingString: StrUrl]; + DLog(@"StrUrl: %@", StrUrl); + NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:StrUrl]]; + NSError *error = nil; + NSDictionary *dictionary = nil; + + if (data != nil) + { + dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; + } + + if ([dictionary[@"error"] intValue] == 910 && dictionary != nil) + { + DLog(@"events: %@", dictionary[@"events"]); + NSArray *arrayEventResponse = dictionary[@"events"]; + NSMutableArray *arrayEvent = [[NSMutableArray alloc] init]; + + for (int i = 0; i < arrayEventResponse.count; i++) + { + NSDictionary *row = arrayEventResponse[i]; + Event *event = [[Event alloc] init]; + event = [event dictinaryToEvent:row]; + [arrayEvent addObject:event]; + } + + self.poster = [arrayEvent copy]; + DLog(@"self.today: %@", self.poster); + } + else + { + self.poster = [[NSArray alloc] init]; + } +} + +- (void)loadFromDate:(NSDate *)date +{ + [self searchTag:nil date:date free:true text:nil]; +} + +- (void)loadTag:(NSArray *)tags +{ + [self searchTag:tags date:nil free:true text:nil]; +} + +- (void)searchTag:(nullable NSArray *)tags date:(nullable NSDate *)date free:(BOOL)free text:(nullable NSString *)text +{ + NSString *StrUrl = @"/api/event.get?"; + NSString *freeString = free ? @"true" : @"false"; + StrUrl = [NSString stringWithFormat:@"%@free=%@", StrUrl, freeString]; + + if (tags.count != 0 && tags != nil) + { + StrUrl = [NSString stringWithFormat:@"%@&tag=%@", StrUrl, [tags componentsJoinedByString:@","]]; + } + + if (date != nil) + { + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + dateFormatter.dateFormat = @"yyyy-MM-dd"; + StrUrl = [NSString stringWithFormat:@"%@&date=%@", StrUrl, [dateFormatter stringFromDate:date]]; + } + + if (text != nil && ![text isEqual: @""]) + { + StrUrl = [NSString stringWithFormat:@"%@&text=%@", StrUrl, text]; + } + + StrUrl = [DOMEN stringByAppendingString: StrUrl]; + StrUrl = [StrUrl stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLFragmentAllowedCharacterSet]]; + DLog(@"StrUrl: %@", StrUrl); + + NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:StrUrl]]; + NSError *error = nil; + NSDictionary *dictionary = nil; + + if (data != nil) + { + dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; + } + + if ([dictionary[@"error"] intValue] == 910 && dictionary != nil) + { + DLog(@"events: %@", dictionary[@"events"]); + NSArray *arrayEventResponse = dictionary[@"events"]; + NSMutableArray *arrayEvent = [[NSMutableArray alloc] init]; + + for (int i = 0; i < arrayEventResponse.count; i++) + { + NSDictionary *row = arrayEventResponse[i]; + Event *event = [[Event alloc] init]; + event = [event dictinaryToEvent:row]; + [arrayEvent addObject:event]; + } + + self.today = [arrayEvent copy]; + DLog(@"self.today: %@", self.today); + } + else + { + self.today = [[NSArray alloc] init]; + } +} + +@end diff --git a/pro-service/Model/Event/Event.h b/pro-service/Model/Event/Event.h new file mode 100644 index 0000000..d9f502e --- /dev/null +++ b/pro-service/Model/Event/Event.h @@ -0,0 +1,34 @@ +// +// Event.h +// pro-service +// +// Created by Александр Мишаков on 21/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface Event : NSObject + +@property int idEvent; +@property float price; +@property float rating; +@property (nonatomic, nonnull) NSString *title; +@property (nonatomic, nonnull) NSString *description_text; +@property (nonatomic, nonnull) NSString *organization_title; +@property (nonatomic, nonnull) NSString *age_rating; +@property (nonatomic, nonnull) NSDate *created_date; +@property (nonatomic) NSDate *end_event; +@property (nonatomic, nonnull) NSString *main_photo; +@property (nonatomic, nonnull) NSString *profile_name; +@property (nonatomic, nonnull) NSString *profile_surname; +@property (nonatomic, nonnull) NSArray *category; +@property (nonatomic, nonnull) NSArray *more_photos; + +- (Event *)dictinaryToEvent:(NSDictionary *)dictinary; + +@end + +NS_ASSUME_NONNULL_END diff --git a/pro-service/Model/Event/Event.m b/pro-service/Model/Event/Event.m new file mode 100644 index 0000000..92b0631 --- /dev/null +++ b/pro-service/Model/Event/Event.m @@ -0,0 +1,70 @@ +// +// Event.m +// pro-service +// +// Created by Александр Мишаков on 21/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import "Event.h" + +@implementation Event + +- (instancetype)init +{ + self = [super init]; + if (self) + { + self.category = @[ + @{@"id": @2, @"title": @"Кино", @"imageName": @"emoji_cinema"}, + @{@"id": @3, @"title": @"Музыка", @"imageName": @"emoji_music"}, + @{@"id": @4, @"title": @"Музеи, выставки, библиотеки", @"imageName": @"emoji_museum"}, + @{@"id": @5, @"title": @"Фестивали, массовые гуляния, конкурсы", @"imageName": @"emoji_festival"}, + @{@"id": @6, @"title": @"Спорт", @"imageName": @"emoji_sport"}, + @{@"id": @7, @"title": @"Образование", @"imageName": @"emoji_education"}, + @{@"id": @8, @"title": @"Услуги", @"imageName": @"emoji_amenities"} + ]; + } + return self; +} + +- (Event *)dictinaryToEvent:(NSDictionary *)dictinary +{ + Event *event = [[Event alloc] init]; + + event.idEvent = [dictinary[@"id"] intValue]; + event.price = [dictinary[@"price"] floatValue]; + event.title = dictinary[@"title"]; + event.age_rating = dictinary[@"age_rating"]; + event.main_photo = dictinary[@"main_photo"]; + event.organization_title = dictinary[@"organization_title"]; + event.profile_name = dictinary[@"profile_name"]; + event.profile_surname = dictinary[@"profile_surname"]; + event.rating = [dictinary[@"rating"] floatValue]; + event.category = dictinary[@"tag"]; + event.more_photos = dictinary[@"image"]; + + if (dictinary[@"description"] == (NSString *)[NSNull null]) + { + event.description_text = @""; + } + else + { + event.description_text = dictinary[@"description"]; + } + + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"]; + + event.created_date = [dateFormatter dateFromString:dictinary[@"created_date"]]; + event.end_event = [[NSDate alloc] init]; + + if (dictinary[@"end_event"] != (NSString *)[NSNull null]) + { + event.end_event = [dateFormatter dateFromString:dictinary[@"end_event"]]; + } + + return event; +} + +@end diff --git a/pro-service/Supporting/Defines.h b/pro-service/Supporting/Defines.h new file mode 100644 index 0000000..e9d988f --- /dev/null +++ b/pro-service/Supporting/Defines.h @@ -0,0 +1,25 @@ +// +// Defines.h +// pro-service +// +// Created by Александр Мишаков on 16/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +// MARK: Custom log +#ifdef DEBUG + #define DLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__) +#else + #define DLog(...) +#endif + +// MARK: Urls +#if DEBUG + #define DOMEN @"http://ps.api.192.168.1.69.xip.io:8888" +#else + #define DOMEN @"" +#endif + +// MARK: Colors +#define COLOR_MAIN [UIColor colorWithRed:1.000 green:0.388 blue:0.388 alpha:1.00] +#define COLOR_LIGHT_MAIN [UIColor colorWithRed:1.000 green:0.882 blue:0.882 alpha:1.00] diff --git a/pro-service/Supporting/Info.plist b/pro-service/Supporting/Info.plist new file mode 100644 index 0000000..4956137 --- /dev/null +++ b/pro-service/Supporting/Info.plist @@ -0,0 +1,50 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + ProДосуг + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 0.0.1 + CFBundleVersion + 1 + LSRequiresIPhoneOS + + NSAppTransportSecurity + + NSAllowsArbitraryLoads + + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/pro-service/Supporting/PrefixHeader.pch b/pro-service/Supporting/PrefixHeader.pch new file mode 100644 index 0000000..7057efe --- /dev/null +++ b/pro-service/Supporting/PrefixHeader.pch @@ -0,0 +1,18 @@ +// +// PrefixHeader.pch +// pro-service +// +// Created by Александр Мишаков on 16/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#ifndef PrefixHeader_pch +#define PrefixHeader_pch + +// Include any system framework and library headers here that should be included in all compilation units. +// You will also need to set the Prefix Header build setting of one or more of your targets to reference this file. +#ifdef __OBJC__ + #import "Defines.h" +#endif + +#endif /* PrefixHeader_pch */ diff --git a/pro-service/Supporting/main.m b/pro-service/Supporting/main.m new file mode 100644 index 0000000..8441749 --- /dev/null +++ b/pro-service/Supporting/main.m @@ -0,0 +1,16 @@ +// +// main.m +// pro-service +// +// Created by Александр Мишаков on 14/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/pro-service/View/CategoryTableViewCell/CategoryTableViewCell.h b/pro-service/View/CategoryTableViewCell/CategoryTableViewCell.h new file mode 100644 index 0000000..9b8e581 --- /dev/null +++ b/pro-service/View/CategoryTableViewCell/CategoryTableViewCell.h @@ -0,0 +1,20 @@ +// +// CategoryTableViewCell.h +// pro-service +// +// Created by Александр Мишаков on 14/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface CategoryTableViewCell : UITableViewCell + +@property (weak, nonatomic) IBOutlet UIImageView *imageViewIcon; +@property (weak, nonatomic) IBOutlet UILabel *titleLabel; + +@end + +NS_ASSUME_NONNULL_END diff --git a/pro-service/View/CategoryTableViewCell/CategoryTableViewCell.m b/pro-service/View/CategoryTableViewCell/CategoryTableViewCell.m new file mode 100644 index 0000000..221cc12 --- /dev/null +++ b/pro-service/View/CategoryTableViewCell/CategoryTableViewCell.m @@ -0,0 +1,24 @@ +// +// CategoryTableViewCell.m +// pro-service +// +// Created by Александр Мишаков on 14/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import "CategoryTableViewCell.h" + +@implementation CategoryTableViewCell + +- (void)awakeFromNib { + [super awakeFromNib]; + // Initialization code +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated { + [super setSelected:selected animated:animated]; + + // Configure the view for the selected state +} + +@end diff --git a/pro-service/View/CategoryTableViewCell/CategoryTableViewCell.xib b/pro-service/View/CategoryTableViewCell/CategoryTableViewCell.xib new file mode 100644 index 0000000..e010317 --- /dev/null +++ b/pro-service/View/CategoryTableViewCell/CategoryTableViewCell.xib @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pro-service/View/FooterEventTableViewCell/FooterEventTableViewCell.h b/pro-service/View/FooterEventTableViewCell/FooterEventTableViewCell.h new file mode 100644 index 0000000..83dd7ac --- /dev/null +++ b/pro-service/View/FooterEventTableViewCell/FooterEventTableViewCell.h @@ -0,0 +1,23 @@ +// +// FooterEventTableViewCell.h +// pro-service +// +// Created by Александр Мишаков on 23/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface FooterEventTableViewCell : UITableViewCell + +@property (weak, nonatomic) IBOutlet UILabel *organaztionLabel; +@property (weak, nonatomic) IBOutlet MKMapView *mapView; + +- (void)setToMapSubTitle:(NSString *)subTitle letitude:(double)letitude longitude:(double)longitude; + +@end + +NS_ASSUME_NONNULL_END diff --git a/pro-service/View/FooterEventTableViewCell/FooterEventTableViewCell.m b/pro-service/View/FooterEventTableViewCell/FooterEventTableViewCell.m new file mode 100644 index 0000000..edd81f5 --- /dev/null +++ b/pro-service/View/FooterEventTableViewCell/FooterEventTableViewCell.m @@ -0,0 +1,48 @@ +// +// FooterEventTableViewCell.m +// pro-service +// +// Created by Александр Мишаков on 23/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import "FooterEventTableViewCell.h" + +@implementation FooterEventTableViewCell + +- (void)awakeFromNib +{ + [super awakeFromNib]; + +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated +{ + [super setSelected:selected animated:animated]; + +} + +- (void)setToMapSubTitle:(NSString *)subTitle letitude:(double)letitude longitude:(double)longitude +{ + CLLocationCoordinate2D centerCoordinate; + centerCoordinate.latitude = letitude; + centerCoordinate.longitude = longitude; + + MKPointAnnotation *annotation = [[MKPointAnnotation alloc] init]; + annotation.coordinate = centerCoordinate; +// annotation.title = title; + annotation.subtitle = subTitle; + [self.mapView addAnnotation:annotation]; + [self.mapView selectAnnotation:annotation animated:NO]; + + MKCoordinateRegion region; + MKCoordinateSpan span; + span.latitudeDelta = 0.002; + span.longitudeDelta = 0.002; + region.span = span; + centerCoordinate.latitude += 0.00025; + region.center = centerCoordinate; + [self.mapView setRegion:region animated:NO]; +} + +@end diff --git a/pro-service/View/FooterEventTableViewCell/FooterEventTableViewCell.xib b/pro-service/View/FooterEventTableViewCell/FooterEventTableViewCell.xib new file mode 100644 index 0000000..92f4829 --- /dev/null +++ b/pro-service/View/FooterEventTableViewCell/FooterEventTableViewCell.xib @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pro-service/View/HeaderEventTableViewCell/HeaderEventTableViewCell.h b/pro-service/View/HeaderEventTableViewCell/HeaderEventTableViewCell.h new file mode 100644 index 0000000..ac9ac72 --- /dev/null +++ b/pro-service/View/HeaderEventTableViewCell/HeaderEventTableViewCell.h @@ -0,0 +1,23 @@ +// +// HeaderEventTableViewCell.h +// pro-service +// +// Created by Александр Мишаков on 23/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface HeaderEventTableViewCell : UITableViewCell + +@property (weak, nonatomic) IBOutlet UILabel *dateLabel; +@property (weak, nonatomic) IBOutlet UILabel *titleLabel; +@property (weak, nonatomic) IBOutlet UILabel *categoryLabel; +@property (weak, nonatomic) IBOutlet UILabel *descriptionLabel; +@property (weak, nonatomic) IBOutlet UIImageView *imageImageView; + +@end + +NS_ASSUME_NONNULL_END diff --git a/pro-service/View/HeaderEventTableViewCell/HeaderEventTableViewCell.m b/pro-service/View/HeaderEventTableViewCell/HeaderEventTableViewCell.m new file mode 100644 index 0000000..3c346e8 --- /dev/null +++ b/pro-service/View/HeaderEventTableViewCell/HeaderEventTableViewCell.m @@ -0,0 +1,24 @@ +// +// HeaderEventTableViewCell.m +// pro-service +// +// Created by Александр Мишаков on 23/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import "HeaderEventTableViewCell.h" + +@implementation HeaderEventTableViewCell + +- (void)awakeFromNib { + [super awakeFromNib]; + // Initialization code +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated { + [super setSelected:selected animated:animated]; + + // Configure the view for the selected state +} + +@end diff --git a/pro-service/View/HeaderEventTableViewCell/HeaderEventTableViewCell.xib b/pro-service/View/HeaderEventTableViewCell/HeaderEventTableViewCell.xib new file mode 100644 index 0000000..417f2eb --- /dev/null +++ b/pro-service/View/HeaderEventTableViewCell/HeaderEventTableViewCell.xib @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pro-service/View/ImageEventCollectionViewCell/ImageEventCollectionViewCell.h b/pro-service/View/ImageEventCollectionViewCell/ImageEventCollectionViewCell.h new file mode 100644 index 0000000..37d81fb --- /dev/null +++ b/pro-service/View/ImageEventCollectionViewCell/ImageEventCollectionViewCell.h @@ -0,0 +1,19 @@ +// +// ImageEventCollectionViewCell.h +// pro-service +// +// Created by Александр Мишаков on 23/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface ImageEventCollectionViewCell : UICollectionViewCell + +@property (weak, nonatomic) IBOutlet UIImageView *imageImageView; + +@end + +NS_ASSUME_NONNULL_END diff --git a/pro-service/View/ImageEventCollectionViewCell/ImageEventCollectionViewCell.m b/pro-service/View/ImageEventCollectionViewCell/ImageEventCollectionViewCell.m new file mode 100644 index 0000000..1560769 --- /dev/null +++ b/pro-service/View/ImageEventCollectionViewCell/ImageEventCollectionViewCell.m @@ -0,0 +1,18 @@ +// +// ImageEventCollectionViewCell.m +// pro-service +// +// Created by Александр Мишаков on 23/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import "ImageEventCollectionViewCell.h" + +@implementation ImageEventCollectionViewCell + +- (void)awakeFromNib { + [super awakeFromNib]; + // Initialization code +} + +@end diff --git a/pro-service/View/ImageEventCollectionViewCell/ImageEventCollectionViewCell.xib b/pro-service/View/ImageEventCollectionViewCell/ImageEventCollectionViewCell.xib new file mode 100644 index 0000000..dd812f3 --- /dev/null +++ b/pro-service/View/ImageEventCollectionViewCell/ImageEventCollectionViewCell.xib @@ -0,0 +1,48 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pro-service/View/ImagesEventTableViewCell/ImagesEventTableViewCell.h b/pro-service/View/ImagesEventTableViewCell/ImagesEventTableViewCell.h new file mode 100644 index 0000000..12b07c9 --- /dev/null +++ b/pro-service/View/ImagesEventTableViewCell/ImagesEventTableViewCell.h @@ -0,0 +1,20 @@ +// +// ImagesEventTableViewCell.h +// pro-service +// +// Created by Александр Мишаков on 23/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface ImagesEventTableViewCell : UITableViewCell + +@property (weak, nonatomic) IBOutlet UICollectionView *collectionImage; +@property (strong) NSArray *images; + +@end + +NS_ASSUME_NONNULL_END diff --git a/pro-service/View/ImagesEventTableViewCell/ImagesEventTableViewCell.m b/pro-service/View/ImagesEventTableViewCell/ImagesEventTableViewCell.m new file mode 100644 index 0000000..2aa5a4d --- /dev/null +++ b/pro-service/View/ImagesEventTableViewCell/ImagesEventTableViewCell.m @@ -0,0 +1,63 @@ +// +// ImagesEventTableViewCell.m +// pro-service +// +// Created by Александр Мишаков on 23/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import "ImagesEventTableViewCell.h" +#import "ImageEventCollectionViewCell.h" + +@implementation ImagesEventTableViewCell + +- (void)awakeFromNib +{ + [super awakeFromNib]; + + self.collectionImage.pagingEnabled = NO; + self.collectionImage.showsVerticalScrollIndicator = false; + self.collectionImage.showsHorizontalScrollIndicator = false; + self.collectionImage.delaysContentTouches = false; + [self.collectionImage registerNib:[UINib nibWithNibName:@"ImageEventCollectionViewCell" bundle:nil] forCellWithReuseIdentifier:@"ImageEventCollectionViewCell"]; +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated { + [super setSelected:selected animated:animated]; + + // Configure the view for the selected state +} + +- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section +{ + return self.images.count; +} + +- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath +{ + ImageEventCollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"ImageEventCollectionViewCell" forIndexPath:indexPath]; + + NSString *stringUrl = [NSString stringWithFormat:@"%@%@", DOMEN, self.images[indexPath.row]]; + DLog(@"%@", stringUrl); + NSURL *urlImage = [NSURL URLWithString:stringUrl]; + NSURLSessionTask *task = [[NSURLSession sharedSession] dataTaskWithURL:urlImage completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { + if (data) { + UIImage *image = [UIImage imageWithData:data]; + if (image) { + dispatch_async(dispatch_get_main_queue(), ^{ + if (cell) cell.imageImageView.image = image; + }); + } + } + }]; + [task resume]; + + return cell; +} + +- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath +{ + return CGSizeMake(120, 120); +} + +@end diff --git a/pro-service/View/ImagesEventTableViewCell/ImagesEventTableViewCell.xib b/pro-service/View/ImagesEventTableViewCell/ImagesEventTableViewCell.xib new file mode 100644 index 0000000..6b13b10 --- /dev/null +++ b/pro-service/View/ImagesEventTableViewCell/ImagesEventTableViewCell.xib @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pro-service/View/MainCollectionViewCell/MainCollectionViewCell.h b/pro-service/View/MainCollectionViewCell/MainCollectionViewCell.h new file mode 100644 index 0000000..13eb0bf --- /dev/null +++ b/pro-service/View/MainCollectionViewCell/MainCollectionViewCell.h @@ -0,0 +1,21 @@ +// +// MainCollectionViewCell.h +// pro-service +// +// Created by Александр Мишаков on 14/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MainCollectionViewCell : UICollectionViewCell + +@property (weak, nonatomic) IBOutlet UIView *wrapImage; +@property (weak, nonatomic) IBOutlet UILabel *titleLabel; +@property (weak, nonatomic) IBOutlet UIImageView *imageImageView; + +@end + +NS_ASSUME_NONNULL_END diff --git a/pro-service/View/MainCollectionViewCell/MainCollectionViewCell.m b/pro-service/View/MainCollectionViewCell/MainCollectionViewCell.m new file mode 100644 index 0000000..79138b3 --- /dev/null +++ b/pro-service/View/MainCollectionViewCell/MainCollectionViewCell.m @@ -0,0 +1,21 @@ +// +// MainCollectionViewCell.m +// pro-service +// +// Created by Александр Мишаков on 14/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import "MainCollectionViewCell.h" + +@implementation MainCollectionViewCell + +- (void)awakeFromNib +{ + [super awakeFromNib]; + + self.wrapImage.layer.masksToBounds = YES; + self.wrapImage.layer.cornerRadius = 10; +} + +@end diff --git a/pro-service/View/MainCollectionViewCell/MainCollectionViewCell.xib b/pro-service/View/MainCollectionViewCell/MainCollectionViewCell.xib new file mode 100644 index 0000000..4d025db --- /dev/null +++ b/pro-service/View/MainCollectionViewCell/MainCollectionViewCell.xib @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pro-service/View/MainTableViewCell/MainTableViewCell.h b/pro-service/View/MainTableViewCell/MainTableViewCell.h new file mode 100644 index 0000000..66e51a9 --- /dev/null +++ b/pro-service/View/MainTableViewCell/MainTableViewCell.h @@ -0,0 +1,24 @@ +// +// MainTableViewCell.h +// pro-service +// +// Created by Александр Мишаков on 14/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface MainTableViewCell : UITableViewCell + +@property (weak, nonatomic) IBOutlet UIView *contentShadow; +@property (weak, nonatomic) IBOutlet UIView *content; +@property (weak, nonatomic) IBOutlet UIImageView *image; +@property (weak, nonatomic) IBOutlet UILabel *titleLabel; +@property (weak, nonatomic) IBOutlet UILabel *catagoryLabel; +@property (weak, nonatomic) IBOutlet UILabel *dateLabel; + +@end + +NS_ASSUME_NONNULL_END diff --git a/pro-service/View/MainTableViewCell/MainTableViewCell.m b/pro-service/View/MainTableViewCell/MainTableViewCell.m new file mode 100644 index 0000000..8382ace --- /dev/null +++ b/pro-service/View/MainTableViewCell/MainTableViewCell.m @@ -0,0 +1,33 @@ +// +// MainTableViewCell.m +// pro-service +// +// Created by Александр Мишаков on 14/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import "MainTableViewCell.h" + +@implementation MainTableViewCell + +- (void)awakeFromNib +{ + [super awakeFromNib]; + + self.contentShadow.layer.masksToBounds = NO; + self.contentShadow.layer.cornerRadius = 10; + self.contentShadow.layer.shadowOffset = CGSizeMake(0, 5); + self.contentShadow.layer.shadowRadius = 9; + self.contentShadow.layer.shadowOpacity = 0.12; + + self.content.layer.masksToBounds = YES; + self.content.layer.cornerRadius = 10; +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated { + [super setSelected:selected animated:animated]; + + // Configure the view for the selected state +} + +@end diff --git a/pro-service/View/MainTableViewCell/MainTableViewCell.xib b/pro-service/View/MainTableViewCell/MainTableViewCell.xib new file mode 100644 index 0000000..1a78be8 --- /dev/null +++ b/pro-service/View/MainTableViewCell/MainTableViewCell.xib @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pro-service/View/PlugEventTableViewCell/PlugEventTableViewCell.h b/pro-service/View/PlugEventTableViewCell/PlugEventTableViewCell.h new file mode 100644 index 0000000..31eb2fc --- /dev/null +++ b/pro-service/View/PlugEventTableViewCell/PlugEventTableViewCell.h @@ -0,0 +1,17 @@ +// +// PlugEventTableViewCell.h +// pro-service +// +// Created by Александр Мишаков on 23/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface PlugEventTableViewCell : UITableViewCell + +@end + +NS_ASSUME_NONNULL_END diff --git a/pro-service/View/PlugEventTableViewCell/PlugEventTableViewCell.m b/pro-service/View/PlugEventTableViewCell/PlugEventTableViewCell.m new file mode 100644 index 0000000..e3a9c69 --- /dev/null +++ b/pro-service/View/PlugEventTableViewCell/PlugEventTableViewCell.m @@ -0,0 +1,24 @@ +// +// PlugEventTableViewCell.m +// pro-service +// +// Created by Александр Мишаков on 23/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import "PlugEventTableViewCell.h" + +@implementation PlugEventTableViewCell + +- (void)awakeFromNib { + [super awakeFromNib]; + // Initialization code +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated { + [super setSelected:selected animated:animated]; + + // Configure the view for the selected state +} + +@end diff --git a/pro-service/View/PlugEventTableViewCell/PlugEventTableViewCell.xib b/pro-service/View/PlugEventTableViewCell/PlugEventTableViewCell.xib new file mode 100644 index 0000000..251d880 --- /dev/null +++ b/pro-service/View/PlugEventTableViewCell/PlugEventTableViewCell.xib @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pro-service/View/SearchTableViewCell/SearchTableViewCell.h b/pro-service/View/SearchTableViewCell/SearchTableViewCell.h new file mode 100644 index 0000000..44194c1 --- /dev/null +++ b/pro-service/View/SearchTableViewCell/SearchTableViewCell.h @@ -0,0 +1,20 @@ +// +// SearchTableViewCell.h +// pro-service +// +// Created by Александр Мишаков on 19/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface SearchTableViewCell : UITableViewCell + +@property (weak, nonatomic) IBOutlet UILabel *titleLabel; +@property (weak, nonatomic) IBOutlet UILabel *supLabel; + +@end + +NS_ASSUME_NONNULL_END diff --git a/pro-service/View/SearchTableViewCell/SearchTableViewCell.m b/pro-service/View/SearchTableViewCell/SearchTableViewCell.m new file mode 100644 index 0000000..964a61f --- /dev/null +++ b/pro-service/View/SearchTableViewCell/SearchTableViewCell.m @@ -0,0 +1,27 @@ +// +// SearchTableViewCell.m +// pro-service +// +// Created by Александр Мишаков on 19/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import "SearchTableViewCell.h" + +@implementation SearchTableViewCell + +- (void)awakeFromNib +{ + [super awakeFromNib]; + + self.titleLabel.textColor = COLOR_MAIN; + self.supLabel.hidden = true; +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated { + [super setSelected:selected animated:animated]; + + // Configure the view for the selected state +} + +@end diff --git a/pro-service/View/SearchTableViewCell/SearchTableViewCell.xib b/pro-service/View/SearchTableViewCell/SearchTableViewCell.xib new file mode 100644 index 0000000..7a80711 --- /dev/null +++ b/pro-service/View/SearchTableViewCell/SearchTableViewCell.xib @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/pro-service/ru.lproj/LaunchScreen.strings b/pro-service/ru.lproj/LaunchScreen.strings new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/pro-service/ru.lproj/LaunchScreen.strings @@ -0,0 +1 @@ + diff --git a/pro-service/ru.lproj/Main.strings b/pro-service/ru.lproj/Main.strings new file mode 100644 index 0000000..a3fe117 --- /dev/null +++ b/pro-service/ru.lproj/Main.strings @@ -0,0 +1,48 @@ + +/* Class = "UILabel"; text = "ВС"; ObjectID = "0l9-H6-aBf"; */ +"0l9-H6-aBf.text" = "ВС"; + +/* Class = "UINavigationItem"; title = "Календарь"; ObjectID = "3PM-ra-mag"; */ +"3PM-ra-mag.title" = "Календарь"; + +/* Class = "UILabel"; text = "Афиша"; ObjectID = "4hQ-vV-0QM"; */ +"4hQ-vV-0QM.text" = "Афиша"; + +/* Class = "UITabBarItem"; title = "Профиль"; ObjectID = "5X5-ee-fdS"; */ +"5X5-ee-fdS.title" = "Профиль"; + +/* Class = "UITabBarItem"; title = "Поиск"; ObjectID = "7Dy-61-aOT"; */ +"7Dy-61-aOT.title" = "Поиск"; + +/* Class = "UINavigationItem"; title = "Категории"; ObjectID = "9Zz-Vr-w9S"; */ +"9Zz-Vr-w9S.title" = "Категории"; + +/* Class = "UILabel"; text = "ПТ"; ObjectID = "Bxg-ux-5LX"; */ +"Bxg-ux-5LX.text" = "ПТ"; + +/* Class = "UITabBarItem"; title = "Категории"; ObjectID = "DVd-v9-qzU"; */ +"DVd-v9-qzU.title" = "Категории"; + +/* Class = "UILabel"; text = "ПН"; ObjectID = "EPX-g6-WEC"; */ +"EPX-g6-WEC.text" = "ПН"; + +/* Class = "UILabel"; text = "ВТ"; ObjectID = "NLc-IV-gHl"; */ +"NLc-IV-gHl.text" = "ВТ"; + +/* Class = "UINavigationItem"; title = "Поиск"; ObjectID = "NoB-Sv-YTy"; */ +"NoB-Sv-YTy.title" = "Поиск"; + +/* Class = "UITabBarItem"; title = "Лента"; ObjectID = "YaH-v5-Crn"; */ +"YaH-v5-Crn.title" = "Лента"; + +/* Class = "UILabel"; text = "ЧТ"; ObjectID = "b2Q-Wg-II1"; */ +"b2Q-Wg-II1.text" = "ЧТ"; + +/* Class = "UITabBarItem"; title = "Календарь"; ObjectID = "eRf-Rt-y01"; */ +"eRf-Rt-y01.title" = "Календарь"; + +/* Class = "UILabel"; text = "СБ"; ObjectID = "w9v-6b-qJN"; */ +"w9v-6b-qJN.text" = "СБ"; + +/* Class = "UILabel"; text = "СР"; ObjectID = "xzR-EG-WLh"; */ +"xzR-EG-WLh.text" = "СР"; diff --git a/pro-serviceTests/Info.plist b/pro-serviceTests/Info.plist new file mode 100644 index 0000000..6c40a6c --- /dev/null +++ b/pro-serviceTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/pro-serviceTests/pro_serviceTests.m b/pro-serviceTests/pro_serviceTests.m new file mode 100644 index 0000000..7b10725 --- /dev/null +++ b/pro-serviceTests/pro_serviceTests.m @@ -0,0 +1,37 @@ +// +// pro_serviceTests.m +// pro-serviceTests +// +// Created by Александр Мишаков on 14/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import + +@interface pro_serviceTests : XCTestCase + +@end + +@implementation pro_serviceTests + +- (void)setUp { + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. +} + +- (void)testExample { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. +} + +- (void)testPerformanceExample { + // This is an example of a performance test case. + [self measureBlock:^{ + // Put the code you want to measure the time of here. + }]; +} + +@end diff --git a/pro-serviceUITests/Info.plist b/pro-serviceUITests/Info.plist new file mode 100644 index 0000000..6c40a6c --- /dev/null +++ b/pro-serviceUITests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/pro-serviceUITests/pro_serviceUITests.m b/pro-serviceUITests/pro_serviceUITests.m new file mode 100644 index 0000000..11565e6 --- /dev/null +++ b/pro-serviceUITests/pro_serviceUITests.m @@ -0,0 +1,38 @@ +// +// pro_serviceUITests.m +// pro-serviceUITests +// +// Created by Александр Мишаков on 14/05/2019. +// Copyright © 2019 Александр Мишаков. All rights reserved. +// + +#import + +@interface pro_serviceUITests : XCTestCase + +@end + +@implementation pro_serviceUITests + +- (void)setUp { + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + self.continueAfterFailure = NO; + + // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method. + [[[XCUIApplication alloc] init] launch]; + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. +} + +- (void)testExample { + // Use recording to get started writing UI tests. + // Use XCTAssert and related functions to verify your tests produce the correct results. +} + +@end