i need to make my custom buttom which is made in cg to be darker when user pressed it, just like original uibutton highlighted state. I came up with making alpha 50% but then background view is visible and i don't want that. Here is my code for that:
func unhighlightButton(){
self.color = someColor
self.setNeedsDisplay()
}
override var isHighlighted: Bool {
didSet{
if isHighlighted == true{
self.gradientColor = someColor.withAlphaComponent(0.5)
self.setNeedsDisplay()
self.perform(#selector(unhighlightButton), with: nil, afterDelay: 0.1)
}
}
}
Related
How do I change the button background color when the button is highlighted with swift,then I also want to know . How can I make this background color last for a period of time instead of clicking it to disappear immediately? For example, I want it to disappear 2 seconds after clicking. I checked some information and couldn't find a way. All I can think of is to write a click event, then change the background color of the button and set a time to change it back
I found the method. As a novice, I can't fully understand it, but it can be used. Friends with similar problems can refer to it
class MyButton : UIButton {
#IBInspectable var normalBackgroundColor: UIColor? {
didSet {
backgroundColor = normalBackgroundColor
}
}
#IBInspectable var highlightedBackgroundColor: UIColor?
override var isHighlighted: Bool {
didSet {
if oldValue == false && isHighlighted {
highlight()
} else if oldValue == true && !isHighlighted {
unHighlight()
}
}
}
func highlight() {
animateBackground(to: highlightedBackgroundColor, duration: highlightDuration)
}
func unHighlight() {
animateBackground(to: normalBackgroundColor, duration: highlightDuration)
}
var highlightDuration: TimeInterval = 1
private func animateBackground(to color: UIColor?, duration: TimeInterval) {
guard let color = color else { return }
UIView.animate(withDuration: highlightDuration) {
self.backgroundColor = color
}
} }
You can create a new file and write the above code
Then bind the button class as shown in the figure
Finally, your button has the content you want in the right property panel
You can modify the animation time by changing the value of highlightduration
Preamble (page down after code for the actual problem):
I have a custom UIButton class in which I replaced the ordinary UIButton isHighlighted animation behavior with this behavior:
When the user's finger is actually on the button (ie. highlighting the button), a stroked outline (square border) will appear around the button. When they are no longer touching the button, the outline disappears.
Also, I have replaced the normal isSelected behavior (background goes blue) with this:
An outline identical to the one used with isHighlighted is drawn, except it is slightly thicker and always there as long as isSelected = true, and it is not there when isSelected = false.
This works, and this is how I did it:
import UIKit
class CustomButton: UIButton {
// BUTTON TYPES:
// Gorsh, enums sure would be swell here. :T
// 1 : plus
// 2 : minus
// 3 : etc etc....
#IBInspectable
var thisButtonsType: Int = 1 { didSet { setNeedsDisplay() } }
#IBInspectable
var fillColor: UIColor = .black { didSet { setNeedsDisplay() } }
#IBInspectable
var strokeColor: UIColor = .black { didSet { setNeedsDisplay() } }
override var isHighlighted: Bool {
didSet {
setNeedsDisplay()
}
}
override func draw(_ rect: CGRect) {
let unitOfMeasure = bounds.width / 5
// draw outline in case we are selected / highlighted
if (isSelected || isHighlighted) {
let tempPath = BezierPathFactory.outline(totalWidth: bounds.width)
if (isSelected) {tempPath.lineWidth = 4.0}
strokeColor.setStroke()
tempPath.stroke()
}
// initialize path object
var path = UIBezierPath()
// get the path corresponding to our button type
switch thisButtonsType {
case 1:
path = BezierPathFactory.plus(gridSpacing: unitOfMeasure)
case 2:
path = BezierPathFactory.minus(gridSpacing: unitOfMeasure)
default: print("hewo!")
}
fillColor.setFill()
path.fill()
}
}
Once again, that code works but ...
What I would really like is if that isHighlighted border outline would gradually fade away after the touch finishes.
Note: In case you're wondering why I would do things this way... I plan to implement lots of different button types... all with different icons "printed" on them... but I want them all to follow these basic behaviors. Only a couple of them are "toggle" buttons that ever become selected, so there IS a use for the highlight fade.
I already know how to do animations... but it's just doing my head in trying to think how to do that in this context.
I wish I could get the UIButton source code.
Is there a way that the fade animation could be added relatively simply to my above code without completely changing the design pattern? Am I going to have to start using some other feature of core graphics like layers?
Thanks!
You might do the following:
Create a subclass of UIButton which adds and manages a sublayer of class CAShapeLayer for the outline the button.
Draw the outline the outline into the shape layer.
Ensure that the layer resizes with the view: Overwrite layoutSubviews of your view such that it updates the frame of the layer and updates the path for the outline.
You should observe or overwrite the state property of UIControl (which is an ancestor of UIButton) to notice the state changes.
Use property animations (CABasicAnimation) for the opacity of the shape layer to fade the outline in and out.
I'm using this extension of UIButton witch ignore taps on transparent color of buttons
open override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
if (!self.bounds.contains(point)) {
return nil
}
else {
let color : UIColor = self.getColourFromPoint(point: point)
let alpha = color.cgColor.alpha;
if alpha <= 0.0 {
debugPrint("no tocado")
return nil
}
return self
}
}
When i call UIImagePickerController the buttons has only text with transparent background, making hard to hit them...
There is some way to detect the context of the Buttons to avoid this extension in UIImagePickerController?
or put some background in the buttons of UIImagePickerController them without a custom picker?
Thanks!
You could do this at the start of your hitTest function:
if self.isKind(of: UIImagePickerController.self){
return nil
}
I am trying to make a UIView flash a certain color until a stop button is pressed.
Any help in doing so would be greatly appreciated.
Take a look at the animation methods of UIView. Specifically look at methods like animateWithDuration:animations: and variants. The variants with options are what you want. There are options to repeat and/or auto-reverse the animation.
EDIT:
Actually, if you want the color to flash rather than cross-fade between colors then using a UIView animation might not be the best choice. That's going to cause smooth transitions between colors.
If you want the color to flash from one color to the next you might be better off using a timer and simply setting the background color.
I created a simple custom subclass of UIView that has a variable animateColor. Set it to true and it creates a timer that cycles through an array of background colors. Use 2 colors if you want it to cycle back and forth between colors. Use more if desired.
public class LiveView: UIView {
//Adjust this interval value if desired to get a different flash interval.
//Note that changing the interval will have no effect while the timer is running.
public var interval = 0.5
//Change the array of colors if you want different colors
public var backgroundColors = [UIColor.gray, UIColor.green, UIColor.blue, UIColor.red]
var colorIndex = 0
//Set this flag to true to animate between the colors. Set it to false to stop the animation.
public var animateColor: Bool = false {
didSet {
if animateColor {
colorTimer = Timer.scheduledTimer(withTimeInterval: interval, repeats: true, block: {
timer in
self.colorIndex = (self.colorIndex + 1) % self.backgroundColors.count
self.setColor()
})
} else {
colorTimer?.invalidate()
}
}
}
private weak var colorTimer: Timer?
func setColor() {
backgroundColor = backgroundColors[colorIndex]
}
public required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setColor()
}
public override init(frame: CGRect) {
super.init(frame: frame)
setColor()
}
}
The following code gotten from this post supposedly changes a button's color when it is pressed.
override var highlighted: Bool {
didSet {
if highlighted {
backgroundColor = UIColor.lightGrayColor()
} else {
backgroundColor = UIColor.whiteColor()
}
}
}
However, I was wondering what the variable "highlighted" would corrospond too?
If I programatically added a button to my view like this:
let exampleButton = UIButton()
self.view.addSubview(exampleButton)
//Set constraints,title-text,etc...
How would I get this to work with exampleButton?