自定义点赞切换控件

场景:

点赞功能这样的需求很常见,一般我们会考虑是否可以直接用 UIButton 实现,UIButton 作为一个系统复合控件,外部是一个 View + UIControl 的容器,内部包含了 UILabel 和 UIImage、以及排版规则。用 UIButton 不好控制去做『赞』和『取消赞』切换时的动画效果。

可是我们又很需要 UIButton 控件的事件响应机制。怎么办呢?

这时我们可以考虑使用 UIControl,在这里有两个突出的优势:

1、作为 UIButton 的父控件,具有 UIButton 一样的事件响应机制

2、作为 UIView 的简单子控件,具有作为容器视图的潜质

实现方式:

继承 UIControl 的自定义控件包含多个图片视图,通过控制多个图片视图的透明度和缩放动画效果来切换。这里抛砖引玉,只是一种实现思路。

效果如下:

 

KMFlagView.h

 1 #import <UIKit/UIKit.h>
 2 
 3 typedef NS_ENUM(NSInteger, FlagMode) {
 4     FlagModeNO = 0,
 5     FlagModeYES = 1,
 6     FlagModeDefault = 2
 7 };
 8 
 9 @interface KMFlagView : UIControl
10 {
11     @private
12     UIImageView *_imgVNO;
13     UIImageView *_imgVYES;
14     UIImageView *_imgVDefault;
15 }
16 
17 @property (strong, nonatomic) UIImage *imgNO;
18 @property (strong, nonatomic) UIImage *imgYES;
19 @property (strong, nonatomic) UIImage *imgDefault;
20 @property (assign, nonatomic) FlagMode flag;
21 
22 - (instancetype)initWithFrame:(CGRect)frame withImgNO:(UIImage *)imgNO withImgYES:(UIImage *)imgYES withImgDefault:(UIImage *)imgDefault;
23 - (void)changeToFlag:(FlagMode)flag withAnimation:(BOOL)animation;
24 
25 @end

KMFlagView.m

  1 #import "KMFlagView.h"
  2 
  3 @interface KMFlagView ()
  4 
  5 @end
  6 
  7 @implementation KMFlagView
  8 
  9 #pragma mark - Override Property Method
 10 - (void)setImgNO:(UIImage *)imgNO {
 11     if (!_imgVNO) {
 12         _imgVNO = [[UIImageView alloc] initWithFrame:self.bounds];
 13         _imgVNO.contentMode = UIViewContentModeCenter;
 14         _imgVNO.alpha = 0.0;
 15         [self addSubview:_imgVNO];
 16     }
 17     _imgVNO.image = imgNO;
 18     _imgNO = imgNO;
 19 }
 20 
 21 - (void)setImgYES:(UIImage *)imgYES {
 22     if (!_imgVYES) {
 23         _imgVYES = [[UIImageView alloc] initWithFrame:self.bounds];
 24         _imgVYES.contentMode = UIViewContentModeCenter;
 25         _imgVYES.alpha = 0.0;
 26         [self addSubview:_imgVYES];
 27     }
 28     _imgVYES.image = imgYES;
 29     _imgYES = imgYES;
 30 }
 31 
 32 - (void)setImgDefault:(UIImage *)imgDefault {
 33     if (!_imgVDefault) {
 34         _imgVDefault = [[UIImageView alloc] initWithFrame:self.bounds];
 35         _imgVDefault.contentMode = UIViewContentModeCenter;
 36         _imgVDefault.alpha = 1.0;
 37         [self addSubview:_imgVDefault];
 38     }
 39     _imgVDefault.image = imgDefault;
 40     _imgDefault = imgDefault;
 41 }
 42 
 43 #pragma mark - Public Method
 44 - (instancetype)initWithFrame:(CGRect)frame withImgNO:(UIImage *)imgNO withImgYES:(UIImage *)imgYES withImgDefault:(UIImage *)imgDefault {
 45     if (self = [super initWithFrame:frame]) {
 46         //In order to use [Override Property Method]
 47         self.imgNO = imgNO;
 48         self.imgYES = imgYES;
 49         self.imgDefault = imgDefault;
 50         
 51         _flag = FlagModeDefault;
 52     }
 53     return self;
 54 }
 55 
 56 - (void)changeToFlag:(FlagMode)flag withAnimation:(BOOL)animation {
 57     if (animation) {
 58         if (flag == FlagModeYES) {
 59             _imgVYES.transform = CGAffineTransformMakeScale(0.1, 0.1);
 60             [UIView animateWithDuration:0.5
 61                              animations:^{
 62                                  _imgVYES.alpha = 1.0;
 63                                  _imgVNO.alpha = 0.0;
 64                                  _imgVDefault.alpha = 0.0;
 65                                  
 66                                  _imgVYES.transform = CGAffineTransformMakeScale(1.0, 1.0);
 67                                  _imgVNO.transform = CGAffineTransformMakeScale(2.0, 2.0);
 68                              } completion:^(BOOL finished) {
 69                                  _imgVYES.transform = CGAffineTransformMakeScale(1.0, 1.0);
 70                                  _imgVNO.transform = CGAffineTransformMakeScale(1.0, 1.0);
 71                              }];
 72         } else {
 73             _imgVNO.transform = CGAffineTransformMakeScale(0.1, 0.1);
 74             [UIView animateWithDuration:0.5
 75                              animations:^{
 76                                  _imgVYES.alpha = 0.0;
 77                                  _imgVNO.alpha = 1.0;
 78                                  _imgVDefault.alpha = 0.0;
 79                                  
 80                                  _imgVYES.transform = CGAffineTransformMakeScale(2.0, 2.0);
 81                                  _imgVNO.transform = CGAffineTransformMakeScale(1.0, 1.0);
 82                              } completion:^(BOOL finished) {
 83                                  _imgVYES.transform = CGAffineTransformMakeScale(1.0, 1.0);
 84                                  _imgVNO.transform = CGAffineTransformMakeScale(1.0, 1.0);
 85                              }];
 86         }
 87     } else {
 88         if (flag == FlagModeYES) {
 89             _imgVYES.alpha = 1.0;
 90             _imgVNO.alpha = 0.0;
 91             _imgVDefault.alpha = 0.0;
 92         } else {
 93             _imgVYES.alpha = 0.0;
 94             _imgVNO.alpha = 1.0;
 95             _imgVDefault.alpha = 0.0;
 96         }
 97         _imgVYES.transform = CGAffineTransformMakeScale(1.0, 1.0);
 98         _imgVNO.transform = CGAffineTransformMakeScale(1.0, 1.0);
 99         _imgVDefault.transform = CGAffineTransformMakeScale(1.0, 1.0);
100     }
101     _flag = flag;
102 }
103 
104 @end

ViewController.h

1 #import <UIKit/UIKit.h>
2 #import "KMFlagView.h"
3 
4 @interface ViewController : UIViewController
5 @property (strong, nonatomic) KMFlagView *flagView;
6 
7 @end

ViewController.m

 1 #import "ViewController.h"
 2 
 3 @interface ViewController ()
 4 - (void)layoutUI;
 5 - (void)flagViewDidPush:(KMFlagView *)sender;
 6 @end
 7 
 8 @implementation ViewController
 9 
10 - (void)viewDidLoad {
11     [super viewDidLoad];
12     
13     [self layoutUI];
14 }
15 
16 - (void)didReceiveMemoryWarning {
17     [super didReceiveMemoryWarning];
18     // Dispose of any resources that can be recreated.
19 }
20 
21 - (void)layoutUI {
22     UIImage *imgNO = [UIImage imageNamed:@"OrderDetails_Like"];
23     UIImage *imgYES = [UIImage imageNamed:@"OrderDetails_LikePress"];
24     UIImage *imgDefault = [UIImage imageNamed:@"OrderDetails_Default"];
25     
26     _flagView = [[KMFlagView alloc] initWithFrame:CGRectMake(0, 0, 80.0, 80.0)
27                                         withImgNO:imgNO
28                                        withImgYES:imgYES
29                                    withImgDefault:imgDefault];
30     _flagView.center = self.view.center;
31     [_flagView addTarget:self
32                   action:@selector(flagViewDidPush:)
33         forControlEvents:UIControlEventTouchUpInside];
34     [self.view addSubview:_flagView];
35 }
36 
37 - (void)flagViewDidPush:(KMFlagView *)sender {
38     FlagMode flag = sender.flag != FlagModeYES ? FlagModeYES : FlagModeNO;
39     [sender changeToFlag:flag withAnimation:YES];
40 }
41 
42 @end
原文地址:https://www.cnblogs.com/huangjianwu/p/4656831.html