RDMBorderedButton

简介:

RDMBorderedButton

https://github.com/reesemclean/RDMBorderedButton

效果:

源码:

RDMBorderedButton.h + RDMBorderedButton.m

//
//  RDMBorderedButton.h
//  RDMBorderedButton
//
//  Created by Reese McLean on 6/12/14.
//  Copyright (c) 2014 Reese McLean. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface RDMBorderedButton : UIButton

///Adjusting corner radius manually turns off automatic corner radius updating.
@property (nonatomic, assign) CGFloat cornerRadius;

///Determines whether the buttons corner radius is adjusting based on frame changes. Default = YES.
@property (nonatomic, assign) BOOL adjustsCornerRadiusBasedOnFrame;

///Approximate ratio of corner radius to smallest side of button frame. Default = 1.0/6.0.
@property (nonatomic, assign) CGFloat cornerRadiusRatioToSmallestSide;

@end


//
//  RDMBorderedButton.m
//  RDMBorderedButton
//
//  Created by Reese McLean on 6/12/14.
//  Copyright (c) 2014 Reese McLean. All rights reserved.
//

#import "RDMBorderedButton.h"

@implementation RDMBorderedButton

-(id) init {
    return [self initWithFrame:CGRectZero];
}

- (id)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        [self commonSetup];
    }
    return self;
}

-(id) initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        
        NSAssert(self.buttonType == UIButtonTypeCustom, @"RDMBorderedButton's created in interface builder must be set to type custom.");
        
        [self commonSetup];
    }
    return self;
}

-(void) commonSetup {
    
    [self setTitleColor:self.tintColor forState:UIControlStateNormal];
    [self setTitleColor:[UIColor whiteColor] forState:UIControlStateHighlighted];
    [self setTitleColor:[UIColor grayColor] forState:UIControlStateDisabled];
    
    _adjustsCornerRadiusBasedOnFrame = YES;
    _cornerRadiusRatioToSmallestSide = 1.0/6.0;
    [self adjustCornerRadius];
        
    self.layer.cornerRadius = _cornerRadius;
    self.layer.borderWidth = 1.0;
    self.layer.borderColor = self.tintColor.CGColor;
}

-(void) layoutSubviews {
    [super layoutSubviews];
    if (self.adjustsCornerRadiusBasedOnFrame) {
        [self adjustCornerRadius];
    }
}

-(void) tintColorDidChange {
    [super tintColorDidChange];
    [self setTitleColor:self.tintColor forState:UIControlStateNormal];
    [self updateBorderAndFill];
}

-(void) adjustCornerRadius {
    _cornerRadius = roundf(MIN(CGRectGetHeight(self.frame), CGRectGetWidth(self.frame)) * self.cornerRadiusRatioToSmallestSide);
    self.layer.cornerRadius = _cornerRadius;
}

-(void) setTitleColor:(UIColor *)color forState:(UIControlState)state {
    
    if ([[self titleColorForState:state] isEqual:color]) {
        return;
    }
    
    [super setTitleColor:color forState:state];
    
    if (state == UIControlStateNormal) {
        self.tintColor = color;
    }
    
    [self updateBorderAndFill];
}

-(void) setTintColor:(UIColor *)tintColor {
    
    if ([[self tintColor] isEqual:tintColor]) {
        return;
    }
    
    [super setTintColor:tintColor];
    [self setTitleColor:self.tintColor forState:UIControlStateNormal];
    [self updateBorderAndFill];
}

-(void) setCornerRadius:(CGFloat)cornerRadius {
    self.adjustsCornerRadiusBasedOnFrame = NO;
    _cornerRadius = cornerRadius;
    self.layer.cornerRadius = _cornerRadius;
}

-(void) setEnabled:(BOOL)enabled {

    [super setEnabled:enabled];
    [self updateBorderAndFill];
    
}

-(void) updateBorderAndFill {
    self.layer.borderColor = self.enabled ? self.tintColor.CGColor : [self titleColorForState:UIControlStateDisabled].CGColor;
    self.backgroundColor = self.highlighted ? self.tintColor : [UIColor clearColor];
}

-(void) setHighlighted:(BOOL)highlighted {
    
    if (self.highlighted == highlighted) {
        return;
    }
    
    [super setHighlighted:highlighted];
    
    [UIView animateWithDuration:0.2f
                          delay:0.0f
                        options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationOptionBeginFromCurrentState
                     animations:^{
                         self.backgroundColor = highlighted ? self.tintColor : [UIColor clearColor];
                     }
                     completion:nil];
    
}

@end

显示的代码:
//
//  RootViewController.m
//
//  http://home.cnblogs.com/u/YouXianMing/
//
//  Copyright (c) 2014年 Y.X. All rights reserved.
//

#import "RootViewController.h"
#import "RDMBorderedButton.h"

@interface RootViewController ()

@end

@implementation RootViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // 初始化
    RDMBorderedButton *button = \
        [[RDMBorderedButton alloc] initWithFrame:CGRectMake(0, 0, 100, 30)];
    button.center             = self.view.center;
    
    // 设置圆角
    button.cornerRadius       = 1.f;
    
    // 设置字体
    button.titleLabel.font    = [UIFont fontWithName:@"HelveticaNeue-Thin"
                                                size:13.f];
    
    // 设置标题
    [button setTitle:@"YouXianMing"
            forState:UIControlStateNormal];
    
    // 设置标题颜色
    [button setTitleColor:[UIColor redColor]
                 forState:UIControlStateNormal];
    
    [self.view addSubview:button];
}

@end

附录:

 

Usage

In code: Use initWithFrame to create a button and add to a subview.

Interface Builder: Add a button as usual. Set the class to RDMBorderedButton — there are some bugs with iOS 7.1 that require you to set the buttom type to Custom in Interface Builder. Also note that you can use the "User Defined Runtime Attributes" in Interface Builder to set the corner radius (key: "cornerRadius"). The example project shows this with the black and yellow buttons.

 

Corner Radius

By default, RDMBorderedButton will adjusts the corner radius of its border based on its frame. You can turn this off with:

button.adjustsCornerRadiusBasedOnFrame = NO; //Default is YES

You can also change the ratio of the corner radius of this automatic adjustment:

button.cornerRadiusRatioToSmallestSide = 1.0/4.0; //Default is 1.0/6.0

Note that changes to Corner Radius will not be animated. If you would like a corner radius change to be animated you will need to animate the key path using CoreAnimation. See the programatic view controller in the example project to see an example of this.

The corner radius can be adjusted manually (this turns off automatic adjustments):

//This will forward the cornerRadius to the button's layer and turn off automatic adjustments
button.cornerRadius = 6.0; 

 

Color

The text and border color are adjusted together. For normal state they can be changed using either:

button.tintColor = [UIColor greenColor];

or:

[button setTitleColor:[UIColor greenColor] forState:UIControlStateNormal]; 

Disabled state can be adjusted using:

[button setTitleColor:[UIColor grayColor] forState:UIControlStateDisabled]; //Default is [UIColor grayColor]

The text color when highlighted should be changed using:

[self setTitleColor:[UIColor blueColor] forState:UIControlStateHighlighted]; //Default is [UIColor whiteColor]

目录
相关文章
|
4天前
|
弹性计算 安全 API
访问控制(RAM)|云上安全使用AccessKey的最佳实践
集中管控AK/SK的生命周期,可以极大降低AK/SK管理和使用成本,同时通过加密和轮转的方式,保证AK/SK的安全使用,本次分享为您介绍产品原理,以及具体的使用步骤。
101786 0
|
5天前
|
SQL 关系型数据库 分布式数据库
Doodle Jump — 使用Flutter&Flame开发游戏真不错!
用Flutter&Flame开发游戏是一种什么体验?最近网上冲浪的时候,我偶然发现了一个国外的游戏网站,类似于国内的4399。在浏览时,我遇到了一款经典的小游戏:Doodle Jump...
|
12天前
|
弹性计算 运维 安全
访问控制(RAM)|云上程序使用临时凭证的最佳实践
STS临时访问凭证是阿里云提供的一种临时访问权限管理服务,通过STS获取可以自定义时效和访问权限的临时身份凭证,减少长期访问密钥(AccessKey)泄露的风险。本文将为您介绍产品原理,以及具体的使用步骤。
151035 4
|
10天前
|
数据采集 存储 运维
提升团队工程交付能力,从“看见”工程活动和研发模式开始
本文从统一工程交付的概念模型开始,介绍了如何将应用交付的模式显式地定义出来,并通过工具平台落地。
119991 57
|
11天前
|
监控 负载均衡 Java
深入探究Java微服务架构:Spring Cloud概论
**摘要:** 本文深入探讨了Java微服务架构中的Spring Cloud,解释了微服务架构如何解决传统单体架构的局限性,如松耦合、独立部署、可伸缩性和容错性。Spring Cloud作为一个基于Spring Boot的开源框架,提供了服务注册与发现、负载均衡、断路器、配置中心、API网关等组件,简化了微服务的开发、部署和管理。文章详细介绍了Spring Cloud的核心模块,如Eureka、Ribbon、Hystrix、Config、Zuul和Sleuth,并通过一个电商微服务系统的实战案例展示了如何使用Spring Cloud构建微服务应用。
103503 8
|
12天前
|
人工智能 Serverless 对象存储
让你的文档从静态展示到一键部署可操作验证
通过函数计算的能力让阿里云的文档从静态展示升级为动态可操作验证,用户在文档中单击一键部署可快速完成代码的部署及测试。这一改变已在函数计算的活动沙龙中得到用户的认可。
120862 228
|
12天前
|
SQL 存储 数据可视化
Ganos H3地理网格能力解析与最佳实践
本文介绍了Ganos H3的相关功能,帮助读者快速了解Ganos地理网格的重要特性与应用实践。H3是Uber研发的一种覆盖全球表面的二维地理网格,采用了一种全球统一的、多层次的六边形网格体系来表示地球表面,这种地理网格技术在诸多业务场景中得到广泛应用。Ganos不仅提供了H3网格的全套功能,还支持与其它Ganos时空数据类型进行跨模联合分析,极大程度提升了客户对于时空数据的挖掘分析能力。
|
11天前
|
存储 缓存 安全
深度解析JVM世界:JVM内存结构
深度解析JVM世界:JVM内存结构
|
18天前
|
人工智能 编解码 对象存储
一键生成视频!用 PAI-EAS 部署 AI 视频生成模型 SVD 工作流
本教程将带领大家免费领取阿里云PAI-EAS的免费试用资源,并且带领大家在 ComfyUI 环境下使用 SVD的模型,根据任何图片生成一个小短视频。