CourseViewController.m 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. //
  2. // CourseViewController.m
  3. // KulexiuForTeacher
  4. //
  5. // Created by Kyle on 2022/3/17.
  6. //
  7. #import "CourseViewController.h"
  8. #import "FSCalendar.h"
  9. #import "CourseNavView.h"
  10. #import "LTSCalendarBottomView.h"
  11. #import "KSFullDatePicker.h"
  12. #import "AccompanyCourseCell.h"
  13. #import "LiveCourseCell.h"
  14. @interface CourseViewController ()<UITableViewDataSource,UITableViewDelegate,FSCalendarDataSource,FSCalendarDelegate,UIGestureRecognizerDelegate>
  15. {
  16. void * _KVOContext;
  17. }
  18. @property (nonatomic, strong) CourseNavView *navHeadView;
  19. @property (nonatomic, strong) NSString *chooseMonth;
  20. @property (nonatomic, strong) NSString *chooseDay;
  21. @property (nonatomic,strong) FSCalendar *calendar;
  22. @property (strong, nonatomic) NSCalendar *gregorian;
  23. @property (nonatomic, strong) UITableView *tableView;
  24. @property (strong, nonatomic) UIPanGestureRecognizer *scopeGesture;
  25. @property (strong, nonatomic) NSDateFormatter *dateFormatter;
  26. @property (nonatomic, strong) LTSCalendarBottomView *calendarBottom;
  27. @property (nonatomic, assign) BOOL cancleRequest;
  28. @end
  29. @implementation CourseViewController
  30. - (void)viewDidLoad {
  31. [super viewDidLoad];
  32. // Do any additional setup after loading the view.
  33. self.ks_prefersNavigationBarHidden = YES;
  34. [self configUI];
  35. [self loadCalendarInfo];
  36. }
  37. - (void)loadCalendarInfo {
  38. NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
  39. formatter.timeZone = [NSTimeZone systemTimeZone];
  40. [formatter setDateFormat:@"yyyy-MM"];
  41. NSDate *date = [NSDate date];
  42. self.chooseMonth = [formatter stringFromDate:date];
  43. self.chooseDay = [NSString stringWithFormat:@"%@ 00:00:00", [formatter stringFromDate:date]];
  44. [self.calendar selectDate:date];
  45. [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
  46. [self loadMonthCourse:self.chooseMonth];
  47. if (![NSString isEmptyString:self.chooseDay]) {
  48. [self getCourseByDate:self.chooseDay];
  49. }
  50. }
  51. - (void)configUI {
  52. [self.view addSubview:self.navHeadView];
  53. [self.navHeadView mas_makeConstraints:^(MASConstraintMaker *make) {
  54. make.left.right.top.mas_equalTo(self.view);
  55. make.height.mas_equalTo(kNaviBarHeight);
  56. }];
  57. [self.scrollView mas_remakeConstraints:^(MASConstraintMaker *make) {
  58. make.left.right.mas_equalTo(self.view);
  59. make.top.mas_equalTo(self.navHeadView.mas_bottom);
  60. make.bottom.mas_equalTo(self.view.mas_bottom);
  61. }];
  62. UIView *containerView = [[UIView alloc] initWithFrame:CGRectZero];
  63. containerView.backgroundColor = [UIColor clearColor];
  64. [self.scrollView addSubview:containerView];
  65. [containerView mas_makeConstraints:^(MASConstraintMaker *make) {
  66. make.edges.mas_equalTo(self.scrollView);
  67. make.width.mas_equalTo(self.scrollView);
  68. }];
  69. self.calendar = [[FSCalendar alloc] init];
  70. [self configCalendar];
  71. [containerView addSubview:self.calendar];
  72. [self.calendar mas_makeConstraints:^(MASConstraintMaker *make) {
  73. make.left.right.mas_equalTo(containerView);
  74. make.top.mas_equalTo(containerView.mas_top);
  75. make.height.mas_equalTo(300);
  76. }];
  77. self.calendarBottom = [LTSCalendarBottomView shareInstance];
  78. MJWeakSelf;
  79. [self.calendarBottom changeDisplay:^{
  80. [weakSelf changeDisplay];
  81. }];
  82. [containerView addSubview:self.calendarBottom];
  83. [self.calendarBottom mas_makeConstraints:^(MASConstraintMaker *make) {
  84. make.left.right.mas_equalTo(containerView);
  85. make.top.mas_equalTo(self.calendar.mas_bottom);
  86. make.height.mas_equalTo(40);
  87. }];
  88. [containerView addSubview:self.tableView];
  89. CGFloat tableHeight = kScreenHeight - kNaviBarHeight - kTabBarHeight - 300 - 40;
  90. [self.tableView mas_makeConstraints:^(MASConstraintMaker *make) {
  91. make.left.right.mas_equalTo(self.view);
  92. make.top.mas_equalTo(self.calendarBottom.mas_bottom);
  93. make.height.mas_equalTo(tableHeight);
  94. }];
  95. [containerView mas_makeConstraints:^(MASConstraintMaker *make) {
  96. make.bottom.mas_equalTo(self.tableView.mas_bottom);
  97. }];
  98. UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self.calendar action:@selector(handleScopeGesture:)];
  99. panGesture.delegate = self;
  100. panGesture.minimumNumberOfTouches = 1;
  101. panGesture.maximumNumberOfTouches = 2;
  102. [self.scrollView addGestureRecognizer:panGesture];
  103. self.scopeGesture = panGesture;
  104. [self.tableView.panGestureRecognizer requireGestureRecognizerToFail:panGesture];
  105. self.scrollView.mj_header = [KSGifRefreshHeader headerWithRefreshingBlock:^{
  106. [weakSelf.calendar setToday:[NSDate date]];
  107. [weakSelf loadMonthCourse:weakSelf.chooseMonth];
  108. if (![NSString isEmptyString:weakSelf.chooseDay]) {
  109. [weakSelf getCourseByDate:weakSelf.chooseDay];
  110. }
  111. }];
  112. if (@available(iOS 11.0, *)) {
  113. self.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
  114. } else {
  115. // Fallback on earlier versions
  116. self.automaticallyAdjustsScrollViewInsets = NO;
  117. }
  118. }
  119. - (void)endRefresh {
  120. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
  121. [self.scrollView.mj_header endRefreshing];
  122. });
  123. }
  124. #pragma mark ---- calender action
  125. // 收起或展开日历
  126. - (void)changeDisplay {
  127. FSCalendarScope selectedScope = self.calendar.scope == FSCalendarScopeMonth ? FSCalendarScopeWeek : FSCalendarScopeMonth;
  128. [self.calendar setScope:selectedScope animated:YES];
  129. NSString *imgName = selectedScope == FSCalendarScopeWeek ? @"arrow_down" : @"arrow_up";
  130. [self.calendarBottom.arrowImage setImage:[UIImage imageNamed:imgName]];
  131. #warning ---- 测试有课日期
  132. self.calendar.highlightDates = [NSMutableArray arrayWithArray:@[@"2022-04-12 00:00:00",@"2022-04-15 00:00:00"]];
  133. [self.calendar reloadData];
  134. }
  135. - (void)configCalendar {
  136. self.calendar.backgroundColor = [UIColor whiteColor];
  137. self.calendar.appearance.titleFont = [UIFont systemFontOfSize:14.0f weight:UIFontWeightMedium];
  138. self.calendar.appearance.titleDefaultColor = HexRGB(0x444444);
  139. self.calendar.appearance.titleTodayColor = HexRGB(0x444444);
  140. self.calendar.appearance.titleSelectionColor = [UIColor whiteColor];
  141. self.calendar.appearance.selectionColor = THEMECOLOR;
  142. self.calendar.appearance.weekdayFont = [UIFont systemFontOfSize:14.0f];
  143. self.calendar.appearance.weekdayTextColor = HexRGB(0x777777);
  144. self.calendar.appearance.titleWeekendColor = THEMECOLOR;
  145. self.calendar.appearance.todaySelectionColor = THEMECOLOR;
  146. self.calendar.appearance.todayColor = [UIColor whiteColor];
  147. self.calendar.appearance.todayBorderColor = [UIColor whiteColor];
  148. self.calendar.appearance.borderRadius = 0.2f;
  149. self.calendar.appearance.borderDefaultColor = [UIColor whiteColor];
  150. self.calendar.appearance.titleHightlightColor = HexRGB(0x444444);
  151. self.calendar.appearance.backgoundHightlightColor = HexRGBAlpha(0xffd7a6, 0.21);
  152. self.calendar.appearance.subtitleFont = [UIFont systemFontOfSize:10.0f];
  153. self.calendar.appearance.subtitleOffset = CGPointMake(0, 3);
  154. self.calendar.appearance.subtitleTodayColor = HexRGB(0xff6363);
  155. self.calendar.appearance.subtitleDefaultColor = HexRGB(0xff6363);
  156. self.calendar.appearance.subtitleSelectionColor = [UIColor whiteColor];
  157. self.calendar.dataSource = self;
  158. self.calendar.delegate = self;
  159. // self.calendar.firstWeekday = 2;
  160. self.calendar.appearance.caseOptions = FSCalendarCaseOptionsWeekdayUsesSingleUpperCase|FSCalendarCaseOptionsHeaderUsesUpperCase;
  161. self.calendar.calendarHeaderView.hidden = YES;
  162. self.calendar.locale = [NSLocale localeWithLocaleIdentifier:@"zh_CN"];
  163. [self.calendar addObserver:self forKeyPath:@"scope" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:_KVOContext];
  164. self.calendar.placeholderType = FSCalendarPlaceholderTypeNone;
  165. self.calendar.scope = FSCalendarScopeMonth;
  166. [self.calendar selectDate:[NSDate date] scrollToDate:YES];
  167. }
  168. #pragma mark - FSCalendarDataSource
  169. - (NSString *)calendar:(FSCalendar *)calendar subtitleForDate:(NSDate *)date {
  170. // 判断有课的日期显示subtitle
  171. if ([calendar.highlightDates containsObject:date]) {
  172. return @"有课";
  173. }
  174. return nil;
  175. }
  176. #pragma mark - FSCalendarDelegate
  177. - (void)calendar:(FSCalendar *)calendar boundingRectWillChange:(CGRect)bounds animated:(BOOL)animated
  178. {
  179. [calendar mas_updateConstraints:^(MASConstraintMaker *make) {
  180. make.height.mas_equalTo(bounds.size.height);
  181. // Do other updates
  182. }];
  183. [self.tableView mas_updateConstraints:^(MASConstraintMaker *make) {
  184. make.height.mas_equalTo(kScreenHeight - kTabBarHeight - bounds.size.height - kNaviBarHeight - 40);
  185. }];
  186. [self.view layoutIfNeeded];
  187. }
  188. - (void)calendar:(FSCalendar *)calendar didSelectDate:(NSDate *)date atMonthPosition:(FSCalendarMonthPosition)monthPosition
  189. {
  190. NSLog(@"did select date %@",[self.dateFormatter stringFromDate:date]);
  191. NSMutableArray *selectedDates = [NSMutableArray arrayWithCapacity:calendar.selectedDates.count];
  192. [calendar.selectedDates enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
  193. [selectedDates addObject:[self.dateFormatter stringFromDate:obj]];
  194. }];
  195. self.navHeadView.navTitle.text = [self.dateFormatter stringFromDate:date];
  196. NSLog(@"selected dates is %@",selectedDates);
  197. if (monthPosition == FSCalendarMonthPositionNext || monthPosition == FSCalendarMonthPositionPrevious) {
  198. [calendar setCurrentPage:date animated:YES];
  199. }
  200. NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
  201. formatter.timeZone = [NSTimeZone systemTimeZone];
  202. [formatter setDateFormat:@"yyyy-MM-dd"];
  203. NSString *dateStr = [formatter stringFromDate:date];
  204. dateStr = [NSString stringWithFormat:@"%@ 00:00:00", dateStr];
  205. self.chooseDay = dateStr;
  206. [self getCourseByDate:dateStr];
  207. }
  208. - (void)calendarCurrentPageDidChange:(FSCalendar *)calendar
  209. {
  210. self.navHeadView.navTitle.text = [self.dateFormatter stringFromDate:calendar.currentPage];
  211. NSLog(@"%s %@", __FUNCTION__, [self.dateFormatter stringFromDate:calendar.currentPage]);
  212. // 获取当前月份信息
  213. NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
  214. formatter.timeZone = [NSTimeZone systemTimeZone];
  215. [formatter setDateFormat:@"yyyy-MM"];
  216. NSString *month = [formatter stringFromDate:calendar.currentPage];
  217. if (![_chooseMonth isEqualToString:month]) {
  218. _chooseMonth = month;
  219. [self loadMonthCourse:month];
  220. }
  221. [formatter setDateFormat:@"yyyy-MM-dd"];
  222. NSString *chooseDay = [formatter stringFromDate:calendar.currentPage];
  223. self.chooseDay = chooseDay;
  224. [self.calendar selectDate:calendar.currentPage];
  225. [formatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
  226. NSString *currentDate = [formatter stringFromDate:calendar.currentPage];
  227. [self getCourseByDate:currentDate];
  228. }
  229. #pragma mark --- 获取当前月份有课日期
  230. - (void)loadMonthCourse:(NSString *)month {
  231. }
  232. #pragma mark --- 获取当日课程
  233. - (void)getCourseByDate:(NSString *)date {
  234. }
  235. #pragma mark - <UIGestureRecognizerDelegate>
  236. // Whether scope gesture should begin
  237. - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
  238. {
  239. BOOL shouldBegin = self.tableView.contentOffset.y <= -self.tableView.contentInset.top;
  240. if (shouldBegin) {
  241. CGPoint velocity = [self.scopeGesture velocityInView:self.view];
  242. switch (self.calendar.scope) {
  243. case FSCalendarScopeMonth:
  244. return velocity.y < 0;
  245. case FSCalendarScopeWeek:
  246. return velocity.y > 0;
  247. }
  248. }
  249. return shouldBegin;
  250. }
  251. #pragma mark - KVO
  252. - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context
  253. {
  254. if (context == _KVOContext) {
  255. FSCalendarScope oldScope = [change[NSKeyValueChangeOldKey] unsignedIntegerValue];
  256. FSCalendarScope newScope = [change[NSKeyValueChangeNewKey] unsignedIntegerValue];
  257. NSLog(@"From %@ to %@",(oldScope==FSCalendarScopeWeek?@"week":@"month"),(newScope==FSCalendarScopeWeek?@"week":@"month"));
  258. } else {
  259. [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
  260. }
  261. }
  262. #pragma mark --- table data source
  263. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView{
  264. return 1;
  265. }
  266. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
  267. return self.dataArray.count;
  268. }
  269. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  270. AccompanyCourseCell *cell = [tableView dequeueReusableCellWithIdentifier:@"AccompanyCourseCell"];
  271. return cell;
  272. }
  273. #pragma mark --- lazying
  274. - (CourseNavView *)navHeadView {
  275. if (!_navHeadView) {
  276. _navHeadView = [CourseNavView shareInstance];
  277. MJWeakSelf;
  278. [_navHeadView chooseNavCallback:^{
  279. [weakSelf displayMounthPicker];
  280. }];
  281. }
  282. return _navHeadView;
  283. }
  284. - (void)displayMounthPicker {
  285. }
  286. - (NSDateFormatter *)dateFormatter {
  287. if (!_dateFormatter) {
  288. _dateFormatter = [[NSDateFormatter alloc] init];
  289. _dateFormatter.timeZone = [NSTimeZone systemTimeZone];
  290. _dateFormatter.dateFormat = @"yyyy年MM月";
  291. }
  292. return _dateFormatter;
  293. }
  294. - (UITableView *)tableView {
  295. if (!_tableView) {
  296. _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
  297. _tableView.delegate = self;
  298. _tableView.dataSource = self;
  299. _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
  300. _tableView.backgroundColor = [UIColor clearColor];
  301. _tableView.showsVerticalScrollIndicator = NO;
  302. _tableView.showsHorizontalScrollIndicator = NO;
  303. _tableView.rowHeight = UITableViewAutomaticDimension;
  304. _tableView.estimatedRowHeight = 130;
  305. [_tableView registerNib:[UINib nibWithNibName:@"AccompanyCourseCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"AccompanyCourseCell"];
  306. [_tableView registerNib:[UINib nibWithNibName:@"LiveCourseCell" bundle:[NSBundle mainBundle]] forCellReuseIdentifier:@"LiveCourseCell"];
  307. UIView *bottomView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, kScreenWidth, 15)];
  308. bottomView.backgroundColor = [UIColor clearColor];
  309. _tableView.tableFooterView = bottomView;
  310. }
  311. return _tableView;
  312. }
  313. /*
  314. #pragma mark - Navigation
  315. // In a storyboard-based application, you will often want to do a little preparation before navigation
  316. - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
  317. // Get the new view controller using [segue destinationViewController].
  318. // Pass the selected object to the new view controller.
  319. }
  320. */
  321. @end