「透過的な」テキストを望まないとお勧めします。代わりに、これをテキストの輪郭である「マスク」で白い視点と考えることができ、その下の画像を表示することができます。これは、マスクが実際に画像をマスクする方法(たとえば、「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
などの画像(非ゼロのアルファチャンネルでは、何を隠すべきか、そうでないことを明らかにします)でマスキングします。しかしここでは、Core Graphicsの「イメージマスク」を使用してマスクしています。画像マスクによるマスキングと画像によるマスキングの違いについては、Quartz 2D Programming GuideのMasking Imagesの章を参照してください。
スウィフト2のレンディションについては、previous revision of this answerを参照してください。
出典
2016-04-23 17:12:12
Rob
実際にコードが視覚的にどのように生成されているかを確認すると便利です。 –