How to make programmatically generated UIButton do default animation on press? - ios

I am attempting to program in swift without storyboards/interface builder. When I press a UIButton, it does not change color like it would had I created it on the storyboard file. How can I enable this visual feature?
Here is (roughly) my code:
import UIKit
class MyView: UIView {
var myButton: UIButton
init(buttonTitle: String) {
myButton = UIButton()
myButton.translateAutoresizingMaskIntoConstraints = false
myButton.setTitle(buttonTitle, forState: .Normal)
myButton.setTitleColor(.blueColor(), forState: .Normal)
super.init(frame: CGRect())
addSubview(myButton)
var layoutConstraints = [NSLayoutConstraints]()
//... autolayout ...
NSLayoutConstraint.activateConstraints(layoutConstraints)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Thanks in advance.

please refer the below link, its from objective c. You can find some concept from here,
How to change the background color of a UIButton while it's highlighted?
They have already answered . Got it friend!

Related

keep the original color of the UIButton's icon when it's tapped in Swift

I'm working on making a custom UIButton in Swift and have a question for initializing the UIButton with type custom.
This is the image of the current custom button in my project, and when the user taps a button, the image icon, whose the original color is .whilte, grays out. However, I want to keed the image color to white even when the user taps the button and the button state changes. I think I should initialize the button with type custom, but I get the message like, Must call a designated initializer of the superclass 'UIButton', when I try initializing with init(type: UIButton.ButtonType), so could someone point me to the right direction, please?
Here is the code, for the custom button class.
import UIKit
class MyCapsuleButton: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
configure()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
init(backgroundColor: UIColor, title: String, textColor: UIColor) {
super.init(frame: .zero)
// super.init(type: .custom) -> tried to initialize with type, but didn't work
self.backgroundColor = backgroundColor
self.setTitle(title, for: .normal)
self.setTitleColor(textColor, for: .normal)
configure()
}
func configure() {
translatesAutoresizingMaskIntoConstraints = false
titleLabel?.font = UIFont.customNormal()
}
override func layoutSubviews() {
super.layoutSubviews()
self.layer.cornerRadius = self.frame.height / 2
}
}
and I call as
lazy var deletionButton: MyCapsuleButton = {
let button = MyCapsuleButton(backgroundColor: .Red(), title: "DELETE", textColor: .white)
button.setImage(Images.delete, for: .normal)
return button
}()
I read the documentation and it says You specify the type of a button at creation time using the init(type:) method, I thought I need to call super.init(type: .custom) in the custom initializer, but I get a "Must call..." error on the storyboard. Also, I dont't use a storyboard in this project, and I want to know how can I call type custom with some custom init parameters, like backgroundColor, title, textColor.
Add this part later...
So, it seems when I make a subclass of UIButton, the type is gonna be custom by default. (I printed out the type and figured out.)
So is setting button.setImage(Images.delete, for: .normal) makes the trash icon gray?
When the Highlighted Adjusts Image (adjustsImageWhenHighlighted) option is enabled, button images get darker when it’s in the highlighted state.
So, You should turn off that attribute like below.
button.adjustsImageWhenHighlighted = false
OR, You can turn off in the storyboard.
Note below screen-shot.
https://i.stack.imgur.com/N42m4.png

Why do I need two inits when implementing a custom UIButton

I am currently learning iOS and one part that I find confusing is having mandatory initializations for things like UIButtons. Here is an example below.
import UIKit
class CustomButton: UIButton {
override init(frame: CGRect) {
super.init(frame: frame)
configure()
}
init(backgroundColor: UIColor, title: String) {
super.init(frame: .zero)
self.backgroundColor = backgroundColor
setTitle(title, for: .normal)
configure()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func configure() {
//code that configures my button
}
}
So here I am creating a custom for my app. I have noticed I needed two inits.
override init(frame: CGRect) {
super.init(frame: frame)
configure()
}
and
init(backgroundColor: UIColor, title: String) {
super.init(frame: .zero)
self.backgroundColor = backgroundColor
setTitle(title, for: .normal)
configure()
}
I always assumed the first init was to actually initialize the button. It is the equivalent of me going to apple and saying "Hey, I want to be able to create a button based off of everything that UIButton has".
However, it seems that I have to have another init if I actually want to be able to customize the button. My second init is me pretty much saying "Hey, I want to be able to create a button with certain attributes such as a background color and a title". I find this kinda weird... Why do I need a separate initializer to do this? Why do I need to set the super.init(frame: .zero)? In a way, why do I even need a super.init in my custom init? Can't I pack everything into the first init?
Just in case, I was rambling. I find it confusing that we have to use two inits. I would think that we could just use one and pack everything into it. To me these two inits feel completely different and serve no purpose for each other. Any help would be much appreciated.
Thanks!

UIBarButton Rendering Issues

Currently, I am implementing somewhat of a custom UIBarButtonItem when I use a couple custom methods to change the positioning of the button image to move it to the right of the text and add some padding. However, when I leave the screen and come back the buttons text and images get switched and distorted as can be seen in the attached images.
First picture is the way the button looks when i leave the screen and come back second picture is what it originally looks like. i have included the code for the uibarbuttonitem if anyone sees anything I don't that is causing this rendering issue I would greatly appreciate it.
import Foundation
import UIKit
class LocationManager: UIBarButtonItem {
var viewController: MainViewController?
lazy var customButton : UIButton = {
let customButton = UIButton(type: .system)
customButton.setImage(UIImage(named: "downArrow"), for: .normal)
customButton.imageEdgeInsets = UIEdgeInsetsMake(0, 20, 0, -10)
guard let customFont = UIFont(name: "NoirPro-SemiBold", size: 20) else {
fatalError("""
Failed to load the "CustomFont-Light" font.
Make sure the font file is included in the project and the font name is spelled correctly.
"""
)
}
customButton.semanticContentAttribute = UIApplication.shared
.userInterfaceLayoutDirection == .rightToLeft ? .forceLeftToRight : .forceRightToLeft
customButton.titleLabel?.font = customFont
customButton.setTitleColor(UIColor.black, for: .normal)
return customButton
}()
override init() {
super.init()
setupViews()
}
#objc func setupViews(){
customView = customButton
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
customView should be of type UIView. I suspect using the higher type of UIButton is causing issues. Within your customView you will need to set up the title and image as sub views and constrain according to your wishes.

Errors with custom class UIButton in Swift 4.2. What's new with UIButton?

I have the following code
import UIKit
class CustomButton: UIButton {
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
self.theme_setTitleColor(GlobalPicker.customButtonTextColor, forState: .normal)
self.theme_setTitleColor(GlobalPicker.customButtonDisabledTextColor, forState: .disabled)
self.theme_backgroundColor = GlobalPicker.primaryColor
self.layer.cornerRadius = self.frame.height/4.0
self.clipsToBounds = true
}
override init(frame: CGRect) {
super.init(frame: frame)
self.layer.cornerRadius = self.frame.height/2.0
self.clipsToBounds = true
}
}
And I'm getting errors when trying to build this code with Xcode 10. The code works just fine with Xcode 9 and Swift 4.0. I was hoping for a seamless transition but apparently that's not what I'm getting.
Is this an Xcode 10 bug? Anyone else running into anything similar?
My guess is that there's an extension somewhere in one of the targets of your project or workspace that messes with UIButton in a way that cripples it somehow. (The fact that this is possible is clear, and I regard it as a bug; see https://bugs.swift.org/browse/SR-2935 and the related duplicates, including https://bugs.swift.org/browse/SR-3228, and mine at https://bugs.swift.org/browse/SR-8010.)
You might be able to slide around the extension by subclassing UIKit.UIButton instead of simple UIButton. For the reason why this works, see the comment discussion in my duplicate bug report. When an extension behaves this way, it overloads methods, and you can distinguish the UIButton that doesn't have the overloads by using the module namespace.

create custom UIButton using extension

I am new on iOS and Swift and I need some help.
I want create custom UIButton
Here is what I did
protocol ButtonProtocol {}
extension ButtonProtocol where Self: UIButton {
func addOrangeButton(){
layer.cornerRadius = 8
layer.backgroundColor = UIColor(netHex:ButtonColor.orange).cgColor
}
}
I want all params came from here which are cornerRadius, backgrounColor, highlightedColor, textColor, size etc...
I want use this way bcoz maybe in future the button color will change I will change it from one place directly.
But I don't understand what is layer how could I cast it as UIButton?
Is anyone can tell me which way should I take ?
You can create the subclass of UIButton, to add your own custom look to your button. like this
import UIKit
protocol DVButtonCustomMethods: class {
func customize()
}
class DVButton: UIButton {
var indexPath: IndexPath?
override init(frame: CGRect) {
super.init(frame: frame)
customize()// To set the button color and text size
}
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
customize()// To set the button color and text size
}
override func layoutSubviews() {
super.layoutSubviews()
customize()
}
}
extension DVButton: DVButtonCustomMethods {
func customize() {
layer.cornerRadius = self.frame.size.height / 2
backgroundColor = UIColor.white
tintColor = UIColor.red
titleLabel?.textColor = UIColor.black
clipsToBounds = true
}
}
Now what is need to do is, create one button in interface builder and assign you subClass as its class. Thats all everything will change as you want. If you want to change button colour just change in your subclass, it will affect in all button which is assigned your subclass.
Assigning subclass to your button: Refer below image
Thanks:)
The way you defined the extension, doesn't make you able to use it in the UIButton instance so simple.
So, you can decide whether extend UIButton to conform the protocol, or you can create a subclass of UIButton
// in this way you can use the `addOrangeButton` method anywhere
extension UIButton: ButtonProtocol {}
// in this way your new subclass contains the addOrangeButton definition
// and a normal UIButton cannot access that method
final class OrangeButton: UIButton, ButtonProtocol {
func setupButton() {
addOrangeButton()
}
}
Try this:
class func CutomeButton(bgColor: UIColor,corRadius: Float,hgColor: UIColor, textColor: UIColor, size: CGSize, titleText: String) -> UIButton {
let button = UIButton()
button.layer.cornerRadius = CGFloat(corRadius)
button.backgroundColor = bgColor
button.setTitleColor(textColor, for: .normal)
button.frame.size = size
button.setTitle(titleText, for: .normal)
return button
}
If I understand well, you want to modify a UIButton with specific parameters, let me tell you how do I do this:
extension UIButton
{
func setRadius(radius:CGFloat) {
self.layer.cornerRadius = radius
}
}
Use it as the following:
yourButton.setRadius(radius: 15)

Resources