我建議你不要「透明」文本。相反,您可能希望將此視爲帶有作爲文本輪廓的「遮罩」的白色視圖,從而可以顯示下方的圖像。這很複雜,因爲面具實際上是從我們通常掩蓋圖像的方式反轉而來的(例如,「用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
}
這裏要注意的技巧是使用CGImage(maskWidth:...)
,它可以讓我們創建一個圖像遮罩除了我們繪製的白色文本和邊框之外的所有東西。然後,當我們創建最終圖像時,我們可以使用clip(to:mask:)
將其剪輯到此「圖像蒙版」。通常,當我們談論掩蔽圖像時,我們用UIBezierRect
或其他圖像(其中一個非零的alpha通道揭示了應掩蓋的內容以及不應該掩蓋的內容)掩蓋它們。但在這裏我們使用了一個核心圖形「圖像蒙版」來掩蓋,這給了我們更多的控制權。有關圖像蒙版蒙版與圖像蒙版之間差異的討論,請參閱「石英2D編程指南」的Masking Images一章。
對於Swift 2再現,請參見previous revision of this answer。
來源
2016-04-23 17:12:12
Rob
這將有助於看到你的代碼實際上產生的視覺效果。 –