// // SideSlipFilterController.m // IBOSSMAP // // Created by apple on 2017/4/1. // Copyright © 2017年 apple. All rights reserved. // #import "SideSlipFilterController.h" #import "SideSlipModel.h" #import "SideSlipBaseTableViewCell.h" #import "objc/message.h" #import "SideSlipConfig.h" #import "UIColor+hexColor.h" #import "objc/runtime.h" #define SCREEN_WIDTH [[UIScreen mainScreen] bounds].size.width #define SCREEN_HEIGHT [[UIScreen mainScreen] bounds].size.height #define SLIP_ORIGIN_FRAME CGRectMake(SCREEN_WIDTH, 0, SCREEN_WIDTH - _sideSlipLeading, SCREEN_HEIGHT) #define SLIP_DISTINATION_FRAME CGRectMake(_sideSlipLeading, rectStatusHeight, SCREEN_WIDTH - _sideSlipLeading, SCREEN_HEIGHT-rectStatusHeight-[Util obtainHomeAreaHeight]) const CGFloat ANIMATION_DURATION_DEFAULT = 0.3f; const CGFloat SIDE_SLIP_LEADING_DEFAULT = 20; id (*objc_msgSendGetCellIdentifier)(id self, SEL _cmd) = (void *)objc_msgSend; CGFloat (*objc_msgSendGetCellHeight)(id self, SEL _cmd) = (void *)objc_msgSend; id (*objc_msgSendCreateCellWithIndexPath)(id self, SEL _cmd, NSIndexPath *) = (void *)objc_msgSend; @interface SideSlipFilterController () @property (copy, nonatomic) SideSlipFilterCommitBlock commitBlock; @property (copy, nonatomic) SideSlipFilterResetBlock resetBlock; @property (weak, nonatomic) UINavigationController *filterNavigation; @property (strong, nonatomic) UITableView *mainTableView; @property (strong, nonatomic) UIView *backCover; @property (weak, nonatomic) UIViewController *sponsor; @property (strong, nonatomic) NSMutableDictionary *templateCellDict; @end @implementation SideSlipFilterController - (instancetype)initWithSponsor:(UIViewController *)sponsor resetBlock:(SideSlipFilterResetBlock)resetBlock commitBlock:(SideSlipFilterCommitBlock)commitBlock { self = [super init]; if (self) { _sponsor = sponsor; _resetBlock = resetBlock; _commitBlock = commitBlock; UINavigationController *filterNavigation = [[NSClassFromString(FILTER_NAVIGATION_CONTROLLER_CLASS) alloc] initWithRootViewController:self]; [filterNavigation setNavigationBarHidden:YES]; filterNavigation.navigationBar.translucent = NO; [filterNavigation.view setFrame:SLIP_ORIGIN_FRAME]; self.filterNavigation = filterNavigation; [self configureStatic]; [self configureUI]; } return self; } - (void)viewDidLoad { [super viewDidLoad]; [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil]; [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil]; } #pragma mark 键盘出现 -(void)keyboardWillShow:(NSNotification *)note { CGRect keyBoardRect=[note.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue]; self.mainTableView.contentInset = UIEdgeInsetsMake(0, 0, keyBoardRect.size.height, 0); } #pragma mark 键盘消失 -(void)keyboardWillHide:(NSNotification *)note { self.mainTableView.contentInset = UIEdgeInsetsZero; } - (void)configureUI { //bottomView UIView *bottomView = [self createBottomView]; [self.view addSubview:bottomView]; UIView *headView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, SCREEN_WIDTH, 40)]; headView.backgroundColor = [UIColor whiteColor]; [headView setTranslatesAutoresizingMaskIntoConstraints:NO]; UIButton *btnHead=[UIButton buttonWithType:UIButtonTypeCustom]; btnHead.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; btnHead.frame= CGRectMake(SCREEN_WIDTH - 100, 0, 80, 40); btnHead.titleLabel.font= [UIFont systemFontOfSize:14]; [btnHead setTitle:@"取消" forState:UIControlStateNormal]; [btnHead setTitleColor:[UIColor redColor] forState:UIControlStateNormal]; [btnHead addTarget:self action:@selector(clickBackCover:) forControlEvents:UIControlEventTouchUpInside]; [headView addSubview:btnHead]; [self.view addSubview:headView]; NSDictionary *views = @{@"headView":headView,@"mainTableView":self.mainTableView, @"bottomView":bottomView}; [self.view addConstraint:[NSLayoutConstraint constraintWithItem:bottomView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.f constant:BOTTOM_BUTTON_HEIGHT]]; [self.view addConstraint:[NSLayoutConstraint constraintWithItem:headView attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.f constant:40]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[headView]|" options:NSLayoutFormatAlignAllCenterX metrics:nil views:views]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[mainTableView]|" options:NSLayoutFormatAlignAllCenterX metrics:nil views:views]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[bottomView]|" options:NSLayoutFormatAlignAllCenterX metrics:nil views:views]]; [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[headView][mainTableView][bottomView]|" options:NSLayoutFormatAlignAllCenterX metrics:nil views:views]]; } - (void)configureStatic { self.animationDuration = ANIMATION_DURATION_DEFAULT; self.sideSlipLeading = SIDE_SLIP_LEADING_DEFAULT; } - (void)show { [_sponsor.navigationController.view addSubview:self.backCover]; [_sponsor.navigationController addChildViewController:self.navigationController]; [_sponsor.navigationController.view addSubview:self.navigationController.view]; _sponsor.navigationController.interactivePopGestureRecognizer.enabled = NO; [_backCover setHidden:YES]; [UIView animateWithDuration:_animationDuration animations:^{ [self.navigationController.view setFrame:SLIP_DISTINATION_FRAME]; } completion:^(BOOL finished) { [_backCover setHidden:NO]; }]; } -(void)showPagerView:(UINavigationController*)nav{ [nav.view addSubview:self.backCover]; [nav addChildViewController:self.navigationController]; [nav.view addSubview:self.navigationController.view]; nav.interactivePopGestureRecognizer.enabled = NO; [_backCover setHidden:YES]; [UIView animateWithDuration:_animationDuration animations:^{ [self.navigationController.view setFrame:SLIP_DISTINATION_FRAME]; } completion:^(BOOL finished) { [_backCover setHidden:NO]; }]; } - (void)dismiss { [UIView animateWithDuration:_animationDuration animations:^{ [self.navigationController.view setFrame:SLIP_ORIGIN_FRAME]; } completion:^(BOOL finished) { [_backCover removeFromSuperview]; [self.navigationController.view removeFromSuperview]; [self.navigationController removeFromParentViewController]; }]; } - (UIView *)createBottomView { UIView *bottomView = [[UIView alloc] init]; [bottomView setTranslatesAutoresizingMaskIntoConstraints:NO]; //resetButton UIButton *resetButton = [[UIButton alloc] init]; [resetButton setTranslatesAutoresizingMaskIntoConstraints:NO]; [resetButton addTarget:self action:@selector(clickResetButton:) forControlEvents:UIControlEventTouchUpInside]; [resetButton.titleLabel setFont:[UIFont systemFontOfSize:BOTTOM_BUTTON_FONT_SIZE]]; [resetButton setTitleColor:[UIColor hexColor:FILTER_BLACK_STRING] forState:UIControlStateNormal]; // NSString *resetString = LocalString(@"sZYFilterReset"); // if ([resetString isEqualToString:@"sZYFilterReset"]) { // resetString = @"Reset"; // } [resetButton setTitle:@"重置" forState:UIControlStateNormal]; [resetButton setBackgroundColor:[UIColor whiteColor]]; [bottomView addSubview:resetButton]; //commitButton UIButton *commitButton = [[UIButton alloc] init]; [commitButton setTranslatesAutoresizingMaskIntoConstraints:NO]; [commitButton addTarget:self action:@selector(clickCommitButton:) forControlEvents:UIControlEventTouchUpInside]; [commitButton.titleLabel setFont:[UIFont systemFontOfSize:BOTTOM_BUTTON_FONT_SIZE]]; [commitButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; // NSString *commitString = LocalString(@"sZYFilterCommit"); // if ([commitString isEqualToString:@"sZYFilterCommit"]) { // commitString = @"Commit"; // } [commitButton setTitle:@"确定" forState:UIControlStateNormal]; [commitButton setBackgroundColor:[UIColor hexColor:FILTER_RED_STRING]]; [bottomView addSubview:commitButton]; //constraints NSDictionary *views = NSDictionaryOfVariableBindings(resetButton, commitButton); [bottomView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[resetButton][commitButton]|" options:NSLayoutFormatAlignAllCenterY metrics:nil views:views]]; [bottomView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[resetButton]|" options:NSLayoutFormatAlignAllCenterY metrics:nil views:views]]; [bottomView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[commitButton]|" options:NSLayoutFormatAlignAllCenterY metrics:nil views:views]]; [bottomView addConstraint:[NSLayoutConstraint constraintWithItem:resetButton attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:commitButton attribute:NSLayoutAttributeWidth multiplier:1.f constant:0.f]]; return bottomView; } - (void)clickResetButton:(id)sender { _resetBlock(_dataList); [[NSNotificationCenter defaultCenter] postNotificationName:FILTER_NOTIFICATION_NAME_DID_RESET_DATA object:nil]; [_mainTableView reloadData]; } - (void)clickCommitButton:(id)sender { _commitBlock(_dataList); [[NSNotificationCenter defaultCenter] postNotificationName:FILTER_NOTIFICATION_NAME_DID_COMMIT_DATA object:nil]; //[self dismiss]; } - (void)clickBackCover:(id)sender { //NSLog(@"clickBackCover"); [self dismiss]; } - (void)reloadData { if (_mainTableView) { [_mainTableView reloadData]; } } #pragma mark - DataSource Delegate - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return _dataList.count; } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { SideSlipModel *model = _dataList[indexPath.row]; Class cellClazz = NSClassFromString(model.containerCellClass); if ([(id)cellClazz respondsToSelector:@selector(cellHeight)]) { CGFloat cellHeight = objc_msgSendGetCellHeight(cellClazz, NSSelectorFromString(@"cellHeight")); return cellHeight; } NSString *identifier = objc_msgSendGetCellIdentifier(cellClazz, NSSelectorFromString(@"cellReuseIdentifier")); SideSlipBaseTableViewCell *templateCell = [self.templateCellDict objectForKey:identifier]; if (!templateCell) { templateCell = objc_msgSendCreateCellWithIndexPath(cellClazz, NSSelectorFromString(@"createCellWithIndexPath:"), indexPath); templateCell.delegate = self; [self.templateCellDict setObject:templateCell forKey:identifier]; } [templateCell updateFrame:self.view.frame.size.width]; //update [templateCell updateCellWithModel:&model indexPath:indexPath]; //calculate NSLayoutConstraint *calculateCellConstraint = [NSLayoutConstraint constraintWithItem:templateCell.contentView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.f constant:self.view.bounds.size.width]; [templateCell.contentView addConstraint:calculateCellConstraint]; CGSize cellSize = [templateCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize]; [templateCell.contentView removeConstraint:calculateCellConstraint]; CGFloat height = 0.f; if (cellSize.height>0) { height = cellSize.height; }else{ height = templateCell.cellHeight; } return height; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { SideSlipModel *model = _dataList[indexPath.row]; Class cellClazz = NSClassFromString(model.containerCellClass); NSString *identifier = objc_msgSendGetCellIdentifier(cellClazz, NSSelectorFromString(@"cellReuseIdentifier")); SideSlipBaseTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier]; if (!cell) { cell = objc_msgSendCreateCellWithIndexPath(cellClazz, NSSelectorFromString(@"createCellWithIndexPath:"), indexPath); cell.delegate = self; } cell.selectionStyle=UITableViewCellSelectionStyleNone; //update [cell updateCellWithModel:&model indexPath:indexPath]; return cell; } - (void)sideSlipTableViewCellNeedsReload:(NSIndexPath *)indexPath { [_mainTableView reloadData]; } - (void)sideSlipTableViewCellNeedsPushViewController:(UIViewController *)viewController animated:(BOOL)animated { [self.navigationController pushViewController:viewController animated:animated]; } - (void)sideSlipTableViewCellNeedsDismissViewController:(UIViewController *)viewController animated:(BOOL)animated{ [self presentViewController:viewController animated:NO completion:nil]; } - (void)sideSlipTableViewCellNeedsScrollToCell:(UITableViewCell *)cell atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated { NSIndexPath *indexPath = [_mainTableView indexPathForRowAtPoint:cell.center]; [_mainTableView scrollToRowAtIndexPath:indexPath atScrollPosition:scrollPosition animated:animated]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } #pragma mark - GetSet - (UITableView *)mainTableView { if (!_mainTableView) { _mainTableView = [[UITableView alloc] init]; _mainTableView.separatorStyle = UITableViewCellSeparatorStyleNone; _mainTableView.delegate = self; _mainTableView.dataSource = self; [_mainTableView setTranslatesAutoresizingMaskIntoConstraints:NO]; [self.view addSubview:_mainTableView]; //if (self.hasHeadView) { //_mainTableView.tableHeaderView = headView; //} } return _mainTableView; } - (NSMutableDictionary *)templateCellDict { if (!_templateCellDict) { _templateCellDict = [NSMutableDictionary dictionary]; } return _templateCellDict; } - (UIView *)backCover { if (!_backCover) { _backCover = [[UIView alloc] initWithFrame:CGRectMake(0, rectStatusHeight, SCREEN_WIDTH, SCREEN_HEIGHT-rectStatusHeight)]; [_backCover setBackgroundColor:[UIColor hexColor:FILTER_BACKGROUND_COVER_COLOR]]; [_backCover setAlpha:FILTER_BACKGROUND_COVER_ALPHA]; [_backCover addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(clickBackCover:)]]; } return _backCover; } - (UINavigationController *)filterNavigation { return objc_getAssociatedObject(_sponsor, _cmd); } - (void)setFilterNavigation:(UINavigationController *)filterNavigation { //让sponsor持有filterNavigation objc_setAssociatedObject(_sponsor, @selector(filterNavigation), filterNavigation, OBJC_ASSOCIATION_RETAIN_NONATOMIC); } - (void)setDataList:(NSArray *)dataList { _dataList = [dataList copy]; if (_mainTableView) { [_mainTableView reloadData]; } } @end