如何在Swift中应用反向文本掩码?

问题描述 投票:0回答:2

我正在尝试以编程方式创建一个透明文本的图层。我尝试的一切似乎都不起作用。我的最终目标是在文本上创建内部阴影。

而不是像下面的代码中的圆圈,我想要文本。

let view = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
view.backgroundColor = .white

// MASK
let blackSquare = UIView(frame: CGRect(x: 100, y: 100, width: 200, height: 200))
blackSquare.backgroundColor = .black
view.addSubview(blackSquare)

let maskLayer = CAShapeLayer()

// Create a path with the rectangle in it.
let path = CGMutablePath()
path.addArc(center: CGPoint(x: 100, y: 100), radius: 50, startAngle: 0.0, endAngle: 2.0 * .pi, clockwise: false)
path.addRect(CGRect(x: 0, y: 0, width: blackSquare.frame.width, height: blackSquare.frame.height))
maskLayer.backgroundColor = UIColor.black.cgColor

maskLayer.path = path;
maskLayer.fillRule = kCAFillRuleEvenOdd

blackSquare.layer.mask = maskLayer

maskLayer.masksToBounds = false
maskLayer.shadowRadius = 4
maskLayer.shadowOpacity = 0.5
maskLayer.shadowOffset = CGSize(width: 5, height: 5)

view.addSubview(blackSquare)

我也可以使用文本作为掩码,但我无法反转掩码。任何帮助表示赞赏。

编辑:

根据罗什的答案,我根据乔希的建议弄清楚了。这是我的游乐场代码。

import Foundation
import UIKit
import PlaygroundSupport

// view
let view = UIView(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
view.backgroundColor = .black

// button
let button = UIButton(frame: CGRect(x: 0, y: 0, width: 500, height: 500))
button.setTitle("120", for: .normal)
button.setTitleColor(.white, for: .normal)
button.titleLabel?.font = UIFont(name: "AvenirNextCondensed-UltraLight", size: 200)

view.addSubview(button)

addInnerShadow(button: button)

func addInnerShadow(button: UIButton) {

// text
let text = button.titleLabel!.text!

// get context
UIGraphicsBeginImageContextWithOptions(button.bounds.size, true, 0)
let context = UIGraphicsGetCurrentContext()

context?.scaleBy(x: 1, y: -1)
context?.translateBy(x: 0, y: -button.bounds.size.height)

let font = button.titleLabel!.font!

// draw the text
let attributes = [
    NSAttributedStringKey.font: font,
    NSAttributedStringKey.foregroundColor: UIColor.white
]

let size = text.size(withAttributes: attributes)
let point = CGPoint(x: (button.bounds.size.width - size.width) / 2.0, y: (button.bounds.size.height - size.height) / 2.0)
text.draw(at: point, withAttributes: attributes)

// capture the image and end context
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

// create image mask
let cgimage = image?.cgImage!
let bytesPerRow = cgimage?.bytesPerRow
let dataProvider = cgimage?.dataProvider!
let bitsPerPixel = cgimage?.bitsPerPixel
let width = cgimage?.width
let height = cgimage?.height
let bitsPerComponent = cgimage?.bitsPerComponent
let mask = CGImage(maskWidth: width!, height: height!, bitsPerComponent: bitsPerComponent!, bitsPerPixel: bitsPerPixel!, bytesPerRow: bytesPerRow!, provider: dataProvider!, decode: nil, shouldInterpolate: false)

// create background
UIGraphicsBeginImageContextWithOptions(button.bounds.size, false, 0)
UIGraphicsGetCurrentContext()!.clip(to: button.bounds, mask: mask!)
view.backgroundColor!.setFill()
UIBezierPath(rect: button.bounds).fill()
let background = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()

let backgroundView = UIImageView(image: background)

// add shadows
backgroundView.layer.shadowOffset = CGSize(width: 2, height: 2)
backgroundView.layer.shadowRadius = 2
backgroundView.layer.shadowOpacity = 0.75

button.addSubview(backgroundView)

}

PlaygroundPage.current.liveView = view
swift core-graphics
2个回答
0
投票

虽然不完全相同,但请参阅Rob提供的答案,他回答了类似的问题:

如何设置按钮的样式以获得透明文本?

这应该让你至少开始......


0
投票

偶然发现了一个可能的solution,我已经更新为正确的语法:

func mask(withRect rect: CGRect, inverse: Bool = false) {
    let path = UIBezierPath(rect: rect)
    let maskLayer = CAShapeLayer()

    if inverse {
        path.append(UIBezierPath(rect: self.view.bounds))
        maskLayer.fillRule = kCAFillRuleEvenOdd
    }

    maskLayer.path = path.cgPath

    self.view.layer.mask = maskLayer
}

您显然需要选择零件以确定它是否适合您。

© www.soinside.com 2019 - 2024. All rights reserved.