Ios 透明按钮标题

Ios 透明按钮标题,ios,swift,uibutton,calayer,Ios,Swift,Uibutton,Calayer,如何从按钮背景中减去标题文本的形状 我创建了一个自定义UIButton类。当前,添加边框和文本颜色的代码如下所示 layer.borderWidth = 2.0 layer.borderColor = buttonColor.CGColor layer.cornerRadius = (CGFloat(bounds.height) + paddingVertical * 2.0) / 2.0 setTitleColor(buttonColor, forState: UIControlState.

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

我创建了一个自定义UIButton类。当前,添加边框和文本颜色的代码如下所示

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

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

我已经为您编写了一些代码,我的UIButton子类称为AKStencilButton(可在github上获得):

#导入“AKStencilButton.h”
#进口
@界面AKStencilButton()
{
UIColor*\u按钮颜色;
}
@结束
@按钮的实现
-(id)initWithCoder:(NSCoder*)aDecoder
{
if(self=[super initWithCoder:aDecoder]){
[自我设置默认值];
}
回归自我;
}
-(instancetype)initWithFrame:(CGRect)frame
{
if(self=[super initWithFrame:frame]){
[自我设置默认值];
}
回归自我;
}
-(无效)设置默认值
{
self.backgroundColor=[UIColor redColor];
self.layer.cornerRadius=4;
self.clipstobunds=是;
}
-(无效)布局子视图
{
[超级布局子视图];
[自我更新面具];
}
-(void)setTitleColor:(UIColor*)状态的颜色:(UIControlState)状态
{
[super setTitleColor:[UIColor clearColor]用于状态:状态];
}
-(无效)刷新掩码
{
self.titleLabel.backgroundColor=[UIColor clearColor];
[self-setTitleColor:[UIColor clearColor]用于状态:UIControlStateNormal];
NSString*text=self.titleLabel.text;
CGSize buttonSize=self.bounds.size;
UIFont*font=self.titleLabel.font;
NSDictionary*attribs=@{NSFontAttributeName:self.titleLabel.font};
CGSize textSize=[文本大小属性:属性];
UIGraphicsBeginImageContextWithOptions(按钮大小,否,[[UIScreen Main Screen]比例]);
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);
[文本绘图点:带属性的中心:@{NSFontAttributeName:font}];
UIImage*viewImage=UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsSendImageContext();
CALayer*maskLayer=[CALayer层];
maskLayer.contents=(u_桥id)(viewImage.CGImage);
maskLayer.frame=self.bounds;
self.layer.mask=maskLayer;
}
@结束
看起来是这样的(对不起彩虹):


我已经为您编写了一些代码,我的UIButton子类称为AKStencilButton(可在github上获得):

#导入“AKStencilButton.h”
#进口
@界面AKStencilButton()
{
UIColor*\u按钮颜色;
}
@结束
@按钮的实现
-(id)initWithCoder:(NSCoder*)aDecoder
{
if(self=[super initWithCoder:aDecoder]){
[自我设置默认值];
}
回归自我;
}
-(instancetype)initWithFrame:(CGRect)frame
{
if(self=[super initWithFrame:frame]){
[自我设置默认值];
}
回归自我;
}
-(无效)设置默认值
{
self.backgroundColor=[UIColor redColor];
self.layer.cornerRadius=4;
self.clipstobunds=是;
}
-(无效)布局子视图
{
[超级布局子视图];
[自我更新面具];
}
-(void)setTitleColor:(UIColor*)状态的颜色:(UIControlState)状态
{
[super setTitleColor:[UIColor clearColor]用于状态:状态];
}
-(无效)刷新掩码
{
self.titleLabel.backgroundColor=[UIColor clearColor];
[self-setTitleColor:[UIColor clearColor]用于状态:UIControlStateNormal];
NSString*text=self.titleLabel.text;
CGSize buttonSize=self.bounds.size;
UIFont*font=self.titleLabel.font;
NSDictionary*attribs=@{NSFontAttributeName:self.titleLabel.font};
CGSize textSize=[文本大小属性:属性];
UIGraphicsBeginImageContextWithOptions(按钮大小,否,[[UIScreen Main Screen]比例]);
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);
[文本绘图点:带属性的中心:@{NSFontAttributeName:font}];
UIImage*viewImage=UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsSendImageContext();
CALayer*maskLayer=[CALayer层];
maskLayer.contents=(u_桥id)(viewImage.CGImage);
maskLayer.frame=self.bounds;
self.layer.mask=maskLayer;
}
@结束
看起来是这样的(对不起彩虹):


我在UIView中添加了以下方法来解决此问题:

-(void)maskSubviews:(NSArray*)subviews {
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0.0);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);
    CGContextFillRect(context, self.bounds);

    CGContextSetBlendMode(context, kCGBlendModeDestinationOut);
    for (UIView *view in subviews) {
        CGPoint origin = [view convertPoint:CGPointZero toView:self];
        CGContextTranslateCTM(context, origin.x, origin.y);
        [view.layer renderInContext:context];
        CGContextTranslateCTM(context, -origin.x, -origin.y);
    }
    UIImage* mask = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    self.maskView = [[UIImageView alloc] initWithImage:mask];
}
只需用你想要掩盖的视图来调用它。例如:

[button maskSubviews: @[button.titleLabel, button.imageView]]

我在UIView中添加了以下方法来解决此问题:

-(void)maskSubviews:(NSArray*)subviews {
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, 0.0);
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetFillColorWithColor(context, [UIColor blackColor].CGColor);
    CGContextFillRect(context, self.bounds);

    CGContextSetBlendMode(context, kCGBlendModeDestinationOut);
    for (UIView *view in subviews) {
        CGPoint origin = [view convertPoint:CGPointZero toView:self];
        CGContextTranslateCTM(context, origin.x, origin.y);
        [view.layer renderInContext:context];
        CGContextTranslateCTM(context, -origin.x, -origin.y);
    }
    UIImage* mask = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    self.maskView = [[UIImageView alloc] initWithImage:mask];
}
只需用你想要掩盖的视图来调用它。例如:

[button maskSubviews: @[button.titleLabel, button.imageView]]

我将@purrminator的解决方案转换为Swift 3,这只是主要的方法

func clearTextButton(button: UIButton, title: NSString, color: UIColor) {
    button.backgroundColor = color
    button.titleLabel?.backgroundColor = UIColor.clear()
    button.setTitleColor(UIColor.clear(), for: .normal)
    button.setTitle(title as String, for: [])
    let buttonSize: CGSize = button.bounds.size
    let font: UIFont = button.titleLabel!.font
    let attribs: [String : AnyObject] = [NSFontAttributeName: button.titleLabel!.font]
    let textSize: CGSize = title.size(attributes: attribs)
    UIGraphicsBeginImageContextWithOptions(buttonSize, false, UIScreen.main().scale)
    let ctx: CGContext = UIGraphicsGetCurrentContext()!
    ctx.setFillColor(UIColor.white().cgColor)
    let center: CGPoint = CGPoint(x: buttonSize.width / 2 - textSize.width / 2, y: buttonSize.height / 2 - textSize.height / 2)
    let path: UIBezierPath = UIBezierPath(rect: CGRect(x: 0, y: 0, width: buttonSize.width, height: buttonSize.height))
    ctx.addPath(path.cgPath)
    ctx.fillPath()
    ctx.setBlendMode(.destinationOut)
    title.draw(at: center, withAttributes: [NSFontAttributeName: font])
    let viewImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    let maskLayer: CALayer = CALayer()
    maskLayer.contents = ((viewImage.cgImage) as! AnyObject)
    maskLayer.frame = button.bounds
    button.layer.mask = maskLayer
}

我将@purrminator的解决方案转换为Swift 3,这只是主要的方法

func clearTextButton(button: UIButton, title: NSString, color: UIColor) {
    button.backgroundColor = color
    button.titleLabel?.backgroundColor = UIColor.clear()
    button.setTitleColor(UIColor.clear(), for: .normal)
    button.setTitle(title as String, for: [])
    let buttonSize: CGSize = button.bounds.size
    let font: UIFont = button.titleLabel!.font
    let attribs: [String : AnyObject] = [NSFontAttributeName: button.titleLabel!.font]
    let textSize: CGSize = title.size(attributes: attribs)
    UIGraphicsBeginImageContextWithOptions(buttonSize, false, UIScreen.main().scale)
    let ctx: CGContext = UIGraphicsGetCurrentContext()!
    ctx.setFillColor(UIColor.white().cgColor)
    let center: CGPoint = CGPoint(x: buttonSize.width / 2 - textSize.width / 2, y: buttonSize.height / 2 - textSize.height / 2)
    let path: UIBezierPath = UIBezierPath(rect: CGRect(x: 0, y: 0, width: buttonSize.width, height: buttonSize.height))
    ctx.addPath(path.cgPath)
    ctx.fillPath()
    ctx.setBlendMode(.destinationOut)
    title.draw(at: center, withAttributes: [NSFontAttributeName: font])
    let viewImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    let maskLayer: CALayer = CALayer()
    maskLayer.contents = ((viewImage.cgImage) as! AnyObject)
    maskLayer.frame = button.bounds
    button.layer.mask = maskLayer
}

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
                }
            }
        }
    }
}
用法:

button.clearColorForTitle()

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
                }
            }
        }
    }
}
用法:

button.clearColorForTitle()

这可以很容易地实现,如果你有这样的图像。我正在寻找一个编程解决方案这里的小变化可能会帮助你:创建一个渐变层与任何颜色你想要的,他们使它遮罩到你的文本标签,这应该做到。谢谢,但模糊的背景内容不断变化。所以不幸的是,一个静态的、不透明的标题(有或没有渐变)并不能解决这个问题。如果你有这样的图片,这是很容易做到的。我在看