Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define Pressable Button colors via XIB/Storyboards #7

Open
gearoidoceallaigh opened this issue Nov 19, 2016 · 2 comments
Open

Define Pressable Button colors via XIB/Storyboards #7

gearoidoceallaigh opened this issue Nov 19, 2016 · 2 comments

Comments

@gearoidoceallaigh
Copy link

I'm able to change the colours on a FlatButton but not a PressableButton via Storyboards.

Is there a way to do this without dropping into the code?

Great library, thanks :)

@ldiqual ldiqual changed the title Is there a way to change Pressable Button colours via XIB/Storyboards? Define Pressable Button colors via XIB/Storyboards Nov 22, 2016
@ldiqual
Copy link
Contributor

ldiqual commented Nov 22, 2016

@gearoidoceallaigh Thanks for opening an issue! At the moment there is no way to do this. My thinking when using ColorSet was that the button + shadow colors should only be defined together. Having two separate properties increases the risk of forgetting to set one after setting another. For instance:

button.colors = .init(button: .cyan, shadow: .blue)
button.disabledColors = .init(button: .grey, shadow: .black)

as opposed to

button.buttonColor = .cyan
button.shadowColor = .blue
button.disabledButtonColor = .grey
button.disabledShadowColor = .black

where you could forget to set any of these.

The drawback, as you mentioned, is that ColorSet cannot be defined from the storyboard. I'll think a bit more about this to see if I can find an acceptable workaround. In the meantime, if someone is interested in this feature, please upvote the original post. Thank you!

@aal89
Copy link

aal89 commented Dec 17, 2017

I too ran into this problem and 'fixed' it like this:

Swift 4 ahead. I hope this is helpful for someone. After you copy paste this into your project, you now also have a buttonColor inspectable in your IB for PressableButton. I might open a PR with a proper implementation, if there's enough interest.

extension PressableButton {
    
    @IBInspectable
    var buttonColor: UIColor {
        get {
            // The ColorSet has it's properties set to internal. So the get() is
            // improperly implemented, we cannot get the current value (yet?).
            // As a result this is a hack in which we retrieve the pixel color
            // of the background UIImage.
            
            // We use the cornerRadius as an offset else we might read an
            // unintended pixel.
            let imageTopPoint = CGPoint(x: self.cornerRadius, y: self.cornerRadius)
            return self.currentBackgroundImage?.getPixelColor(pos: imageTopPoint) ?? UIColor.black
        }
        set {
            self.colors = ColorSet(button: newValue, shadow: newValue.darker(by: 15.0) ?? newValue)
        }
    }
    
}

extension UIImage {
    
    func getPixelColor(pos: CGPoint) -> UIColor {
        
        let pixelData = self.cgImage!.dataProvider!.data
        let data: UnsafePointer<UInt8> = CFDataGetBytePtr(pixelData)
        
        let pixelInfo: Int = ((Int(self.size.width) * Int(pos.y)) + Int(pos.x)) * 4
        
        let r = CGFloat(data[pixelInfo]) / CGFloat(255.0)
        let g = CGFloat(data[pixelInfo+1]) / CGFloat(255.0)
        let b = CGFloat(data[pixelInfo+2]) / CGFloat(255.0)
        let a = CGFloat(data[pixelInfo+3]) / CGFloat(255.0)
        
        return UIColor(red: r, green: g, blue: b, alpha: a)
    }
    
}

extension UIColor {
    
    func lighter(by percentage: CGFloat = 30.0) -> UIColor? {
        return self.adjust(by: abs(percentage))
    }
    
    func darker(by percentage: CGFloat = 30.0) -> UIColor? {
        return self.adjust(by: -1 * abs(percentage))
    }
    
    func adjust(by percentage: CGFloat = 30.0) -> UIColor? {
        var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0;
        if(self.getRed(&r, green: &g, blue: &b, alpha: &a)) {
            return UIColor(red: min(r + percentage / 100, 1.0),
                           green: min(g + percentage / 100, 1.0),
                           blue: min(b + percentage / 100, 1.0),
                           alpha: a)
        } else {
            return nil
        }
    }
    
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants