BRBaseView.m 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394
  1. //
  2. // BaseView.m
  3. // BRPickerViewDemo
  4. //
  5. // Created by renbo on 2017/8/11.
  6. // Copyright © 2017 irenb. All rights reserved.
  7. //
  8. // 最新代码下载地址:https://github.com/91renb/BRPickerView
  9. #import "BRBaseView.h"
  10. @interface BRBaseView ()
  11. // 蒙层视图
  12. @property (nonatomic, strong) UIView *maskView;
  13. // 标题栏背景视图
  14. @property (nonatomic, strong) UIView *titleBarView;
  15. // 左边取消按钮
  16. @property (nonatomic, strong) UIButton *cancelBtn;
  17. // 右边确定按钮
  18. @property (nonatomic, strong) UIButton *doneBtn;
  19. // 中间标题
  20. @property (nonatomic, strong) UILabel *titleLabel;
  21. // 取消按钮离屏幕边缘的距离
  22. @property (nonatomic, assign) CGFloat cancelBtnMargin;
  23. // 确定按钮离屏幕边缘的距离
  24. @property (nonatomic, assign) CGFloat doneBtnMargin;
  25. @end
  26. @implementation BRBaseView
  27. - (void)initUI {
  28. self.frame = self.keyView.bounds;
  29. // 设置子视图的宽度随着父视图变化
  30. self.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  31. if (!self.pickerStyle.hiddenMaskView) {
  32. [self addSubview:self.maskView];
  33. }
  34. [self addSubview:self.alertView];
  35. // 是否隐藏标题栏
  36. if (!self.pickerStyle.hiddenTitleBarView) {
  37. [self.alertView addSubview:self.titleBarView];
  38. [self.alertView sendSubviewToBack:self.titleBarView];
  39. if (!self.pickerStyle.hiddenTitleLabel) {
  40. [self.titleBarView addSubview:self.titleLabel];
  41. }
  42. if (!self.pickerStyle.hiddenCancelBtn) {
  43. [self.titleBarView addSubview:self.cancelBtn];
  44. // 获取边距
  45. if (self.pickerStyle.cancelBtnFrame.origin.x < self.bounds.size.width / 2) {
  46. self.cancelBtnMargin = self.pickerStyle.cancelBtnFrame.origin.x;
  47. } else {
  48. self.cancelBtnMargin = self.bounds.size.width - self.pickerStyle.cancelBtnFrame.origin.x - self.pickerStyle.cancelBtnFrame.size.width;
  49. }
  50. }
  51. if (!self.pickerStyle.hiddenDoneBtn) {
  52. [self.titleBarView addSubview:self.doneBtn];
  53. // 获取边距
  54. if (self.pickerStyle.doneBtnFrame.origin.x < self.bounds.size.width / 2) {
  55. self.doneBtnMargin = self.pickerStyle.doneBtnFrame.origin.x;
  56. } else {
  57. self.doneBtnMargin = self.bounds.size.width - self.pickerStyle.doneBtnFrame.origin.x - self.pickerStyle.doneBtnFrame.size.width;
  58. }
  59. }
  60. }
  61. }
  62. #pragma mark - 适配横屏安全区域,更新子视图布局
  63. - (void)layoutSubviews {
  64. [super layoutSubviews];
  65. if (_cancelBtn || _doneBtn) {
  66. if (@available(iOS 11.0, *)) {
  67. UIEdgeInsets safeInsets = self.safeAreaInsets;
  68. if (_cancelBtn) {
  69. CGRect cancelBtnFrame = self.pickerStyle.cancelBtnFrame;
  70. if (cancelBtnFrame.origin.x < MIN(self.bounds.size.width / 2, self.bounds.size.height / 2)) {
  71. cancelBtnFrame.origin.x += safeInsets.left;
  72. } else {
  73. cancelBtnFrame.origin.x = self.bounds.size.width - cancelBtnFrame.size.width - safeInsets.right - self.cancelBtnMargin;
  74. }
  75. self.cancelBtn.frame = cancelBtnFrame;
  76. }
  77. if (_doneBtn) {
  78. CGRect doneBtnFrame = self.pickerStyle.doneBtnFrame;
  79. if (doneBtnFrame.origin.x < MIN(self.bounds.size.width / 2, self.bounds.size.height / 2)) {
  80. doneBtnFrame.origin.x += safeInsets.left;
  81. } else {
  82. doneBtnFrame.origin.x = self.bounds.size.width - doneBtnFrame.size.width - safeInsets.right - self.doneBtnMargin;
  83. }
  84. self.doneBtn.frame = doneBtnFrame;
  85. }
  86. }
  87. }
  88. if (_alertView && self.pickerStyle.topCornerRadius > 0) {
  89. // 设置顶部圆角
  90. [self br_setView:_alertView roundingCorners:UIRectCornerTopLeft | UIRectCornerTopRight withRadius:self.pickerStyle.topCornerRadius];
  91. }
  92. }
  93. #pragma mark - 蒙层视图
  94. - (UIView *)maskView {
  95. if (!_maskView) {
  96. _maskView = [[UIView alloc]initWithFrame:self.keyView.bounds];
  97. _maskView.backgroundColor = self.pickerStyle.maskColor;
  98. // 设置子视图的大小随着父视图变化
  99. _maskView.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  100. _maskView.userInteractionEnabled = YES;
  101. UITapGestureRecognizer *myTap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(didTapMaskView:)];
  102. [_maskView addGestureRecognizer:myTap];
  103. }
  104. return _maskView;
  105. }
  106. #pragma mark - 弹框视图
  107. - (UIView *)alertView {
  108. if (!_alertView) {
  109. CGFloat accessoryViewHeight = 0;
  110. if (self.pickerHeaderView) {
  111. accessoryViewHeight += self.pickerHeaderView.bounds.size.height;
  112. }
  113. if (self.pickerFooterView) {
  114. accessoryViewHeight += self.pickerFooterView.bounds.size.height;
  115. }
  116. CGFloat height = self.pickerStyle.titleBarHeight + self.pickerStyle.pickerHeight + self.pickerStyle.paddingBottom + accessoryViewHeight;
  117. _alertView = [[UIView alloc]initWithFrame:CGRectMake(0, self.keyView.bounds.size.height - height, self.keyView.bounds.size.width, height)];
  118. _alertView.backgroundColor = self.pickerStyle.alertViewColor ? self.pickerStyle.alertViewColor : self.pickerStyle.pickerColor;
  119. if (!self.pickerStyle.topCornerRadius && !self.pickerStyle.hiddenShadowLine) {
  120. // 设置弹框视图顶部边框线
  121. UIView *shadowLineView = [[UIView alloc]initWithFrame:CGRectMake(0, 0, _alertView.frame.size.width, self.pickerStyle.shadowLineHeight)];
  122. shadowLineView.backgroundColor = self.pickerStyle.shadowLineColor;
  123. shadowLineView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
  124. [_alertView addSubview:shadowLineView];
  125. }
  126. _alertView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth;
  127. }
  128. return _alertView;
  129. }
  130. #pragma mark - 标题栏视图
  131. - (UIView *)titleBarView {
  132. if (!_titleBarView) {
  133. _titleBarView =[[UIView alloc]initWithFrame:CGRectMake(0, 0, self.keyView.bounds.size.width, self.pickerStyle.titleBarHeight)];
  134. _titleBarView.backgroundColor = self.pickerStyle.titleBarColor;
  135. _titleBarView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
  136. if (!self.pickerStyle.hiddenTitleLine) {
  137. // 设置标题栏底部分割线
  138. UIView *titleLineView = [[UIView alloc]initWithFrame:CGRectMake(0, _titleBarView.frame.size.height - 0.5f, _titleBarView.frame.size.width, 0.5f)];
  139. titleLineView.backgroundColor = self.pickerStyle.titleLineColor;
  140. titleLineView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
  141. [_titleBarView addSubview:titleLineView];
  142. }
  143. }
  144. return _titleBarView;
  145. }
  146. #pragma mark - 取消按钮
  147. - (UIButton *)cancelBtn {
  148. if (!_cancelBtn) {
  149. _cancelBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  150. _cancelBtn.frame = self.pickerStyle.cancelBtnFrame;
  151. _cancelBtn.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin;
  152. _cancelBtn.backgroundColor = self.pickerStyle.cancelColor;;
  153. _cancelBtn.titleLabel.font = self.pickerStyle.cancelTextFont;
  154. [_cancelBtn setTitleColor:self.pickerStyle.cancelTextColor forState:UIControlStateNormal];
  155. if (self.pickerStyle.cancelBtnImage) {
  156. [_cancelBtn setImage:self.pickerStyle.cancelBtnImage forState:UIControlStateNormal];
  157. }
  158. if (self.pickerStyle.cancelBtnTitle) {
  159. [_cancelBtn setTitle:self.pickerStyle.cancelBtnTitle forState:UIControlStateNormal];
  160. }
  161. [_cancelBtn addTarget:self action:@selector(clickCancelBtn) forControlEvents:UIControlEventTouchUpInside];
  162. // 设置按钮圆角或边框
  163. if (self.pickerStyle.cancelBorderStyle == BRBorderStyleSolid) {
  164. _cancelBtn.layer.cornerRadius = self.pickerStyle.cancelCornerRadius > 0 ? self.pickerStyle.cancelCornerRadius : 6.0f;
  165. _cancelBtn.layer.borderColor = self.pickerStyle.cancelTextColor.CGColor;
  166. _cancelBtn.layer.borderWidth = self.pickerStyle.cancelBorderWidth > 0 ? self.pickerStyle.cancelBorderWidth : 1.0f;
  167. _cancelBtn.layer.masksToBounds = YES;
  168. } else if (self.pickerStyle.cancelBorderStyle == BRBorderStyleFill) {
  169. _cancelBtn.layer.cornerRadius = self.pickerStyle.cancelCornerRadius > 0 ? self.pickerStyle.cancelCornerRadius : 6.0f;
  170. _cancelBtn.layer.masksToBounds = YES;
  171. }
  172. }
  173. return _cancelBtn;
  174. }
  175. #pragma mark - 确定按钮
  176. - (UIButton *)doneBtn {
  177. if (!_doneBtn) {
  178. _doneBtn = [UIButton buttonWithType:UIButtonTypeCustom];
  179. _doneBtn.frame = self.pickerStyle.doneBtnFrame;
  180. _doneBtn.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin;
  181. _doneBtn.backgroundColor = self.pickerStyle.doneColor;
  182. if (self.pickerStyle.doneBtnImage) {
  183. [_doneBtn setImage:self.pickerStyle.doneBtnImage forState:UIControlStateNormal];
  184. }
  185. if (self.pickerStyle.doneBtnTitle) {
  186. _doneBtn.titleLabel.font = self.pickerStyle.doneTextFont;
  187. [_doneBtn setTitleColor:self.pickerStyle.doneTextColor forState:UIControlStateNormal];
  188. [_doneBtn setTitle:self.pickerStyle.doneBtnTitle forState:UIControlStateNormal];
  189. }
  190. [_doneBtn addTarget:self action:@selector(clickDoneBtn) forControlEvents:UIControlEventTouchUpInside];
  191. // 设置按钮圆角或边框
  192. if (self.pickerStyle.doneBorderStyle == BRBorderStyleSolid) {
  193. _doneBtn.layer.cornerRadius = self.pickerStyle.doneCornerRadius > 0 ? self.pickerStyle.doneCornerRadius : 6.0f;
  194. _doneBtn.layer.borderColor = self.pickerStyle.doneTextColor.CGColor;
  195. _doneBtn.layer.borderWidth = self.pickerStyle.doneBorderWidth > 0 ? self.pickerStyle.doneBorderWidth : 1.0f;
  196. _doneBtn.layer.masksToBounds = YES;
  197. } else if (self.pickerStyle.doneBorderStyle == BRBorderStyleFill) {
  198. _doneBtn.layer.cornerRadius = self.pickerStyle.doneCornerRadius > 0 ? self.pickerStyle.doneCornerRadius : 6.0f;
  199. _doneBtn.layer.masksToBounds = YES;
  200. }
  201. }
  202. return _doneBtn;
  203. }
  204. #pragma mark - 中间标题label
  205. - (UILabel *)titleLabel {
  206. if (!_titleLabel) {
  207. _titleLabel = [[UILabel alloc]initWithFrame:self.pickerStyle.titleLabelFrame];
  208. _titleLabel.backgroundColor = self.pickerStyle.titleLabelColor;
  209. _titleLabel.autoresizingMask = UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin;
  210. _titleLabel.textAlignment = NSTextAlignmentCenter;
  211. _titleLabel.font = self.pickerStyle.titleTextFont;
  212. _titleLabel.textColor = self.pickerStyle.titleTextColor;
  213. _titleLabel.text = self.title;
  214. }
  215. return _titleLabel;
  216. }
  217. #pragma mark - 点击蒙层视图事件
  218. - (void)didTapMaskView:(UITapGestureRecognizer *)sender {
  219. [self removePickerFromView:nil];
  220. if (self.cancelBlock) {
  221. self.cancelBlock();
  222. }
  223. }
  224. #pragma mark - 取消按钮的点击事件
  225. - (void)clickCancelBtn {
  226. [self removePickerFromView:nil];
  227. if (self.cancelBlock) {
  228. self.cancelBlock();
  229. }
  230. }
  231. #pragma mark - 确定按钮的点击事件
  232. - (void)clickDoneBtn {
  233. if (self.doneBlock) {
  234. self.doneBlock();
  235. }
  236. }
  237. #pragma mark - 添加视图方法
  238. - (void)addPickerToView:(UIView *)view {
  239. if (view) {
  240. self.frame = view.bounds;
  241. self.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
  242. CGFloat accessoryViewHeight = 0;
  243. if (self.pickerHeaderView) {
  244. CGRect rect = self.pickerHeaderView.frame;
  245. self.pickerHeaderView.frame = CGRectMake(0, 0, view.bounds.size.width, rect.size.height);
  246. self.pickerHeaderView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
  247. [self addSubview:self.pickerHeaderView];
  248. accessoryViewHeight += self.pickerHeaderView.bounds.size.height;
  249. }
  250. if (self.pickerFooterView) {
  251. CGRect rect = self.pickerFooterView.frame;
  252. self.pickerFooterView.frame = CGRectMake(0, view.bounds.size.height - rect.size.height, view.bounds.size.width, rect.size.height);
  253. self.pickerFooterView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
  254. [self addSubview:self.pickerFooterView];
  255. accessoryViewHeight += self.pickerFooterView.bounds.size.height;
  256. }
  257. [view addSubview:self];
  258. } else {
  259. [self initUI];
  260. if (self.pickerHeaderView) {
  261. CGRect rect = self.pickerHeaderView.frame;
  262. CGFloat titleBarHeight = self.pickerStyle.hiddenTitleBarView ? 0 : self.pickerStyle.titleBarHeight;
  263. self.pickerHeaderView.frame = CGRectMake(0, titleBarHeight, self.alertView.bounds.size.width, rect.size.height);
  264. self.pickerHeaderView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
  265. [self.alertView addSubview:self.pickerHeaderView];
  266. }
  267. if (self.pickerFooterView) {
  268. CGRect rect = self.pickerFooterView.frame;
  269. self.pickerFooterView.frame = CGRectMake(0, self.alertView.bounds.size.height - self.pickerStyle.paddingBottom - rect.size.height, self.alertView.bounds.size.width, rect.size.height);
  270. self.pickerFooterView.autoresizingMask = UIViewAutoresizingFlexibleWidth;
  271. [self.alertView addSubview:self.pickerFooterView];
  272. }
  273. [self.keyView addSubview:self];
  274. // 动画前初始位置
  275. CGRect rect = self.alertView.frame;
  276. rect.origin.y = self.bounds.size.height;
  277. self.alertView.frame = rect;
  278. // 弹出动画
  279. if (!self.pickerStyle.hiddenMaskView) {
  280. self.maskView.alpha = 0;
  281. }
  282. [UIView animateWithDuration:0.3 animations:^{
  283. if (!self.pickerStyle.hiddenMaskView) {
  284. self.maskView.alpha = 1;
  285. }
  286. CGFloat alertViewHeight = self.alertView.bounds.size.height;
  287. CGRect rect = self.alertView.frame;
  288. rect.origin.y -= alertViewHeight;
  289. self.alertView.frame = rect;
  290. }];
  291. }
  292. }
  293. #pragma mark - 移除视图方法
  294. - (void)removePickerFromView:(UIView *)view {
  295. if (view) {
  296. [self removeFromSuperview];
  297. } else {
  298. // 关闭动画
  299. [UIView animateWithDuration:0.2 animations:^{
  300. CGFloat alertViewHeight = self.alertView.bounds.size.height;
  301. CGRect rect = self.alertView.frame;
  302. rect.origin.y += alertViewHeight;
  303. self.alertView.frame = rect;
  304. if (!self.pickerStyle.hiddenMaskView) {
  305. self.maskView.alpha = 0;
  306. }
  307. } completion:^(BOOL finished) {
  308. [self removeFromSuperview];
  309. }];
  310. }
  311. }
  312. #pragma mark - 刷新选择器数据
  313. - (void)reloadData {
  314. }
  315. #pragma mark - 添加自定义视图到选择器(picker)上
  316. - (void)addSubViewToPicker:(UIView *)customView {
  317. }
  318. #pragma mark - 添加自定义视图到标题栏(titleBar)上
  319. - (void)addSubViewToTitleBar:(UIView *)customView {
  320. if (!self.pickerStyle.hiddenTitleBarView) {
  321. [self.titleBarView addSubview:customView];
  322. }
  323. }
  324. - (BRPickerStyle *)pickerStyle {
  325. if (!_pickerStyle) {
  326. _pickerStyle = [[BRPickerStyle alloc]init];
  327. }
  328. return _pickerStyle;
  329. }
  330. - (UIView *)keyView {
  331. if (!_keyView) {
  332. _keyView = BRGetKeyWindow();
  333. }
  334. return _keyView;
  335. }
  336. #pragma mark - 设置 view 的部分圆角
  337. // corners(枚举类型,可组合使用):UIRectCornerTopLeft | UIRectCornerTopRight | UIRectCornerBottomLeft | UIRectCornerBottomRight | UIRectCornerAllCorners
  338. - (void)br_setView:(UIView *)view roundingCorners:(UIRectCorner)corners withRadius:(CGFloat)radius {
  339. UIBezierPath *rounded = [UIBezierPath bezierPathWithRoundedRect:view.bounds byRoundingCorners:corners cornerRadii:CGSizeMake(radius, radius)];
  340. CAShapeLayer *shape = [[CAShapeLayer alloc]init];
  341. [shape setPath:rounded.CGPath];
  342. view.layer.mask = shape;
  343. }
  344. #pragma mark - setter 方法(支持动态设置标题)
  345. - (void)setTitle:(NSString *)title {
  346. _title = title;
  347. if (_titleLabel) {
  348. _titleLabel.text = title;
  349. }
  350. }
  351. - (void)dealloc {
  352. NSLog(@"%@ dealloc", NSStringFromClass([self class]));
  353. }
  354. @end