问题描述
我目前正在开设一个欢迎页面,我遇到了这个有趣的设计:
I am currently working on a welcome page and I came across this interesting design:
我正在尝试在底部创建一个文本,该文本通过半透明视图在它背后。我尝试了以下代码但它似乎没有工作:
I'm trying to make a button at the bottom with text that goes through the semi-transparent view behind it. I tried out the following code but it doesn't seem to be working:
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
有谁知道怎么做这个?
推荐答案
我建议您不要透明文字。相反,您可能希望将此视为带有蒙版的白色视图,该蒙版是文本的轮廓,允许显示下面的图像。这有点复杂,因为掩码实际上与我们通常掩盖图像的方式相反(例如,用Facebook登录文本不是掩模,而是围绕它的白色空间)。但Core Graphics提供了很容易实现这一目标的方法。
I'd suggest that you don't want "transparent" text. Instead, you may want to think of this as a white view with a "mask" which is the outline of the text, allowing the image underneath to be revealed. This is complicated a bit because the mask is actually inverted from how we generally mask images (e.g., the "Sign in with Facebook" text is not the mask, but rather the white space around it is). But Core Graphics offer ways to do this very easily.
因此,尽管在您最喜欢的图像编辑工具中创建此图形可能最简单,但如果您想以编程方式执行此操作,您可以在Swift 3或更高版本中执行以下操作:
So, while it's probably easiest to create this graphic in your favorite image editing tool, if you wanted to do it programmatically, you could do something like the following in Swift 3 or later:
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
}
这里要注意的技巧是使用,它可以让我们创建一个图像蒙版,除了我们绘制的白色文本和边框之外的所有内容。然后,当我们创建最终图像时,我们可以使用。
The technique to pay attention to here is the use of CGImage(maskWidth:...)
, which lets us create an image mask out everything except the white text and border that we drew. Then when we create the final image, we can clip it to this "image mask" with clip(to:mask:)
.
通常,当我们谈论屏蔽图像时,我们用 UIBezierRect
或其他图像(其中一个)掩盖它们非零alpha通道显示应该屏蔽的内容和不应该屏蔽的内容。但是在这里我们使用Core Graphics图像掩码进行掩蔽,这使我们能够获得更多控制权。有关使用图像蒙版进行遮罩和使用图像进行遮罩之间的差异的讨论,请参阅 Quartz 2D编程指南。
Generally, when we talk about masking images, we're masking them with UIBezierRect
or other images (where a non-zero alpha channel reveals what should be masked and what shouldn't). But here we're masking using an Core Graphics "image mask", which gives us more control. For a discussion on the differences between masking with an image mask and masking with an image, see the Masking Images chapter of the Quartz 2D Programming Guide.
对于Swift 2的再现,请参阅。
For Swift 2 rendition, see previous revision of this answer.
这篇关于如何设置按钮的样式以获得透明文本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!