2017-07-26 9 views
14

私が本質的にやっているのは、テキストラベルにテキストの形の穴を「カット」させることです。私はself.mask = uiLabelを使ってみましたが、それらはテキストを正しく配置することを拒否しましたので、私はCore Graphicsを通してこれに近づいています。ここでCore Graphics CGImageマスクが影響を受けない

は(draw(_ rect: CGRect)に)動作していないコードです:

let context = (UIGraphicsGetCurrentContext())! 

    // Set mask background color 
    context.setFillColor(UIColor.black.cgColor) 
    context.fill(rect) 

    context.saveGState() 


    let paragraphStyle = NSMutableParagraphStyle() 
    paragraphStyle.alignment = .center 

    let attributes = [ 
     NSParagraphStyleAttributeName: paragraphStyle, 
     NSFontAttributeName: UIFont.systemFont(ofSize: 16, weight: UIFontWeightMedium), 
     NSForegroundColorAttributeName: UIColor.white 
    ] 

    let string = NSString(string: "LOGIN") 

    // This wouldn't vertically align so we calculate the string size and create a new rect in which it is vertically aligned 
    let size = string.size(attributes: attributes) 
    let position = CGRect(
     x: rect.origin.x, 
     y: rect.origin.y + (rect.size.height - size.height)/2, 
     width: rect.size.width, 
     height: size.height 
    ) 

    context.translateBy(x: 0, y: rect.size.height) 
    context.scaleBy(x: 1, y: -1) 
    string.draw(
     in: position, 
     withAttributes: attributes 
    ) 

    let mask = (context.makeImage())! 

    context.restoreGState() 

    // Redraw with created mask 
    context.clear(rect) 

    context.saveGState() 
    // !!!! Below line is the problem 
    context.clip(to: rect, mask: mask) 
    context.restoreGState() 

基本的に私は私が適用するマスクですCGImagemask変数)を作成するためのコードを正常に作成しました画像全体に

の代わりにcontext.draw(mask, in: rect)(マスクを表示する)とマークされた行が正しく表示されます。

enter image description hereとしてショー(正確に)マスク

しかし、私は(context.clip(to: rect, mask: mask)を使用して)このマスクを適用しようとしたら、何も起こりません! 実際の結果:

Desired result

が、何らかの理由でマスクが正しく適用されていない:

Nothing changing

望ましい結果です。


このコードは、私が何度も何度もドキュメントを読んだように動作するはずです。さらに別のCGContextでマスクを作成しようとしましたが、これはうまくいきませんでした。また、を使ってCGImage(mask)をCGColorSpaceCreateDeviceGray()に変換しようとしたときに、nilを返しました。私はこれを2日間行っていますので、どんな助けもあります。

+0

を私は一度、同様の問題がありました私の設定は若干異なります: 'UIControl' cそれに 'UILabel'サブビュー付きのサブクラスを作成します。 –

+0

私の場合、ラベルサブビューで 'setNeedsDisplay()'を呼び出す前に、それを修正しました。 –

答えて

1

ラベルを完全に半透明のテキストにしたい場合は、マスクの代わりにブレンドモードを使用できます。

public class KnockoutLabel: UILabel { 
    public override func draw(_ rect: CGRect) { 
     let context = UIGraphicsGetCurrentContext()! 
     context.setBlendMode(.clear) 

     self.drawText(in: rect) 
    } 
} 

しかしfalseからisOpaqueを設定してください。デフォルトでは、不透明な背景色を使用しているため、ビューは不透明であるとみなします。

+0

それは何であるか分かりませんが、これは 'UIVisualEffectView'でうまく動作していないようです。他のブレンドモードはありません – Downgoat

+0

@Downgoat正確に何を達成しようとしていますか? –

+0

問題と同じ問題ですが、ブレンドモードを設定するとボタンが変わらないように見えます。これはちょうどUIエフェクトであると考えられています – Downgoat

1

実際には以下のコードを楽しむことはできません。これは、PaintCodeを使用して作成されました。テキストは常に丸い四角形の中央になります。それがあなたを助けることを願っています。

コード、引き分けの内側(_ RECT:CGRect):それを置く

//// General Declarations 
    let context = UIGraphicsGetCurrentContext() 

    //// Color Declarations - just to make a gradient same as your button have 
    let gradientColor = UIColor(red: 0.220, green: 0.220, blue: 0.223, alpha: 1.000) 
    let gradientColor2 = UIColor(red: 0.718, green: 0.666, blue: 0.681, alpha: 1.000) 
    let gradientColor3 = UIColor(red: 0.401, green: 0.365, blue: 0.365, alpha: 1.000) 

    //// Gradient Declarations 
    let gradient = CGGradient(colorsSpace: nil, colors: [gradientColor.cgColor, gradientColor3.cgColor, gradientColor2.cgColor] as CFArray, locations: [0, 0.55, 1])! 


    //// Subframes 
    let group: CGRect = CGRect(x: rect.minX, y: rect.minY, width: rect.width, height: rect.height) 


    //// Group 
    context.saveGState() 
    context.beginTransparencyLayer(auxiliaryInfo: nil) 


    //// Rectangle Drawing 
    let rectanglePath = UIBezierPath(roundedRect: group, cornerRadius: 5) 
    context.saveGState() 
    rectanglePath.addClip() 
    let rectangleRotatedPath = UIBezierPath() 
    rectangleRotatedPath.append(rectanglePath) 
    var rectangleTransform = CGAffineTransform(rotationAngle: -99 * -CGFloat.pi/180) 
    rectangleRotatedPath.apply(rectangleTransform) 
    let rectangleBounds = rectangleRotatedPath.cgPath.boundingBoxOfPath 
    rectangleTransform = rectangleTransform.inverted() 
    context.drawLinearGradient(gradient, 
           start: CGPoint(x: rectangleBounds.minX, y: rectangleBounds.midY).applying(rectangleTransform), 
           end: CGPoint(x: rectangleBounds.maxX, y: rectangleBounds.midY).applying(rectangleTransform), 
           options: []) 
    context.restoreGState() 


    //// Text Drawing 
    context.saveGState() 
    context.setBlendMode(.destinationOut) 

    let textRect = group 
    let textTextContent = "LOGIN" 
    let textStyle = NSMutableParagraphStyle() 
    textStyle.alignment = .center 
    let textFontAttributes = [ 
     NSFontAttributeName: UIFont.systemFont(ofSize: 16, weight: UIFontWeightBold), 
     NSForegroundColorAttributeName: UIColor.black, 
     NSParagraphStyleAttributeName: textStyle, 
     ] 

    let textTextHeight: CGFloat = textTextContent.boundingRect(with: CGSize(width: textRect.width, height: CGFloat.infinity), options: .usesLineFragmentOrigin, attributes: textFontAttributes, context: nil).height 
    context.saveGState() 
    context.clip(to: textRect) 
    textTextContent.draw(in: CGRect(x: textRect.minX, y: textRect.minY + (textRect.height - textTextHeight)/2, width: textRect.width, height: textTextHeight), withAttributes: textFontAttributes) 
    context.restoreGState() 

    context.restoreGState() 


    context.endTransparencyLayer() 
    context.restoreGState() 

結果:

enter image description here

enter image description here

enter image description here

関連する問題