Comicmind Material Framework button event handler - ios

I would just like to ask, how can I handle events of the Material Button using cosmicmind/Material? I currently have this code. Now, I want to do a function when user taps or clicked the button. Thank you!
fileprivate func prepareRaisedButton() {
let button = RaisedButton(title: "Create an account", titleColor : .white)
button.pulseColor = .white
button.backgroundColor = Color.teal.base
view.layout(button)
.height(ButtonLayout.Raised.height)
.top(18 * constant).horizontally(left : constant, right : constant)
}

The method you want is inherited from UIControl:
button.addTarget(self, action: #selector(tapButton), for: .touchUpInside)

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

"addTarget" action function of UIButton not called (strikethrough)? [duplicate]

This question already has an answer here:
Why does Xcode line-out autocomplete methods for selector?
(1 answer)
Closed 2 years ago.
I have a UIButton within a UITableViewCell. When I call addTarget on the button and attempt to put a function in, the autocomplete has the function crossed out with a white line (see first image). Xcode still allows me to put the function in and run the app; however, when the button is tapped the function isn't called.
Button initialization:
private let infoButton: UIButton = {
let button = UIButton()
button.backgroundColor = .clear
button.adjustsImageWhenHighlighted = false
button.setImage(Images.sizeGuide, for: .normal)
button.addTarget(self, action: #selector(infoButtonPressed(_:)), for: .touchUpInside)
return button
}()
Function (infoButtonPressed):
#objc private func infoButtonPressed(_ sender: UIButton) {
print("Button Pressed")
}
Because I reuse this cell multiple times and only one of these cells needs to have this button, I have a variable that dictates whether or not to show the button:
var hasInfoButton: Bool = false {
didSet {
if hasInfoButton {
setupInfoButton()
}
}
}
The function that is called above simply sets up the button using autoLayout. Something to mention: when I tried calling addTarget in this function, the app crashed with Unrecognized selector sent to instance...
The tableView in which this is embedded in is only static and displays data. Therefore, allowSelection and allowsMultipleSelection are both set to false.
Does anyone have a solution to this?
You shouldn't need (_ sender: UIButton) the method should just be:
#objc func infoButtonPressed() {
print("button pressed")
}
EDIT:
The button initializer is also a little strange. The way I generally go about this kind of thing is like this:
let button = UIButton()
private func configureButton() {
button.backgroundColor = .clear
button.adjustsImageWhenHighlighted = false
button.setImage(Images.sizeGuide, for: .normal)
button.addTarget(self, action: #selector(infoButtonPressed(_:)), for: .touchUpInside)
}
Then call configureButton() in viewDidLoad()

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.

How to change UIButton label programmatically

When I first run my app, I retrieve a number from my server and display it for my UIButton label. Think of this as a notification number displayed on a red UIButton.
When I remove a notification within the app, I want my UIButton label decrement by 1. I am able to get the decremented number from the server after I delete a notification, but I can't display this new number on the UIButton. The button always displays the number when the app is first fired.
I call makeButtonView() method after I remove a notification to update the UIButton
func makeButtonView(){
var button = makeButton()
view.addSubView(button)
button.tag = 2
if (view.viewWithTag(2) != nil) {
view.viewWithTag(2)?.removeFromSuperview()
var updatedButton = makeButton()
view.addSubview(updatedButton)
}else{
println("No button found with tag 2")
}
}
func makeButton() -> UIButton{
let button = UIButton(frame: CGRectMake(50, 5, 60, 40))
button.setBackgroundImage(UIImage(named: "redBubbleButton"), forState: .Normal)
API.getNotificationCount(userID) {
data, error in
button.setTitle("\(data)", forState: UIControlState.Normal)
}
button.addTarget(self, action: "targetController:", forControlEvents: UIControlEvents.TouchUpInside)
return button
}
Use this code for Swift 4 or 5
button.setTitle("Click Me", for: .normal)
I need more information to give you a proper code. But this approach should work:
lazy var button : UIButton = {
let button = UIButton(frame: CGRectMake(50, 5, 60, 40))
button.setBackgroundImage(UIImage(named: "redBubbleButton"), forState: .Normal)
button.addTarget(self, action: "targetController:", forControlEvents: UIControlEvents.TouchUpInside)
return button
}()
func makeButtonView(){
// This should be called just once!!
// Likely you should call this method from viewDidLoad()
self.view.addSubview(button)
}
func updateButton(){
API.getNotificationCount(userID) {
data, error in
// be sure this is call in the main thread!!
button.setTitle("\(data)", forState: UIControlState.Normal)
}
}
There have been some updates since Swift 4. This works for me:
self.button.setTitle("Button Title", for: UIControl.State.init(rawValue: 0))
Replace button with your IBOutlet name. You can also use a variable or array in place of the quoted text.
It's fairly simple ...
import UIKit
class ViewController: UIViewController {
#IBOutlet var button: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
button.setTitle("hello world", forState: UIControlState.Normal)
}
}
I believe if you set the state to normal, the value will propagate by default to other states so long as you haven't explicitly set a title for those states.
Said differently, if you set it for normal, it should also display this title when the button enters additional states
UIControlState.allZeros
UIControlState.Application
UIControlState.Disabled
UIControlState.Highlighted
UIControlState.Reserved
UIControlState.Selected
Lastly, here's Apple's documentation in case you have other questions.
Since your API call should be running on a background thread you need to dispatch your UI update back to the main thread like this:
DispatchQueue.main.async {
button.setTitle(“new value”, forState: .normal)
}
After setting the title, just a simple redraw of the button will do:
button.setNeedsDisplay();

Swift Link Button to Controller

I have a programatically made button, which i would like to connect it to an action so that it goes straight to another view when I click it. Normally i would just control + drag. but i can't since it programatically made. How would i link this code to my "ViewController" so when i click it, the ViewController(log-in screen) Pops up.
The Code is here, and its from https://github.com/mamaral/Onboard
let thirdPage: OnboardingContentViewController = OnboardingContentViewController(title: "Seriously Though", body: "Kudos to the photographer.", image: UIImage(named:"yellow"), buttonText: "Let's Get Started"){ //Enter Action Here//
I'm not sure whether this part is necessary to help you, but i'll link it just in case
if (countElements(self.buttonText) != 0) {
var actionButton: UIButton = UIButton(frame: CGRectMake((CGRectGetMaxX(self.view.frame) / 2) - (contentWidth / 2), CGRectGetMaxY(self.view.frame) - kDefaultMainPageControlHeight - kDefaultActionButtonHeight - self.bottomPadding, contentWidth, kDefaultActionButtonHeight))
actionButton.titleLabel?.font = UIFont .systemFontOfSize(24)
actionButton.setTitle(self.buttonText, forState: .Normal)
actionButton.setTitleColor(self.buttonTextColor, forState: .Normal)
actionButton.addTarget(self, action: "handleButtonPressed", forControlEvents: .TouchUpInside)
self.view.addSubview(actionButton)
Going off of this line of code:
actionButton.addTarget(self, action: "handleButtonPressed", forControlEvents: .TouchUpInside)
If it isn't working, you probably forgot to add an actual function titled "handleButtonPressed"--something like this:
func handleButtonPressed() {
// Show the view that needs showing
}

Resources