2016-02-13 85 views
2

我要反转的按钮,看起来像下面的背后:获取颜色的对象

button to be inverted

反相,在这种情况下,就意味着使标题蓝色和按钮的背景为白色。由于我不想对其进行硬编码,因此我不能简单地将其设置为蓝色。当我设置背景色为白色,标题的颜色clearColor,当然,标题是无法读取了:

button inverted incorrectly

有没有办法找出颜色,是后面的按钮(这是当前视图的背景图像),所以我可以将标题的颜色设置为该颜色?
感谢提前:)

回答

0

如果您UIButton坐落在一个UIView,你要访问的UIView's的backgroundColor,你可以这样做我引用UIButton's超。

例子:

@IBOutlet weak var myButton: UIButton! 

override func viewDidLoad() { 
    super.viewDidLoad() 

    myButton.backgroundColor = myButton.superview?.backgroundColor 
} 

如果你想使用一个背景图像的颜色,你可能想看看进入CoreImage来获取图像的平均或perPixel颜色。

+0

不幸的是它不是那么简单,因为背景图像不只是一个颜色。按钮后面的颜色取决于它的位置。我会检查图书馆,感谢您的建议 – LinusGeffarth

2

您需要创建的UIButton的子类(或只是UIControl),并覆盖-drawRect:做撕心裂肺瓦特/自定义的混合模式(kCGBlendModeDestinationOut):

- (void)drawRect:(CGRect)rect 
{ 
    [[UIColor whiteColor] setFill]; // white background of the button 
    UIBezierPath * path = [UIBezierPath bezierPathWithRoundedRect:self.bounds cornerRadius:5.f]; 
    [path fill]; 

    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextSaveGState(context); 
    CGContextSetBlendMode(context, kCGBlendModeDestinationOut); // Set blend mode 

    // u'd better to cache this attributes if u need to redraw the button frequently. 
    NSMutableParagraphStyle * paragraphStyle = [NSMutableParagraphStyle new]; 
    paragraphStyle.alignment = NSTextAlignmentCenter; 
    NSDictionary * attributes = @{NSFontAttributeName:[UIFont systemFontOfSize:20.f], NSParagraphStyleAttributeName:paragraphStyle}; 
    [@"Let's Go" drawAtPoint:CGPointMake(0.f, 0.f) withAttributes:attributes]; 
    CGContextRestoreGState(context); 
} 

kCGBlendModeDestinationOut是你所需要的混合模式设置,这将只显示当前视图下方的视图(R = D *(1 - Sa)),在您的情况下是背景图像。

而关于混合模式:

... R,S,和d分别是 预乘结果,源和目标颜色用α; Ra, Sa和Da是这些颜色的alpha分量。

波特 - 达夫 “源之上” 模式被称为`kCGBlendModeNormal': R = S + d *(1 - 萨)

注意,波特 - 达夫 “XOR” 模式仅titularly有关 经典位图XOR操作(其不受 CoreGraphics的支持)。

+1

对不起,只是注意到你的swift标记,我想你可以很容易地将其转换为swift版本,对不对? ;) – Kjuly

+2

今天早上我没有更好的事情做,所以[我做了一个快速的Swift端口](http://stackoverflow.com/a/35379187/2976878)。 – Hamish

+0

@ originaluser2不错,thx :) – Kjuly

3

Kjuly's answer继,你应该创建一个子类UIButton做到这一点。

为了应用您的不同样式,您只需为按钮触摸事件添加一些动作侦听器,以便在状态更改时重新绘制按钮。

正如Kjuly所说,您将要覆盖drawRect以执行自定义按钮绘制,具体取决于按钮是否被按下。

这样的事情应该能够实现你的目标。

class CustomButton: UIButton { 

    private let paragraphStyle = NSMutableParagraphStyle() 
    private var titleAttributes = [String:AnyObject]() 
    private var isPressed = false 

    var highlightColor = UIColor.whiteColor() { // stroke & highlight color of the button 
     didSet { 
      setNeedsDisplay() 
     } 
    } 
    var cornerRadius:CGFloat = 10.0 { // corner radius of button 
     didSet { 
      setNeedsDisplay() 
     } 
    } 
    var strokeWidth:CGFloat = 5.0 { // stroke width of button 
     didSet { 
      setNeedsDisplay() 
     } 
    } 
    override init(frame: CGRect) { 
     super.init(frame: frame) 

     addTarget(self, action: Selector("buttonWasPressed"), forControlEvents: .TouchDown) 
     addTarget(self, action: Selector("buttonWasReleased"), forControlEvents: .TouchUpInside) 
     addTarget(self, action: Selector("buttonWasReleased"), forControlEvents: .TouchDragExit) 
     addTarget(self, action: Selector("buttonWasReleased"), forControlEvents: .TouchCancel) 
    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
    } 

    func buttonWasPressed() { 
     isPressed = true 
     setNeedsDisplay() // set button to be redrawn 
    } 

    func buttonWasReleased() { 
     isPressed = false 
     setNeedsDisplay() // set button to be redrawn 
    } 

    override func drawRect(rect: CGRect) { 

     let size = bounds.size 
     let context = UIGraphicsGetCurrentContext() 

     if isPressed { // button pressed down 

      let path = UIBezierPath(roundedRect: bounds, cornerRadius: cornerRadius) // path of button shape for filling 

      CGContextSetFillColorWithColor(context, highlightColor.CGColor) // white background of the button 
      path.fill() // fill path 

      CGContextSetBlendMode(context, .DestinationOut) // set blend mode for transparent label 

     } else { // button not pressed 

      let path = UIBezierPath(roundedRect: UIEdgeInsetsInsetRect(bounds, UIEdgeInsets(top: strokeWidth*0.5, left: strokeWidth*0.5, bottom: strokeWidth*0.5, right: strokeWidth*0.5)), cornerRadius: cornerRadius-strokeWidth*0.5) // path of button shape for stroking 

      CGContextSetStrokeColorWithColor(context, highlightColor.CGColor) // set stroke color 
      path.lineWidth = strokeWidth 
      path.stroke() 
     } 

     guard let label = titleLabel else {return} // title label 
     guard let text = label.text else {return} // text to draw 

     // update text attributes, add any extra attributes you want transferred here. 
     paragraphStyle.alignment = label.textAlignment 
     titleAttributes[NSFontAttributeName] = label.font 
     titleAttributes[NSParagraphStyleAttributeName] = paragraphStyle 
     titleAttributes[NSForegroundColorAttributeName] = label.textColor 

     let textHeight = text.sizeWithAttributes(titleAttributes).height // heigh of the text to render, with the attributes 
     let renderRect = CGRect(x:0, y:(size.height-textHeight)*0.5, width:size.width, height:size.height) // rect to draw the text in 

     text.drawInRect(renderRect, withAttributes: titleAttributes) // draw text 
    } 
} 

然后,您可以在按键的设置titleLabel的各种属性,以及在strokeWidthcornerRadius财产使用此按钮。例如:

let button = CustomButton(frame: CGRect(x: 50, y: 50, width: 200, height: 75)) 

button.titleLabel?.text = "Let's go!" 
button.titleLabel?.font = UIFont.systemFontOfSize(30) 
button.titleLabel?.textAlignment = .Center 
button.titleLabel?.textColor = UIColor.whiteColor() 

button.cornerRadius = 15.0 
button.strokeWidth = 5.0 
view.addSubview(button) 

enter image description here