文章目录

  • 基本知识
  • 设置边框和选择状态下的背景颜色
  • UIbutton设置圆角
  • 普通圆角按钮
  • 离屏渲染
  • 绘制图像上下文
  • UIButtonType导致的bug
  • UIButton-如何正确的设置背景图片
  • 创建
  • 背景图片
  • 实例解析
  • 为什么要设置highlighted而不是selected


基本知识

第一、UIButton的定义

UIButton *button=[[UIButton buttonWithType:(UIButtonType);

能够定义的button类型有以下6种,

typedef enum {
 UIButtonTypeCustom = 0, 自定义风格UIButtonTypeRoundedRect, 圆角矩形
UIButtonTypeDetailDisclosure, 蓝色小箭头按钮,主要做详细说明用
UIButtonTypeInfoLight, 亮色感叹号
 UIButtonTypeInfoDark, 暗色感叹号
 UIButtonTypeContactAdd, 十字加号按钮} UIButtonType;

第二、设置frame

button1.frame = CGRectMake(20, 20, 280, 40);
[button setFrame:CGRectMake(20,20,50,50)];

第三、button背景色

button1.backgroundColor = [UIColor clearColor];
[button setBackgroundColor:[UIColor blueColor]];

第四、state状态

forState: 这个参数的作用是定义按钮的文字或图片在何种状态下才会显现

enum {
 UIControlStateNormal = 0, 常规状态显现
 UIControlStateHighlighted = 1 << 0, 高亮状态显现
 UIControlStateDisabled = 1 << 1, 禁用的状态才会显现
 UIControlStateSelected = 1 << 2, 选中状态
 UIControlStateApplication = 0x00FF0000, 当应用程序标志时UIControlStateReserved = 0xFF000000 为内部框架预留,可以不管他
 };@property(nonatomic,getter=isEnabled)BOOL enabled; // default is YES. if NO, ignores touch events and subclasses may draw differently
@property(nonatomic,getter=isSelected)BOOL selected; // default is NO may be used by some subclasses or by application
@property(nonatomic,getter=isHighlighted)BOOL highlighted;

第五 、设置button填充图片和背景图片

[buttonsetImage:[UIImageimageNamed:@"checkmarkControllerIcon"]forState:UIControlStateNormal];

[buttonsetBackgroundImage:[UIImageimageNamed:@"checkmarkControllerIcon"]forState:UIControlStateNormal];

第六、设置button标题和标题颜色

[button1 setTitle:@“点击” forState:UIControlStateNormal];
[buttonsetTitleColor:[UIColorredColor]forState:UIControlStateNormal];

第七、设置按钮按下会发光

button.showsTouchWhenHighlighted=NO;

第八、添加或删除事件处理

[button1 addTarget:self action:@selector(butClick:) forControlEvents:UIControlEventTouchUpInside];
[btn removeTarget:nil action:nil forControlEvents:UIControlEventTouchUpInside];

第九、 设置按钮内部图片间距和标题间距

UIEdgeInsets insets; // 设置按钮内部图片间距
 insets.top = insets.bottom = insets.right = insets.left = 10;
 bt.contentEdgeInsets = insets;
 bt.titleEdgeInsets = insets; // 标题间距

设置边框和选择状态下的背景颜色

[self LimitedCountBtnInit];
[self LimitedTimeBtnInit];
- (void)LimitedCountBtnInit{
   // self.LimitedCountBtn.layer.borderColor=[UIColor blueColor].CGColor;
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    CGColorRef color = CGColorCreate(colorSpaceRef, (CGFloat[]){73/255,230/255,255/255,0.2});
    self.LimitedCountBtn.layer.borderColor=color;
   self.LimitedCountBtn.layer.borderWidth=1.0f;
   // self.LimitedCountBtn.layer.cornerRadius=10.0f;
    self.LimitedCountBtn.layer.masksToBounds=YES;
    [self.LimitedCountBtn addTarget:self action:@selector(LimitedCountBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
    [self.LimitedCountBtn addObserver:self forKeyPath:@"selected" options:NSKeyValueObservingOptionNew context:nil];
}
- (void)LimitedTimeBtnInit{
    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
    CGColorRef color = CGColorCreate(colorSpaceRef, (CGFloat[]){73/255,230/255,255/255,0.2});
    self.LimitedTimeBtn.layer.borderColor=color;
    self.LimitedTimeBtn.layer.borderWidth=1.0f;
    //self.LimitedTimeBtn.layer.cornerRadius=10.0f;
    self.LimitedTimeBtn.layer.masksToBounds=YES;
    [self.LimitedTimeBtn addTarget:self action:@selector(LimitedTimeBtnClicked:) forControlEvents:UIControlEventTouchUpInside];
    [self.LimitedTimeBtn addObserver:self forKeyPath:@"selected" options:NSKeyValueObservingOptionNew context:nil];
}

-(void)LimitedCountBtnClicked:(UIButton*)button{
    [self.LimitedTimeBtn setSelected:NO];
    [button setSelected:YES];
    
}
-(void)LimitedTimeBtnClicked:(UIButton*)button{
    [self.LimitedCountBtn setSelected:NO];
    [button setSelected:YES];
    
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)change context:(void *)context{
    UIButton *button = (UIButton *)object;
    if ([keyPath isEqualToString:@"selected"]) {
        if (button.selected) {
            [button setBackgroundColor:[UIColor blueColor]];
            return;
        }
        [button setBackgroundColor:[UIColor whiteColor]];
    }
}

ios 按钮点击如何得到按下抬起 iphone怎么设置按钮形状_ios 按钮点击如何得到按下抬起


注:需要优化,因为button在按下时,状态是highlighted,而不是selected,所以设置selected是没有作用的。上述代码是主动置类selected

UIbutton设置圆角

普通圆角按钮

UIButton *doneBtn = [UIButton buttonWithType:UIButtonTypeCustom];
doneBtn.frame = CGRectMake(0,0,40,20);
doneBtn.backgroundColor = [UIColor redColor];
//设置圆角的大小
doneBtn.layer.cornerRadius = 3;
//此行代码必须有(UIView例外)
doneBtn.layer.masksToBounds = YES;
doneBtn.titleLabel.font = [UIFont systemFontOfSize:15];
[doneBtn setTitle:@"按钮" forState:UIControlStateNormal];
[doneBtn addTarget:self     action:@selector(clickdoneWithButton:)  forControlEvents:UIControlEventTouchUpInside];

离屏渲染

以上方法只适用于一个界面只有几个按钮,如果是大量的按钮,如UITableViewCell上那么就会出现卡顿,造成这个原因就是离屏渲染。
所谓离屏渲染指的是GPU在当前屏幕缓冲区以外新开辟一个缓冲区进行渲染操作。
而以下一些行为都会触发离屏渲染
shouldRasterize(光栅化)
masks(遮罩)
shadows(阴影)
edge antialiasing(抗锯齿)
group opacity(不透明)
这里我们设置了masksToBounds属性,所以会触发离屏渲染,因而卡顿。

绘制图像上下文

/// 生成纯色图片
/// @param color  [UIColor redColor]
/// @param rect CGRectMake(0, 0, _editBtn.frame.size.width, _editBtn.frame.size.height)],必须0,0开始
+ (UIImage *)createImageWithColor:(UIColor *)color frame:(CGRect)rect
{
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(context, [color CGColor]);
    CGContextFillRect(context, rect);
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return img;
}

/// 对图片生成圆角,可用于button等的背景图片
/// @param OriginalImage 原图,可用纯色图片
/// @param sizeToFit 大小
/// @param radius 圆角弧度
+ (UIImage *)OriginalImage:(UIImage *)OriginalImage WithRoundedCornersAndSize:(CGSize)sizeToFit andCornerRadius:(CGFloat)radius
{
CGRect rect = (CGRect){0.f, 0.f, sizeToFit};
UIGraphicsBeginImageContextWithOptions(sizeToFit, NO, UIScreen.mainScreen.scale);
CGContextAddPath(UIGraphicsGetCurrentContext(),
[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:4].CGPath);
CGContextClip(UIGraphicsGetCurrentContext());
[OriginalImage drawInRect:rect];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
}

@end

使用

UIImage *imageColor=[DrawImage createImageWithColor:[UIColor redColor] frame: CGRectMake(0, 0, _editBtn.frame.size.width, _editBtn.frame.size.height)];
       
        [_editBtn setBackgroundImage:[DrawImage OriginalImage: imageColor WithRoundedCornersAndSize:_editBtn.frame.size andCornerRadius:3.0 ] forState:UIControlStateNormal];

ios 按钮点击如何得到按下抬起 iphone怎么设置按钮形状_离屏渲染_02

UIButtonType导致的bug

上述设置边框和选择状态下的背景颜色的例子,如果UIButtonType 是UIButtonTypeCustom,选中状态下设置背景颜色会很正常。但是UIButtonType如果是系统样式如UIButtonTypeRoundedRect,选中状态下设置背景颜色会有如下bug

ios 按钮点击如何得到按下抬起 iphone怎么设置按钮形状_ios 按钮点击如何得到按下抬起_03

UIButton-如何正确的设置背景图片

创建

xib:直接拖
code:UIButton* button = [UIButton buttonWithType:UIButtonTypeCustom];

注意:xib中直接拖进去的button默认为UIButtonTypeSystem,该类型默认会对button做些一些定制化工作(包括字体,颜色等),如果我们在该类型的基础上对button做自定义背景图片,会产生错误的效果。对于我们最常用的按钮,通常设定为UIButtonTypeCustom

背景图片

设置常态下的背景图片 [self.button setBackgroundImage:[UIImage imageNamed:@“green_btn_normal”] forState:UIControlStateNormal]; 设置按下状态的背景图片 [self.button setBackgroundImage:[UIImage imageNamed:@“green_btn_selected”] forState:UIControlStateHighlighted];

注意:按下状态时,state的值是UIControlStateHighlighted,而不是selected,只有这样设置,才能让你的按钮显示出正确的颜色

实例解析

制作demo,需求如下:

创建2个按钮

SystemTypeOriginal为storyboard中直接拖上去的button,type保持system不变,设置green_btn_normal.png为normal状态的背景图片,设置green_btn_selected.png为highlighted状态的背景图片

CustomTypeOriginal为storyboard中直接拖上去的button,type设置为Custom,设置green_btn_normal.png为normal状态的背景图片,设置green_btn_selected.png为highlighted状态的背景图片

运行demo,效果图如下:

ios 按钮点击如何得到按下抬起 iphone怎么设置按钮形状_离屏渲染_04


通过上图分析可知:

SystemType下字体默认为15,且字体颜色为蓝色
CustomType下字体默认为18,字体颜色为白色
普通状态下的按钮背景图片与预期相符,green_btn_normal表示的是原始图片的颜色,此时原始图片颜色与按钮背景颜色一致
此时,按下SystemTypeOriginal,效果图如下:

按下SystemTypeOriginal

上图的按下效果变得非常诡异,与预期的green_btn_selected颜色相差甚远,这就是上面说的,在systemtype下,设置背景图片会产生错误的效果,所以常用的按钮都会设置为Customtype。

那么,我们按下CustomTypeOriginal,看下效果图:

ios 按钮点击如何得到按下抬起 iphone怎么设置按钮形状_背景图片_05


按下CustomTypeOriginal

ios 按钮点击如何得到按下抬起 iphone怎么设置按钮形状_圆角_06

现在按下的背景图片就对了!

为什么要设置highlighted而不是selected

因为button在按下时,状态是highlighted,而不是selected,所以设置selected是没有作用的。
参考:https://www.jianshu.com/p/8fb8ff3fed44