2016-04-23 83 views
4

我目前工作的一個歡迎頁面上,我碰到這個有趣的設計來:如何設置按鈕的透明文字樣式?

credit to Julian Bialowan for the design: https://dribbble.com/shots/1807682-Everest-Welcome

我試圖讓在文本底部的按鈕,通過它背後的半透明,去。我嘗試了下面的代碼,但它似乎並沒有工作:

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 

有沒有人知道如何做到這一點?

+2

這將有助於看到你的代碼實際上產生的視覺效果。 –

回答

15

我建議你不要「透明」文本。相反,您可能希望將此視爲帶有作爲文本輪廓的「遮罩」的白色視圖,從而可以顯示下方的圖像。這很複雜,因爲面具實際上是從我們通常掩蓋圖像的方式反轉而來的(例如,「用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 
} 

enter image description here

這裏要注意的技巧是使用CGImage(maskWidth:...),它可以讓我們創建一個圖像遮罩除了我們繪製的白色文本和邊框之外的所有東西。然後,當我們創建最終圖像時,我們可以使用clip(to:mask:)將其剪輯到此「圖像蒙版」。通常,當我們談論掩蔽圖像時,我們用UIBezierRect或其他圖像(其中一個非零的alpha通道揭示了應掩蓋的內容以及不應該掩蓋的內容)掩蓋它們。但在這裏我們使用了一個核心圖形「圖像蒙版」來掩蓋,這給了我們更多的控制權。有關圖像蒙版蒙版與圖像蒙版之間差異的討論,請參閱「石英2D編程指南」的Masking Images一章。

對於Swift 2再現,請參見previous revision of this answer

+0

非常有用的代碼,很容易清除我所有的疑惑。非常感謝 !!但有一個問題,文本部分是透明的,但背景是藍色而不是白色和alpha分量。我錯過了什麼? –

+0

@SushreeSwagatika - 如果您在標籤欄等中使用此圖像,則會忽略顏色通道,並使用適當的色調。但是如果你在一個標準的'UIImageView'或'UIButton'中使用它,你應該看到你調用'fill()'時使用的任何顏色。 – Rob

2

我會設計Adobe Fireworks這樣的按鈕,讓文本透明,然後將其保存爲GIF。 然後,您可以將其設置爲您的按鈕的背景。

+1

您也可以使用PNG格式,它也支持傳輸。關鍵是你只是不想使用JPG。 – Rob

0

首先你可以設置tintcolor作爲你想要的顏色。

並且如果您將alpha設置爲0那麼這意味着視圖被隱藏。所以不要給0加alpha。

你有類似的選項,你可以使用clear color。所以會顯示背景顏色。

第二件事,如果你想使用顏色,然後採取白色與阿爾法0.5或其他顏色與阿爾法0.5或0.2同樣不採取確切的0.它會使視圖看不見。

這是最基本的部分。現在在你的情況下,你可以做這樣的事情,

例如,你的按鈕大小是30 x 100比你應該把uiview作爲背景更大的那個按鈕的大小,並設置清晰的顏色作爲背景顏色,並在該視圖上添加按鈕所以如果您將清晰的顏色作爲色調或邊框,邊框顏色或文本顏色將自動設置爲明智。

另一個簡單的選擇是,您可以拍攝與需求完全匹配的圖像,並採用imageview並設置背景以清除顏色和圖像作爲圖像,並在該圖像上添加按鈕,因爲文字覆蓋圖像本身

希望這會幫助:)