2016-04-23 79 views
4

我目前工作的一个欢迎页面上,我碰到这个有趣的设计来:如何设置按钮的透明文字样式?

credit to Julian Bialowan for the design: https://dribbble.com/shots/1807682-Everest-Welcome

我试图让在文本底部的按钮,通过它背后的半透明,去。我尝试了下面的代码,但它似乎并没有工作:

let transparent = UIColor(red: 0, green: 0, blue: 0, alpha: 0) 
let semiwhite = UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: 0.15)   
bottomView.backgroundColor = semiwhite 
loginButton.backgroundColor = semiwhite 
loginButton.setTitleColor(transparent, forState: .Normal) 
loginButton.layer.cornerRadius = 10 
loginButton.layer.masksToBounds = true 
loginButton.layer.borderWidth = 2.5 
loginButton.layer.borderColor = transparent.CGColor 

有没有人知道如何做到这一点?

+2

这将有助于看到你的代码实际上产生的视觉效果。 –

回答

15

我建议你不要“透明”文本。相反,您可能希望将此视为带有作为文本轮廓的“遮罩”的白色视图,从而可以显示下方的图像。这很复杂,因为面具实际上是从我们通常掩盖图像的方式反转而来的(例如,“用Facebook登录”文本不是面具,而是它周围的空白区域)。但Core Graphics提供了很容易做到这一点的方法。

所以,虽然它可能是最简单的在你最喜欢的图像编辑工具来创建这个图形,如果你想以编程方式做到这一点,你可以不喜欢下面的斯威夫特卡伦特3或更高版本:

override func viewDidLayoutSubviews() { 
    super.viewDidLayoutSubviews() 

    let image1 = maskedImage(size: button1.bounds.size, text: "Sign in with Facebook") 
    button1.setImage(image1, for: .normal) 

    let image2 = maskedImage(size: button2.bounds.size, text: "Sign-up with Email") 
    button2.setImage(image2, for: .normal) 
} 

func maskedImage(size: CGSize, text: String) -> UIImage? { 
    UIGraphicsBeginImageContextWithOptions(size, true, 0) 

    let context = UIGraphicsGetCurrentContext() 
    context?.scaleBy(x: 1, y: -1) 
    context?.translateBy(x: 0, y: -size.height) 

    // draw rounded rectange inset of the button's entire dimensions 

    UIColor.white.setStroke() 
    let pathRect = CGRect(origin: .zero, size: size).insetBy(dx: 10, dy: 10) 
    let path = UIBezierPath(roundedRect: pathRect, cornerRadius: 5) 
    path.lineWidth = 4 
    path.stroke() 

    // draw the text 

    let attributes: [NSAttributedStringKey: Any] = [ 
     .font: UIFont.preferredFont(forTextStyle: .caption1), 
     .foregroundColor: UIColor.white 
    ] 
    let textSize = text.size(withAttributes: attributes) 
    let point = CGPoint(x: (size.width - textSize.width)/2, y: (size.height - textSize.height)/2) 
    text.draw(at: point, withAttributes: attributes) 

    // capture the image and end context 

    let maskImage = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 

    // create image mask 

    guard let cgimage = maskImage?.cgImage, let dataProvider = cgimage.dataProvider else { return nil } 

    let bytesPerRow = cgimage.bytesPerRow 
    let bitsPerPixel = cgimage.bitsPerPixel 
    let width = cgimage.width 
    let height = cgimage.height 
    let bitsPerComponent = cgimage.bitsPerComponent 

    guard let mask = CGImage(maskWidth: width, height: height, bitsPerComponent: bitsPerComponent, bitsPerPixel: bitsPerPixel, bytesPerRow: bytesPerRow, provider: dataProvider, decode: nil, shouldInterpolate: false) else { return nil } 

    // create the actual image 

    let rect = CGRect(origin: .zero, size: size) 
    UIGraphicsBeginImageContextWithOptions(size, false, 0) 
    UIGraphicsGetCurrentContext()?.clip(to: rect, mask: mask) 
    UIColor.white.withAlphaComponent(0.9).setFill() 
    UIBezierPath(rect: rect).fill() 
    let image = UIGraphicsGetImageFromCurrentImageContext() 
    UIGraphicsEndImageContext() 

    // return image 

    return image 
} 

enter image description here

这里要注意的技巧是使用CGImage(maskWidth:...),它可以让我们创建一个图像遮罩除了我们绘制的白色文本和边框之外的所有东西。然后,当我们创建最终图像时,我们可以使用clip(to:mask:)将其剪辑到此“图像蒙版”。通常,当我们谈论掩蔽图像时,我们用UIBezierRect或其他图像(其中一个非零的alpha通道揭示了应掩盖的内容以及不应该掩盖的内容)掩盖它们。但在这里我们使用了一个核心图形“图像蒙版”来掩盖,这给了我们更多的控制权。有关图像蒙版蒙版与图像蒙版之间差异的讨论,请参阅“石英2D编程指南”的Masking Images一章。

对于Swift 2再现,请参见previous revision of this answer

+0

非常有用的代码,很容易清除我所有的疑惑。非常感谢 !!但有一个问题,文本部分是透明的,但背景是蓝色而不是白色和alpha分量。我错过了什么? –

+0

@SushreeSwagatika - 如果您在标签栏等中使用此图像,则会忽略颜色通道,并使用适当的色调。但是如果你在一个标准的'UIImageView'或'UIButton'中使用它,你应该看到你调用'fill()'时使用的任何颜色。 – Rob

2

我会设计Adobe Fireworks这样的按钮,让文本透明,然后将其保存为GIF。 然后,您可以将其设置为您的按钮的背景。

+1

您也可以使用PNG格式,它也支持传输。关键是你只是不想使用JPG。 – Rob

0

首先你可以设置tintcolor作为你想要的颜色。

并且如果您将alpha设置为0那么这意味着视图被隐藏。所以不要给0加alpha。

你有类似的选项,你可以使用clear color。所以会显示背景颜色。

第二件事,如果你想使用颜色,然后采取白色与阿尔法0.5或其他颜色与阿尔法0.5或0.2同样不采取确切的0.它会使视图看不见。

这是最基本的部分。现在在你的情况下,你可以做这样的事情,

例如,你的按钮大小是30 x 100比你应该把uiview作为背景更大的那个按钮的大小,并设置清晰的颜色作为背景颜色,并在该视图上添加按钮所以如果您将清晰的颜色作为色调或边框,边框颜色或文本颜色将自动设置为明智。

另一个简单的选择是,您可以拍摄与需求完全匹配的图像,并采用imageview并设置背景以清除颜色和图像作为图像,并在该图像上添加按钮,因为文字覆盖图像本身

希望这会帮助:)