CustomSwitch.m 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. //
  2. // CustomSwitch.m
  3. // Starbuds
  4. //
  5. // Created by 翟玉磊 on 2020/1/17.
  6. // Copyright © 2020 翟玉磊. All rights reserved.
  7. //
  8. #import "CustomSwitch.h"
  9. @interface CustomSwitch ()
  10. @property (nonatomic, readwrite, strong) UIImageView *bgImageView;
  11. @property (nonatomic, readwrite, strong) UIImageView *selectImageView;
  12. @property (nonatomic, readwrite, assign) BOOL feedStatus;
  13. @end
  14. @implementation CustomSwitch
  15. #pragma mark - Public Method
  16. - (void)setOn:(BOOL)on {
  17. _on = on;
  18. // 主动设置的都没有震动效果
  19. self.feedStatus = NO;
  20. [self changeStatus];
  21. }
  22. - (void)setBgColor:(UIColor *)bgColor {
  23. _bgColor = bgColor;
  24. self.bgImageView.backgroundColor = bgColor;
  25. }
  26. - (void)setBgImage:(UIImage *)bgImage {
  27. _bgImage = bgImage;
  28. self.bgImageView.image = bgImage;
  29. }
  30. #pragma mark - Private Method
  31. - (instancetype)initWithCoder:(NSCoder *)coder {
  32. if (self = [super initWithCoder:coder]) {
  33. // 初始化
  34. [self _setup];
  35. // 创建子控件
  36. [self _setupSubViews];
  37. // 布局子控件
  38. [self _makeSubViewsConstraints];
  39. }
  40. return self;
  41. }
  42. - (instancetype)initWithFrame:(CGRect)frame{
  43. if (self = [super initWithFrame:frame]) {
  44. // 初始化
  45. [self _setup];
  46. // 创建子控件
  47. [self _setupSubViews];
  48. // 布局子控件
  49. [self _makeSubViewsConstraints];
  50. }
  51. return self;
  52. }
  53. #pragma mark - 事件处理Or辅助方法
  54. - (void)topAction:(UITapGestureRecognizer *)tap {
  55. self.on = !self.on;
  56. self.feedStatus = YES;
  57. [self changeStatus];
  58. }
  59. - (void)changeStatus {
  60. [UIView animateWithDuration:.3 animations:^{
  61. CGFloat width = self.height - self.margin * 2;
  62. if (self.on) {
  63. self.selectImageView.frame = CGRectMake(self.f_width - self.margin - width, self.margin, width, width);
  64. }else {
  65. self.selectImageView.frame = CGRectMake(self.margin, self.margin, width, width);
  66. }
  67. } completion:^(BOOL finished) {
  68. if (self.on) {
  69. if (self.onImage) {
  70. self.selectImageView.image = self.onImage;
  71. }else {
  72. self.selectImageView.backgroundColor = self.onTintColor;
  73. }
  74. }else {
  75. if (self.offImage) {
  76. self.selectImageView.image = self.offImage;
  77. }else {
  78. self.selectImageView.backgroundColor = self.thumbTintColor;
  79. }
  80. }
  81. if (self.feedStatus) {
  82. // 都是轻度震动
  83. if (@available(iOS 10.0, *)) {
  84. UIImpactFeedbackGenerator *feedBackGenertor = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleLight];
  85. [feedBackGenertor impactOccurred];
  86. } else {
  87. // Fallback on earlier versions
  88. AudioServicesPlaySystemSound(1519);
  89. }
  90. }
  91. }];
  92. }
  93. #pragma mark - Private Method
  94. // 当用户点击到当前控件bounds时,会调用该方法,返回值决定了当前控件是否响应该事件
  95. - (BOOL)beginTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
  96. return [super beginTrackingWithTouch:touch withEvent:event]; // 返回系统默认处理
  97. }
  98. // 如果 beginTrackingWithTouch 返回值 为YES,则以下方法 会在 点击手机屏幕移动 时 调用,如果这里返回值为YES,则继续移动会多次调用。
  99. // 如果 返回 NO,则 即使 继续移动也不会再调用当前方法了。
  100. - (BOOL)continueTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
  101. return [super continueTrackingWithTouch:touch withEvent:event];
  102. }
  103. // 当点击屏幕释放时,调用该方法
  104. - (void)endTrackingWithTouch:(UITouch *)touch withEvent:(UIEvent *)event {
  105. self.on = !self.on;
  106. self.feedStatus = YES;
  107. [self changeStatus];
  108. [super endTrackingWithTouch:touch withEvent:event];
  109. }
  110. // 取消时会调用,如果当前视图被移除。或者来电
  111. - (void)cancelTrackingWithEvent:(UIEvent *)event {
  112. [super cancelTrackingWithEvent:event];
  113. }
  114. - (void)_setup{
  115. }
  116. #pragma mark - 创建子控件
  117. - (void)_setupSubViews{
  118. [self addSubview:self.bgImageView];
  119. [self addSubview:self.selectImageView];
  120. // self.userInteractionEnabled = YES;
  121. // UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(topAction:)];
  122. // tap.numberOfTapsRequired = 1;
  123. // tap.numberOfTouchesRequired = 1;
  124. // [self addGestureRecognizer:tap];
  125. }
  126. #pragma mark - 布局子控件
  127. - (void)_makeSubViewsConstraints{
  128. self.bgImageView.frame = self.bounds;
  129. self.selectImageView.frame = CGRectMake(self.margin, self.margin, self.height - self.margin * 2, self.height - self.margin * 2);
  130. }
  131. - (UIImageView *)bgImageView {
  132. if (!_bgImageView) {
  133. _bgImageView = [UIImageView new];
  134. }
  135. return _bgImageView;
  136. }
  137. - (UIImageView *)selectImageView {
  138. if (!_selectImageView) {
  139. _selectImageView = [UIImageView new];
  140. }
  141. return _selectImageView;
  142. }
  143. @end