YBIBSheetView.m 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. //
  2. // YBIBSheetView.m
  3. // YBImageBrowserDemo
  4. //
  5. // Created by 波儿菜 on 2019/7/6.
  6. // Copyright © 2019 杨波. All rights reserved.
  7. //
  8. #import "YBIBSheetView.h"
  9. #import "YBIBUtilities.h"
  10. #import "YBIBCopywriter.h"
  11. @implementation YBIBSheetAction
  12. + (instancetype)actionWithName:(NSString *)name action:(YBIBSheetActionBlock)action {
  13. YBIBSheetAction *sheetAction = [YBIBSheetAction new];
  14. sheetAction.name = name;
  15. sheetAction.action = action;
  16. return sheetAction;
  17. }
  18. @end
  19. @interface YBIBSheetCell : UITableViewCell
  20. @property (nonatomic, strong) UILabel *titleLabel;
  21. @property (nonatomic, strong) CALayer *line;
  22. @end
  23. @implementation YBIBSheetCell
  24. - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
  25. if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
  26. self.selectionStyle = UITableViewCellSelectionStyleNone;
  27. _titleLabel = [UILabel new];
  28. _titleLabel.textColor = UIColor.darkTextColor;
  29. _titleLabel.font = [UIFont fontWithName:@"Avenir-Medium" size:16];
  30. _titleLabel.textAlignment = NSTextAlignmentCenter;
  31. _line = [CALayer new];
  32. _line.backgroundColor = UIColor.groupTableViewBackgroundColor.CGColor;
  33. [self.contentView addSubview:_titleLabel];
  34. [self.contentView.layer addSublayer:_line];
  35. }
  36. return self;
  37. }
  38. - (void)layoutSubviews {
  39. [super layoutSubviews];
  40. CGFloat width = self.contentView.bounds.size.width, height = self.contentView.bounds.size.height;
  41. CGFloat lineHeight = 0.5;
  42. _line.frame = CGRectMake(0, height - lineHeight, width, lineHeight);
  43. CGFloat offset = 15;
  44. _titleLabel.frame = CGRectMake(offset, 0, width - offset * 2, height);
  45. }
  46. @end
  47. static CGFloat kOffsetSpace = 5;
  48. @interface YBIBSheetView () <UITableViewDelegate, UITableViewDataSource>
  49. @property (nonatomic, strong) UITableView *tableView;
  50. @end
  51. @implementation YBIBSheetView {
  52. CGRect _tableShowFrame;
  53. CGRect _tableHideFrame;
  54. }
  55. #pragma mark - life cycle
  56. - (instancetype)initWithFrame:(CGRect)frame {
  57. self = [super initWithFrame:frame];
  58. if (self) {
  59. _cancelText = [YBIBCopywriter sharedCopywriter].cancel;
  60. _maxHeightScale = 0.7;
  61. _showDuration = 0.2;
  62. _hideDuration = 0.1;
  63. _cellHeight = 50;
  64. _backAlpha = 0.3;
  65. _actions = [NSMutableArray array];
  66. [self addSubview:self.tableView];
  67. }
  68. return self;
  69. }
  70. #pragma mark - public
  71. - (void)showToView:(UIView *)view orientation:(UIDeviceOrientation)orientation {
  72. if (self.actions.count == 0) return;
  73. [view addSubview:self];
  74. self.frame = view.bounds;
  75. UIEdgeInsets padding = YBIBPaddingByBrowserOrientation(orientation);
  76. CGFloat footerHeight = padding.bottom;
  77. CGFloat tableHeight = self.cellHeight * (self.actions.count + 1) + kOffsetSpace + footerHeight;
  78. _tableShowFrame = self.frame;
  79. _tableShowFrame.size.height = MIN(self.maxHeightScale * self.bounds.size.height, tableHeight);
  80. _tableShowFrame.origin.y = self.bounds.size.height - _tableShowFrame.size.height;
  81. _tableHideFrame = _tableShowFrame;
  82. _tableHideFrame.origin.y = self.bounds.size.height;
  83. self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0];
  84. self.tableView.frame = _tableHideFrame;
  85. self.tableView.tableFooterView.bounds = CGRectMake(0, 0, self.tableView.frame.size.width, footerHeight);
  86. [UIView animateWithDuration:self.showDuration animations:^{
  87. self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:self->_backAlpha];
  88. self.tableView.frame = self->_tableShowFrame;
  89. }];
  90. }
  91. - (void)hideWithAnimation:(BOOL)animation {
  92. if (!self.superview) return;
  93. void(^animationsBlock)(void) = ^{
  94. self.tableView.frame = self->_tableHideFrame;
  95. self.backgroundColor = [[UIColor blackColor] colorWithAlphaComponent:0];
  96. };
  97. void(^completionBlock)(BOOL n) = ^(BOOL n){
  98. [self removeFromSuperview];
  99. };
  100. if (animation) {
  101. [UIView animateWithDuration:self.hideDuration animations:animationsBlock completion:completionBlock];
  102. } else {
  103. animationsBlock();
  104. completionBlock(NO);
  105. }
  106. }
  107. #pragma mark - touch
  108. - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
  109. CGPoint point = [touches.anyObject locationInView:self];
  110. if (!CGRectContainsPoint(self.tableView.frame, point)) {
  111. [self hideWithAnimation:YES];
  112. }
  113. }
  114. #pragma mark - <UITableViewDataSource>
  115. - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
  116. return 2;
  117. }
  118. - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
  119. return section == 0 ? self.actions.count : 1;
  120. }
  121. - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
  122. return self.cellHeight;
  123. }
  124. - (CGFloat)tableView:(UITableView *)tableView heightForHeaderInSection:(NSInteger)section {
  125. return section == 0 ? CGFLOAT_MIN : kOffsetSpace;
  126. }
  127. - (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
  128. return CGFLOAT_MIN;
  129. }
  130. - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
  131. YBIBSheetCell *cell = [tableView dequeueReusableCellWithIdentifier:NSStringFromClass(YBIBSheetCell.self)];
  132. if (indexPath.section == 0) {
  133. cell.line.hidden = NO;
  134. YBIBSheetAction *action = self.actions[indexPath.row];
  135. cell.titleLabel.text = action.name;
  136. } else {
  137. cell.line.hidden = YES;
  138. cell.titleLabel.text = self.cancelText;
  139. }
  140. return cell;
  141. }
  142. #pragma mark - <UITableViewDelegate>
  143. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
  144. if (indexPath.section == 0) {
  145. YBIBSheetAction *action = self.actions[indexPath.row];
  146. if (action.action) action.action(self.currentdata());
  147. } else {
  148. [self hideWithAnimation:YES];
  149. }
  150. }
  151. #pragma mark - getters
  152. - (UITableView *)tableView {
  153. if (!_tableView) {
  154. _tableView = [[UITableView alloc] initWithFrame:CGRectZero style:UITableViewStyleGrouped];
  155. _tableView.delegate = self;
  156. _tableView.dataSource = self;
  157. _tableView.estimatedRowHeight = 44;
  158. _tableView.estimatedSectionFooterHeight = 0;
  159. _tableView.estimatedSectionHeaderHeight = 0;
  160. _tableView.backgroundColor = [UIColor clearColor];
  161. _tableView.alwaysBounceVertical = NO;
  162. _tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
  163. if (@available(iOS 11.0, *)) {
  164. _tableView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
  165. }
  166. UIView *footer = [UIView new];
  167. footer.backgroundColor = UIColor.whiteColor;
  168. _tableView.tableFooterView = footer;
  169. [_tableView registerClass:YBIBSheetCell.self forCellReuseIdentifier:NSStringFromClass(YBIBSheetCell.self)];
  170. }
  171. return _tableView;
  172. }
  173. @end