在开发当中,可能很多时候都需要做个点赞的需求,如果用按钮实现,按钮作为一个系统复合控件,外部是一个 View--》UIControl的容器,

内部包含了UILabel和UIImage,以及一些排版规则。用UIButton就很难去做一些在“赞”和“取消赞”切换时的效果。

可是我们又很需要UIButton似的事件响应机制。

怎么办?

对! 就是使用UIControl。

UIControl在这里有两个突出的优势:

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

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

设计思路:实现一个自定义控件,继承UIControl,里面包含一些视图,包含什么视图由你的需求决定,我的是两张图片。 然后在事件响应时,两张图片进行切换。切换动画可以自定义。这样就实现了一个切换效果自由度很大的点赞按钮哦!

参考代码如下:

  1. #import <UIKit/UIKit.h>
  2. typedef NS_ENUM(NSInteger, UIControlFlagMode) {
  3. FlagModelNO,
  4. FlagModelYES,
  5. FlagModelDefalt
  6. };
  7. @interface UIControlFlagView : UIControl
  8. @property (nonatomic, strong) UIImage*noStateImg;
  9. @property (nonatomic, strong) UIImage*yesStateImg;
  10. @property (nonatomic, strong) UIImage*defaultStateImg;
  11. @property (nonatomic, assign) UIControlFlagMode flag;
  12. - (void)setFlag:(UIControlFlagMode)flag withAnimation:(BOOL)animation;
  13. @end

m文件:

  1. #import "UIControlFlagView.h"
  2. @interface UIControlFlagView()
  3. @property (nonatomic, strong) UIImageView*noStateImgV;
  4. @property (nonatomic, strong) UIImageView*yesStateImgV;
  5. @property (nonatomic, strong) UIImageView*defaultStateImgV;
  6. @end
  7. @implementation UIControlFlagView
  8. - (id)initWithFrame:(CGRect)frame
  9. {
  10. self = [super initWithFrame:frame];
  11. if (self) {
  12. // Initialization code
  13. }
  14. return self;
  15. }
  16. - (void)setNoStateImg:(UIImage *)noStateImg
  17. {
  18. if (!self.noStateImgV)
  19. {
  20. self.noStateImgV = [[UIImageView alloc] initWithFrame:self.bounds];
  21. self.noStateImgV.contentMode = UIViewContentModeCenter;
  22. [self addSubview:self.noStateImgV];
  23. self.flag = FlagModelNO;//default style
  24. }
  25. self.noStateImgV.image = noStateImg;
  26. _noStateImg = noStateImg;
  27. }
  28. - (void)setYesStateImg:(UIImage *)yesStateImg
  29. {
  30. if (!self.yesStateImgV)
  31. {
  32. self.yesStateImgV = [[UIImageView alloc] initWithFrame:self.bounds];
  33. self.yesStateImgV.contentMode = UIViewContentModeCenter;
  34. [self addSubview:self.yesStateImgV];
  35. self.yesStateImgV.alpha = 0.0;
  36. }
  37. self.yesStateImgV.image = yesStateImg;
  38. _yesStateImg = yesStateImg;
  39. }
  40. - (void)setDefaultStateImg:(UIImage *)defaultStateImg
  41. {
  42. if (!self.defaultStateImgV)
  43. {
  44. self.defaultStateImgV = [[UIImageView alloc] initWithFrame:self.bounds];
  45. self.defaultStateImgV.contentMode = UIViewContentModeCenter;
  46. [self addSubview:self.defaultStateImgV];
  47. }
  48. self.defaultStateImgV.image = defaultStateImg;
  49. _defaultStateImg = defaultStateImg;
  50. }
  51. - (void)setFlag:(UIControlFlagMode)flag withAnimation:(BOOL)animation
  52. {
  53. if (animation)
  54. {
  55. //no-->yes
  56. if (_flag == FlagModelNO && flag == FlagModelYES)
  57. {
  58. self.yesStateImgV.transform = CGAffineTransformMakeScale(0.1f, 0.1f);
  59. [UIView animateWithDuration:0.3 animations:^{
  60. self.noStateImgV.alpha = 0.0;
  61. self.yesStateImgV.alpha = 1.0;
  62. self.yesStateImgV.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
  63. self.noStateImgV.transform = CGAffineTransformMakeScale(2.0f, 2.0f);
  64. }
  65. completion:^(BOOL finished)
  66. {
  67. self.yesStateImgV.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
  68. self.noStateImgV.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
  69. }];
  70. }
  71. //yes-->no
  72. else if(_flag == FlagModelYES && flag == FlagModelNO)
  73. {
  74. self.noStateImgV.transform = CGAffineTransformMakeScale(0.1f, 0.1f);
  75. [UIView animateWithDuration:0.3 animations:^{
  76. self.noStateImgV.alpha = 1.0;
  77. self.yesStateImgV.alpha = 0.0;
  78. self.yesStateImgV.transform = CGAffineTransformMakeScale(2.0f, 2.0f);
  79. self.noStateImgV.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
  80. }
  81. completion:^(BOOL finished)
  82. {
  83. self.yesStateImgV.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
  84. self.noStateImgV.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
  85. }];
  86. }
  87. }
  88. else
  89. {
  90. //no-->yes
  91. if (_flag == FlagModelNO && flag == FlagModelYES)
  92. {
  93. self.noStateImgV.alpha = 0.0;
  94. self.yesStateImgV.alpha = 1.0;
  95. self.yesStateImgV.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
  96. self.noStateImgV.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
  97. }
  98. //yes-->no
  99. else if(_flag == FlagModelYES && flag == FlagModelNO)
  100. {
  101. self.noStateImgV.alpha = 1.0;
  102. self.yesStateImgV.alpha = 0.0;
  103. self.yesStateImgV.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
  104. self.noStateImgV.transform = CGAffineTransformMakeScale(1.0f, 1.0f);
  105. }
  106. }
  107. _flag = flag;
  108. }
  109. @end

这是一个简单的实现,最大的优势,也是这篇文章的目的,就是在切换效果上的自定义和自由度!

抛砖引玉,希望大家都能做出复合自己心中所想的点赞按钮!

UIControl的使用的更多相关文章

  1. 你真的了解UIControl吗?

    一:首先查看一下关于UIControl的定义 NS_CLASS_AVAILABLE_IOS(2_0) @interface UIControl : UIView //控件默认是启用的YES.是否要禁用 ...

  2. iOS UIControl 详解

    UIControl是UIView的子类,当然也是UIResponder的子类.UIControl是诸如UIButton,UISwitch,UItextField等控件的父类,它本身包含了一些属性和方法 ...

  3. iOS学习24之UIControl及其子类

    1. UIControl初识 1> 概述 UIControl是有控制功能的视图( 如UIButton.UISlider.UISegmentedControl等)的父类 只要跟控制有关的控件都是继 ...

  4. IOS开发UI基础UIControl事件

    UIControl事件1.UIControlEventTouchDown单点触摸按下事件:用户点触屏幕,或者又有新手指落下的时候. 2.UIControlEventTouchDownRepeat多点触 ...

  5. iOS - UIControl

    前言 NS_CLASS_AVAILABLE_IOS(2_0) @interface UIControl : UIView @available(iOS 2.0, *) public class UIC ...

  6. iOS学习之UIControl

    一.UIControl初识      1.UIControl是有控制功能的视图(比如UIButton.UISlider.UISegmentedControl等)的父类. 只要跟控制有关的控件都是继承于 ...

  7. iOS开发~视图(UIView)与控件(UIControl)

    1.UIView类 1.什么是视图 看得见的都是视图 2.什么是控件 一种特殊的视图,都是UIControl的子类,不仅具有一定的显示外观,还能响应高级事件,与用户交互.严格意义上UILabel不是控 ...

  8. MATLAB中为控件(uicontrol)绑定Callback函数(回调函数)

    笔者走了许多弯路,终于找到这个方法,分享给大家. 'callback',@(~,~)colormapeditor(h) 如果版本老不支持“~”这种写法,那就改成: 'callback',@(x,y)c ...

  9. ##DAY5 UIControl及其子类

    ##DAY5 UIControl及其子类 #pragma mark ———————UIControl——————————— UIControl初识: 1)UIControl是有控制功能的视图(比如UI ...

随机推荐

  1. 20145218 《Java程序设计》第二周学习总结

    Java中的注释格式 单行注释 //注释文字 多行注释 /注释文字/ 文档注释 /**注释文字*/ 注释不仅仅是对代码进行解释,在上一篇博客中也写过,注释也可以用来检查程序中的错误,可以说是一个小窍门 ...

  2. swiper轮播图--兼容IE8

    //引入idangerous.swiper.min.js var mySwiper = new Swiper ('.swiper-container', { loop: true, paginatio ...

  3. jsp之 ---- 页面重定向和请求转发(笔记之深度说明)

    1.  HttpServletResponse对象的sendRedirect(String location)方法称作重定向. 如果location地址前面加上“/”,则表示  相对于Servlet容 ...

  4. Could not load file or assembly 'System.Web.Mvc' or one of its dependencies. The located assembly's manifest definition does not

    因为用了MVC,在本地是没有问题的,但是部署在服务器就出现了这个问题. 出错界面如下图 原因分析:上面的出错提示最后一句话翻译过来.找到的程序集清单定义与程序集引用不匹配.也就是程序引用的程序集版本和 ...

  5. jquery通过ajax方法获取json数据不执行success

    1.jquery通过ajax方法获取json数据不执行success回调 问题描述:jquery通过ajax方法获取json数据不执行success回调方法 问题原因:json格式存在问题或不符合标准 ...

  6. Q: How could I use MATLAB interface for parameter selection?

    Q: How could I use MATLAB interface for parameter selection? One can do this by a simple loop. See t ...

  7. HDU 2546(01背包)

    饭卡 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submissi ...

  8. Jquery操作select小结

    每次操作select都要查资料,干脆总结一下. 为select设置placeholder <select class="form-control selOP" placeho ...

  9. poi 读取 excel(.xlsx) 2007及以上版本

    1.注意的一点是sh.getLastRowNum(),比实际的行数少一行 涉及到的包:

  10. Error in Android Studio - "Default Activity Not Found"

    Make sure you have specified the default activity in your AndroidManisfest.xml file. Within your def ...