透明的UIButton标题

Ber*_*rnd 1 uibutton calayer ios swift

如何从按钮背景中减去标题文本的形状?

在此输入图像描述

我创建了一个自定义UIButton类.目前添加边框和文本颜色的代码看起来就像这样

layer.borderWidth = 2.0
layer.borderColor = buttonColor.CGColor
layer.cornerRadius = (CGFloat(bounds.height) + paddingVertical * 2.0) / 2.0
setTitleColor(buttonColor, forState: UIControlState.Normal)
Run Code Online (Sandbox Code Playgroud)

关于如何从背景中减去按钮标题形状的任何建议.我是否需要将所有这些渲染为图像或是否有更好的替代方案?

Cer*_*ise 8

swift 4 的扩展

extension UIButton{
func clearColorForTitle() {

    let buttonSize = bounds.size

    if let font = titleLabel?.font{
        let attribs = [NSAttributedStringKey.font: font]

        if let textSize = titleLabel?.text?.size(withAttributes: attribs){
            UIGraphicsBeginImageContextWithOptions(buttonSize, false, UIScreen.main.scale)

            if let ctx = UIGraphicsGetCurrentContext(){
                ctx.setFillColor(UIColor.white.cgColor)

                let center = CGPoint(x: buttonSize.width / 2 - textSize.width / 2, y: buttonSize.height / 2 - textSize.height / 2)
                let path = UIBezierPath(rect: CGRect(x: 0, y: 0, width: buttonSize.width, height: buttonSize.height))
                ctx.addPath(path.cgPath)
                ctx.fillPath()
                ctx.setBlendMode(.destinationOut)

                titleLabel?.text?.draw(at: center, withAttributes: [NSAttributedStringKey.font: font])

                if let viewImage = UIGraphicsGetImageFromCurrentImageContext(){
                    UIGraphicsEndImageContext()

                    let maskLayer = CALayer()
                    maskLayer.contents = ((viewImage.cgImage) as AnyObject)
                    maskLayer.frame = bounds

                    layer.mask = maskLayer
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

用法 :

button.clearColorForTitle()
Run Code Online (Sandbox Code Playgroud)


kas*_*kad 5

我为你编写了一些代码,我的UIButton子类叫做AKStencilButton(可在github上找到https://github.com/purrrminator/AKStencilButton):

#import "AKStencilButton.h"
#import <QuartzCore/QuartzCore.h>

@interface AKStencilButton ()
{
    UIColor * _buttonColor;
}
@end

@implementation AKStencilButton

-(id)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super initWithCoder:aDecoder]){
        [self setupDefaults];
    }
    return self;
}
-(instancetype)initWithFrame:(CGRect)frame
{
    if (self = [super initWithFrame:frame]){
        [self setupDefaults];
    }
    return self;
}
-(void)setupDefaults
{
    self.backgroundColor = [UIColor redColor];
    self.layer.cornerRadius = 4;
    self.clipsToBounds = YES;
}
-(void)layoutSubviews
{
    [super layoutSubviews];
    [self refreshMask];
}
-(void)setTitleColor:(UIColor *)color forState:(UIControlState)state
{
    [super setTitleColor:[UIColor clearColor] forState:state];
}
-(void)refreshMask
{
    self.titleLabel.backgroundColor = [UIColor clearColor];
    [self setTitleColor:[UIColor clearColor] forState:UIControlStateNormal];

    NSString * text = self.titleLabel.text;
    CGSize buttonSize = self.bounds.size;
    UIFont * font = self.titleLabel.font;

    NSDictionary* attribs = @{NSFontAttributeName: self.titleLabel.font};
    CGSize textSize = [text sizeWithAttributes:attribs];


    UIGraphicsBeginImageContextWithOptions(buttonSize, NO, [[UIScreen mainScreen] scale]);
    CGContextRef ctx = UIGraphicsGetCurrentContext();
    CGContextSetFillColorWithColor(ctx, [UIColor whiteColor].CGColor);
    CGPoint center = CGPointMake(buttonSize.width/2-textSize.width/2, buttonSize.height/2-textSize.height/2);

    UIBezierPath *path = [UIBezierPath bezierPathWithRect:CGRectMake(0, 0, buttonSize.width, buttonSize.height)];
    CGContextAddPath(ctx, path.CGPath);
    CGContextFillPath(ctx);
    CGContextSetBlendMode(ctx, kCGBlendModeDestinationOut);

    [text drawAtPoint:center withAttributes:@{NSFontAttributeName:font}];
    UIImage* viewImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    CALayer *maskLayer = [CALayer layer];
    maskLayer.contents = (__bridge id)(viewImage.CGImage);
    maskLayer.frame = self.bounds;
    self.layer.mask = maskLayer;
}
@end
Run Code Online (Sandbox Code Playgroud)

它看起来像这样(对不起彩虹):

在此输入图像描述