Swift - SwipingController Programmatic - button doesn't work - ios

I created the SwipingController app.
The application was supposed to have the functionality of scrolling with gestures and a management bar with 2 buttons and UIPageControl.
For now, these buttons were supposed to print only a text message in the console, but it doesn't.
let nextButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("NEXT", for: .normal)
button.setTitleColor(.black, for: .normal)
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 14)
button.addTarget(self, action: #selector(handleNextButton), for: .touchUpInside)
return button
}()
#objc func handleNextButton() {
print("Next Botton Pressed")
}
I wanted to add the whole page management bar in a separate file.
When it goes to the main controller, the whole functionality work.
I don't want to paste all the code, so it gives a link to the git
https://github.com/SebaKrk/SwipingControllerProgrammatic.git
Picture from simulator

The Problem is that you set your target right in the setup code of your UIButton
let previousBotton : UIButton = {
let button = UIButton(type: .system)
button.setTitle("PREV", for: .normal)
button.setTitleColor(.black, for: .normal)
button.titleLabel?.font = UIFont.boldSystemFont(ofSize: 14)
button.addTarget(self, action: #selector(handlePreviousButton), for: .touchUpInside)
return button
}()
It seems like the self is not initialized at this point. Because this code is run before your init was run.
So you have to set the target of the Button after you called super.init then it works.

Related

UIButton doesn't work when the searchController is active?

I'm using a UICollectionViewCompositionalLayout with a search controller:
just like this
The Problem:
I can't tap on the UI Button present in the header of Section when the search controller is active. But the GestureRecognizer of the Section just works fine.
Both of them works when I'm not searching anything, and if a tap "enter" on keyboard while searching, the button start to work.
What I'm doing wrong?
I just found an solution. For those who are having problem:
I was adding the Target this way
let button: UIButton = {
let button = UIButton(type: .custom)
button.setTitle("See all", for: .normal)
button.setImage(UIImage(systemName: "chevron.right", withConfiguration: buttonConfig), for: .normal)
button.addTarget(self, action: #selector(myFunc), for: .touchUpInside)
return button
}()
Removing the addTarget, and adding it on the Init of the class fixes the Problem.
override init(frame: CGRect) {
super.init(frame: frame)
addSubview(button.addTarget)
button.addTarget(self, action: #selector(myFunc), for: .touchUpInside)
}
I Don't know why, but it works. lol

UIButton selector is not working

I have a view that is placed as a subview of navigationController in order to fill the whole display. On this view I have a subview that has two buttons. "Remove and Done". and then it also has a datepicker. The datePicker works, however, the Remove and Done buttons are not firing the action functions.
The buttons:
var setButton: UIButton = {
var button = UIButton(type: .system)
button.setTitle("Done", for: .normal)
button.tintColor = .white
button.addTarget(self, action: #selector(handleReminderSetBtn), for: .touchUpInside)
return button
}()
var cancelButton: UIButton = {
var button = UIButton(type: .system)
button.setTitle("Remove", for: .normal)
button.tintColor = .white
button.addTarget(self, action: #selector(handleReminderCancelBtn), for: .touchUpInside)
return button
}()
The main blackView that is in the navigationController:
viewOverLay.addSubview(cardreminder1)
viewOverLay.frame = CGRect(x: 0, y: 0, width: screenSize.width, height: screenSize.height)
viewOverLay.backgroundColor = UIColor.black.withAlphaComponent(0.3)
self.navigationController?.view.addSubview(viewOverLay)
CardReminder1 is the UIView on which I have two buttons.
I reckon there is some issue with the target in the addTarget method of the two buttons. What could be the issue?
You shouldn't initialize setButton and cancelButton in that way.
Quoting the Apple documentation from Setting a Default Property Value with a Closure or Function:
If you use a closure to initialize a property, remember that the rest of the instance has not yet been initialized at the point that the closure is executed. This means that you cannot access any other property values from within your closure, even if those properties have default values.
moreover:
You also cannot use the implicit self property, or call any of the instance’s methods, hence the problem is here:
addTarget(self...)
so to fix the issue you should move the buttons initialization (or move the addTarget) after your CardReminder1 is fully initialized.
I just had a similar issue. Along with the other answer posted, making the property lazy worked in my case as well. It depends on when you first try to access that property, but in my case I only accessed it after initialization was complete, so making the property lazy worked perfectly.
For example in your case, the following might work:
lazy var setButton: UIButton = {
var button = UIButton(type: .system)
button.setTitle("Done", for: .normal)
button.tintColor = .white
button.addTarget(self, action: #selector(handleReminderSetBtn), for: .touchUpInside)
return button
}()
lazy var cancelButton: UIButton = {
var button = UIButton(type: .system)
button.setTitle("Remove", for: .normal)
button.tintColor = .white
button.addTarget(self, action: #selector(handleReminderCancelBtn), for: .touchUpInside)
return button
}()

Remove button when click itselt in swift 3

Hello I have a custom UIButton has added. And I want to remove this button when click on it self. I have done like this.
btnDelete.addTarget(self, action: #selector(deleteCoveringPerson(sender:)), for: .touchUpInside)
btnDelete.setImage(UIImage.init(named: "close-dark"), for: .normal)
btnCoveringPerson.addSubview(btnDelete)
And this is my delete button selector
func deleteCoveringPerson(sender:UIButton)
{
dm.strCoveringPersonNAme=""
dm.strcoveringPersonCode="0"
btnCoveringPerson.setTitle(lan.getConvertedLanguageString(word: "COVERINGPERSON"), for: .normal)
btnDelete.removeFromSuperview()
}
How can I do this?
For me this work just fine
func deleteCoveringPerson(sender:UIButton)
{
dm.strCoveringPersonNAme=""
dm.strcoveringPersonCode="0"
btnCoveringPerson.setTitle(lan.getConvertedLanguageString(word: "COVERINGPERSON"), for: .normal)
sender.removeFromSuperview()
}
Hope this helps

How can I change a group of button's image's colors in Swift3?

I recently asked a question here where I wanted to understand how to change the UIColor of a button's image. I followed #Dorian Roy's recommendation which was very clean and it worked well for my needs. While my specific question previously was around a single button, I would like to know how to change multiple UIBUttons. Can this be done? My thought would be to subclass a UIButton and initialize it to automatically change its image color. I can't quite grasp how to do this though.
Here is how I am currently performing this action and I am seeking a more elegant solution.
private func changeBtnColors() {
let ccStencil = creditCardBtn.imageView?.image?.withRenderingMode(.alwaysTemplate)
let planeStencil = planeBtn.imageView?.image?.withRenderingMode(.alwaysTemplate)
let towelStencil = towelBtn.imageView?.image?.withRenderingMode(.alwaysTemplate)
let carStencil = carBtn.imageView?.image?.withRenderingMode(.alwaysTemplate)
let trainStencil = trainBtn.imageView?.image?.withRenderingMode(.alwaysTemplate)
let graphStencil = graphBtn.imageView?.image?.withRenderingMode(.alwaysTemplate)
creditCardBtn.setImage(ccStencil, for: .normal)
planeBtn.setImage(planeStencil, for: .normal)
towelBtn.setImage(towelStencil, for: .normal)
carBtn.setImage(carStencil, for: .normal)
trainBtn.setImage(trainStencil, for: .normal)
graphBtn.setImage(graphStencil, for: .normal)
creditCardBtn.tintColor = UIColor.white
planeBtn.tintColor = UIColor.white
towelBtn.tintColor = UIColor.white
carBtn.tintColor = UIColor.white
trainBtn.tintColor = UIColor.white
graphBtn.tintColor = UIColor.white
}
The simplest way is create one array of UIButton and loop through all the elements.
let buttonArray = [creditCardBtn, planeBtn, towelBtn, carBtn, trainBtn, graphBtn]
buttonArray.forEach { button in
let image = button.imageView?.image?.withRenderingMode(.alwaysTemplate)
button.setImage(image, for: .normal)
button.tintColor = UIColor.white
}
You can also create extension of UIButton and put this settings code of Button in a function like this.
extension UIButton {
func setImageWithRandringMode() {
let image = self.imageView?.image?.withRenderingMode(.alwaysTemplate)
self.setImage(image, for: .normal)
self.tintColor = .white
}
}
And now simply call this function with forEach closure.
buttonArray.forEach { button in
button.setImageWithRandringMode()
}

Can't change UIbutton image for different state

I want to change the image of a UIButton for different states. To achieve this, I'm using:
btn.setImage(UIImage(named: "blabla"), for .normal)
and
btn.setImage(UIImage(named: blabla2), for .disabled)
This only makes some appear dimmed.
What did I do wrong? I just want to make my button appearance the same for different states, how?
(my button type - .system).
This helped me (swift 3.0)
btn.setImage(UIImage(named:"yourFriend")?.withRenderingMode(.alwaysOriginal), for: .normal)
btn.setImage(UIImage(named:"yourFriend")?.withRenderingMode(.alwaysOriginal), for: .disabled)
You just need to set one for the state. And if you don't set another image for different state. It would look the same in all state.
button.setImage(image, forState: .Normal)
How to change UIButton image in Swift
For display disabled button set image
let btn = UIButton(type: .Custom)
btn.setImage(UIImage(named: blabla2), for .disabled)
Then
btn.enabled = false // to display Disable image
btn.enabled = true // to display Normal image
private let button1: UIButton = {
let button = UIButton(type: .custom)
button.setImage(UIImage(named:"firstButtonNormalStateImage"), for: .normal)
button.setImagesetImage(UIImage(named:"firstButtonSelectedStateImage"), for: .selected)
return button
}()
private let button2: UIButton = {
let button = UIButton(type: .custom)
button.setImage(UIImage(named:"secondButtonNormalStateImage"), for: .normal)
button.setImage(UIImage(named:"secondButtonSelectedStateImage"), for: .selected)
return button
}()
// implement for example in viewDidLoad()
button1.addTarget(self, action: #selector(firstButtonDidTap), for: .touchUpInside)
button2.addTarget(self, action: #selector(secondButtonDidTap), for: .touchUpInside)
// trigger actions
#objc func firstButtonDidTap() {
button1.isSelected = true
button2.isSelected = false
}
#objc func secondButtonDidTap() {
button2.isSelected = true
button1.isSelected = false
}
For whoever is still having this issue (currently Xcode 10.0) with a Custom button, I found I was able to change the text and/or image if instead of:
myButton.setTitle("Hi", for: [.normal])
I used this:
myButton.setTitle("Hi", for: []) //remove specific states
I don't know why .normal was not working for me, even though the button was definitely enabled. But maybe this will save someone else a headache!
You can simply do this by StoryBoard as well.
Select the button, got to identity inspector and do the following:-
Firstly set the buttonType to custom instead of system.
Secondly choose state Config to lets say default and give the imageName in "image" attribute, similarly choose other state configs (Highlighted, disabled, selected etc.) and set images as required by you.
Then later in the code you just have to control and set the state of the button, and respective image will be shown to you.

Resources