Can not set set image for custom button - ios

I'm going to implement a check box like this:
by
class CheckBox: UIButton {
let checkedImage = UIImage(named: "checked")
let uncheckedImage = UIImage(named: "unchecked")
var checked : Bool = false{
didSet{
if checked == false{
self.setImage(uncheckedImage, forState: .Normal)
}else {
self.setImage(checkedImage, forState: .Normal)
}
}
}
override func awakeFromNib() {
self.addTarget(self, action: "buttonClicked:", forControlEvents: .TouchUpInside)
checked = false
}
func buttonClicked(sender: UIButton){
if (sender == self){
checked = !checked
}
}
}
but everything I got is:
Could you explain what happened?

i tried your code it's works fine i only changed this part self.addTarget... to:
self.addTarget(self, action: #selector(CheckBox.buttonClicked(_:)), forControlEvents: .TouchUpInside)
and when you create the button change it class to: CheckBox

Call self.setNeedsLayout() at the end of your didSet statement.
If you change any of subviews you need to ask it to update it's layout and children. Let me know if that helped.

Related

Unable to change image for the button in swift 3?

In my code for checkmark I used button to change images for selected and unselected but unable to implement if I click on it's changing to unchecked but again selecting button it's unable to change to check image can anyone help me how to resolve this ?
var checkedImage = UIImage(named: "check")! as UIImage
var uncheckedImage = UIImage(named: "uncheck")! as UIImage
var isChecked: Bool = true
var checkMarkSelected = 0
checkMarkButton.addTarget(self, action: #selector(checkMarkAction(button:)), for: .touchUpInside)
func checkMarkAction(button : UIButton) {
if isChecked == true {
checkMarkButton.setImage(checkedImage, for: .selected)
isChecked = false
checkMarkSelected = 1
}
else {
checkMarkButton.setImage(uncheckedImage, for: .normal)
isChecked = true
checkMarkSelected = 0
}
}
Step 1: Select your CheckUIButton and set Image “Uncheck” (state config must be Default in attribute inspector)
Step 2: In attribute inspector change state config to Selected and set image “Check”
Step 3: Put following code in your UIButton action.
#IBAction func checkclick(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
}
In Swift 3
#IBAction func btntouchupInsideevent(_ sender: UIButton)
{
if yourbtnOutletName.currentImage == "YourCheckImageName"
{
yourbtnOutletName.setImage(YourUncheckImage.imagetype, for: .normal)
}
else
{
btnIsEventRecouring.setImage(YourcheckImage.imagetype, for: .normal)
}
}
I think that you should add the action in the viewDidLoad() function of your view controller for that button or, if you are declaring it in a stand-alone UIButton inherited class in order to reuse it in the future in many view controllers, you should add the target in the initialiser of the UIButton.
If the code is written in that way is even strange that Xcode is not giving you warnings...
EDIT: This is a code snippet of how I would do it
//Comments
import UIKit
class ViewController: UIViewController {
//link this to the checkmark buttons
//subclass UIButton making a button with the property isChecked: Bool
#IBOutlet weak var checkmarkButton: UICheckButton!
var checkMarkSelected = 0
override function viewDidLoad() {
//do stuff with your viewdidload
}
//link this to the checkmark buttons
#IBAction func checkMarkAction(sender: UICheckButton) {
if sender.isChecked == false {
let checkedImage = UIImage(named: "check")
checkMarkButton.setImage(checkedImage, for: .normal)
sender.isChecked = true
checkMarkSelected += checkMarkSelected
} else {
let uncheckedImage = UIImage(named: "uncheck")
checkMarkButton.setImage(uncheckedImage, for: .normal)
sender.isChecked = false
checkMarkSelected -= checkMarkSelected
}
}
In Swift 4:
#IBOutlet weak var termsAndConditionsButton: UIButton!
if termsAndConditionsButton.isSelected == true {
termsAndConditionsButton.setImage(UIImage(named: "checkboxOff"), for: .normal)
termsAndConditionsButton.isSelected=false
}
else{
termsAndConditionsButton.setImage(UIImage(named: "checkboxOn"), for: .normal)
termsAndConditionsButton.isSelected=true
}
Try with this on IBAction function
sender.isSelected = !sender.isSelected
if sender.isSelected == true {
sender.isSelected = true
sender.setImage(UIImage(named: "img_on"), for: UIControl.State.selected)
}else{
sender.isSelected = false
sender.setImage(UIImage(named: "img_off"), for: UIControl.State.normal)
}

Toggle between select/deselect UIButton

I have a button which I want to change background color and text when tapped(select) and bring it back to its original state when tapped again (deselect). I am able to select it but I am not being able to deselect it. I have researched on SO and I am getting errors in this code in the if-else part
#IBAction func btn1Pressed(_ sender: AnyObject) {
sender.setTitleColor(UIColor.blue, for: UIControlState.normal)
(sender as! UIButton).backgroundColor = UIColor.green
if sender.isSelected {
sender.selected = false
}
else {
sender.selected = true
}
}
Try this:
#IBAction func btnPressed(_ sender: AnyObject) {
guard let button = sender as? UIButton else { return }
if !button.isSelected {
button.isSelected = true
button.setTitleColor(UIColor.blue, for: UIControl.State.normal)
button.backgroundColor = UIColor.green
}
else {
button.isSelected = false
button.setTitleColor(UIColor.green, for: UIControl.State.normal)
button.backgroundColor = UIColor.blue
}
}
It sounds to me like UISwitch is what you're looking for. Give it a try instead of wasting time implementing something that's already there for you.
try this
#IBAction func btn1Pressed(sender: UIButton) {
if sender.selected {
sender.selected = false
sender.setTitleColor(UIColor.redColor(), forState: .Normal)
sender.backgroundColor = UIColor.blackColor()
}
else {
sender.selected = true
sender.setTitleColor(UIColor.redColor(), forState: .Selected)
sender.backgroundColor = UIColor.blackColor()
}
}
Change background color of selected button from storyboard like below in state config choose selected and then change background color and also coustomize default for normal button.
and use below in action
(sender as! UIButton).selected = !(sender as! UIButton).selected
Please try this code first you need to crate action and propert of the button like
#IBOutlet var btn_ButtonPressed: UIButton!
then Action.
#IBAction func click_ButtonPressed(_ sender: Any) {
if !sender.isSelected() {
sender.selected = true
btn_ButtonPressed.setTitleColor(UIColor.red, forState: .normal)
btn_ButtonPressed.backgroundColor = UIColor.yellow
}
else {
sender.selected = false
btn_ButtonPressed.setTitleColor(UIColor.yellow, forState: .normal)
btn_ButtonPressed.backgroundColor = UIColor.red
}
}
this one worked fine for me!
//
#IBAction func buttonColorChanger(sender : UIButton ) {
if button.isSelected == false
{
button.backgroundColor = UIColor.purple
print("selected")
button.setTitle("selected", for: .normal)
button.setTitleColor(UIColor.white, for: .normal)
button.isSelected = true
}else{
button.backgroundColor = UIColor.white
print("unselected")
button.isSelected = false
}
}
A cleaner approach would be:
#objc private func buttonTapped(_ sender: UIButton) {
sender.isSelected.toggle()
if selected {
// Setup appearance for selected state.
} else {
// Setup appearance for deselected state.
}
}

Swift button press copy text

I have a button inside a cell inside a collection view, everything works fine except for the copy function I'm trying to create. When I click on the button the text is not copied or in my test case the text is not printed to console.
cell.buttonViewLink.addTarget(self, action: "buttonViewLinkAction:", forControlEvents: UIControlEvents.TouchUpInside)
func buttonViewLinkAction(sender:UIButton!) {
print("Button tapped")
}
In my storyboard I have a touch up inside action linked from the button to the view (I created this with ctrl-drag form the button to view). Everything looks OK but yet when I press the button nothing happens, doesn't crash either as things look OK.
What am I missing?
do like
Copy
func buttonViewLinkAction(sender:UIButton!) {
print("Button tapped")
UIPasteboard.generalPasteboard().string = yourstring!.text() // or use sender.titleLabel.text
}
paste or Retrieve
func GetCopiedText(sender: UIButton!) {
if let myString = UIPasteboard.generalPasteboard().string {
print(myString)
}
}
Update
func buttonViewLinkAction(sender:UIButton!) {
print(sender.currentTitle)
print(sender.titleLabel.text)
}
update-2
you written the buttonViewLinkAction code in inside the func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) its never call. so remove the buttonViewLinkAction and add outside the method of data source
//fontawesome link
cell.buttonViewLink.setTitle(String.fontAwesomeIconWithName(.Link), forState: .Normal)
cell.buttonViewLink.titleLabel?.font = UIFont.fontAwesomeOfSize(20)
cell.buttonViewLink.addTarget(self, action: "buttonViewLinkAction:", forControlEvents: UIControlEvents.TouchUpInside)
func buttonViewLinkAction(sender:UIButton!) {
print("Button tapped")
UIPasteboard.generalPasteboard().string = "Label text"
}
Final Answer
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! CellClass
let face = self.faces[indexPath.item]
//set image and align center
if let imageURL = NSURL(string:face.image) {
cell.imageView.sd_setImageWithURL(imageURL)
} else {
cell.imageView.image = self.placeholderImage
}
//set name
if let imageNAME: String = String(face.name){
cell.labelView.text = (imageNAME .uppercaseString)
} else {
cell.labelView.text = "oops name"
}
//set border
cell.layer.shadowOffset = CGSizeMake(0, 1)
cell.layer.shadowColor = UIColor.blackColor().CGColor
cell.layer.shadowRadius = 1
cell.layer.shadowOpacity = 0.1
cell.clipsToBounds = false
let shadowFrame: CGRect = (cell.layer.bounds)
let shadowPath: CGPathRef = UIBezierPath(rect: shadowFrame).CGPath
cell.layer.shadowPath = shadowPath
//square background button
cell.buttonViewSquare.backgroundColor = UIColor(red: 249/255, green: 249/255, blue: 249/255, alpha: 1)
cell.buttonViewSquare.enabled = false
//fontawesome link
cell.buttonViewLink.setTitle(String.fontAwesomeIconWithName(.Link), forState: .Normal)
cell.buttonViewLink.titleLabel?.font = UIFont.fontAwesomeOfSize(20)
cell.buttonViewLink.addTarget(self, action: "buttonViewLink:", forControlEvents: UIControlEvents.TouchUpInside)
// or use like cell.buttonViewLink.addTarget(self, action: "buttonViewLinkAction:", forControlEvents: UIControlEvents.TouchUpInside)
//fontawesome heart
cell.buttonViewHeart.setTitle(String.fontAwesomeIconWithName(.Heart), forState: .Normal)
cell.buttonViewHeart.titleLabel?.font = UIFont.fontAwesomeOfSize(20)
cell.buttonViewHeart.setTitleColor(UIColor.redColor(), forState: UIControlState.Normal)
//fontawesome share
cell.buttonViewShare.setTitle(String.fontAwesomeIconWithName(.Share), forState: .Normal)
cell.buttonViewShare.titleLabel?.font = UIFont.fontAwesomeOfSize(20)
return cell
}
call method like
func buttonViewLink(sender:UIButton!) {
print("Button tapped")
UIPasteboard.generalPasteboard().string = sender.titleLabel.text
}
or use directly already you have a function
#IBAction func buttonViewLinkAction(sender: UIButton) {
print("Button tapped")
UIPasteboard.generalPasteboard().string = sender.titleLabel.text
}
modified Answer
add tag in here cell.buttonViewLink.tag = indexPath.item
cell.buttonViewLink.setTitle(String.fontAwesomeIconWithName(.Link), forState: .Normal)
cell.buttonViewLink.titleLabel?.font = UIFont.fontAwesomeOfSize(20)
cell.buttonViewLink.addTarget(self, action: "buttonViewLinkAction:", forControlEvents: UIControlEvents.TouchUpInside)
cell.buttonViewLink.tag = indexPath.item
and call the methof like
#IBAction func buttonViewLinkAction(sender: UIButton) {
print("Button tapped")
let face = self.faces[sender.tag]
if let imageNAME: String = String(face.name){
print(imageNAME .uppercaseString)
}
if let imageURL = NSURL(string:face.image) {
print(imageURL)
}
UIPasteboard.generalPasteboard().string = sender.titleLabel.text
}
Update Swift 4.2
override func viewDidLoad() {
super.viewDidLoad()
label.addGestureRecognizer(UILongPressGestureRecognizer(target: self, action: #selector(copyValuePressed)))
}
#objc func copyValuePressed() {
UIPasteboard.general.string = label.text
}
You just posted your code. The problem is you are doing it inside function. Please take it out of it and it is working well.
Why you are not using it like this:
cell.buttonViewLink.setTitle(String.fontAwesomeIconWithName(.Link), forState: .Normal)
cell.buttonViewLink.titleLabel?.font = UIFont.fontAwesomeOfSize(20)
cell.buttonViewLink.addTarget(self, action: "buttonViewLinkAction:", forControlEvents: UIControlEvents.TouchUpInside)
func buttonViewLinkAction(sender:UIButton!) {
print("Button tapped")
UIPasteboard.generalPasteboard().string = "Label text"
}
You have two duplicated buttonViewLinkAction functions!
When you press the button, this function will be called:
#IBAction func buttonViewLinkAction(sender: UIButton) {
}
instead of this
func buttonViewLinkAction(sender:UIButton!) {
print("Button tapped")
}
Remove the second function and write your code in the first function.
Also, you don't need to write this line:
cell.buttonViewLink.addTarget(self, action: "buttonViewLinkAction:", forControlEvents: UIControlEvents.TouchUpInside)
if you have already linked the button to the function (In the storyboard).

Select/deselect buttons swift xcode 7

Part way done with learning swift but I hit a small wall and yet again, I'm sure I'm just a bit new at this and an easy solution is there but I'm having trouble figuring out how to select/deselect buttons below is what I have so far and it is a button turns into a checkmark when clicked on... I've gotten that far but I need that button to deselect when clicked on again and then obviously be able to be clicked again if need be.
#IBAction func buttonPressed(sender: AnyObject) {
sender.setImage(UIImage(named: "Checkmark.png"), forState: .Normal)
}
Swift 3 note: .selected and .checked are now lower case UIControlState values in the SDK, and some of the methods have been renamed:
let button = UIButton()
button.setImage(UIImage(named: "Unchecked"), for: .normal)
button.setImage(UIImage(named: "Checked"), for: .selected)
You can also now use image literals with Xcode 8 instead of UIImage(named:):
#imageLiteral(resourceName: "Unchecked")
Swift 2:
Why not use the .Selected state of the button as the "checked" state, and the .Normal state as the "unchecked" state.
let button = UIButton()
button.setImage(UIImage(named: "Unchecked"), forState: .Normal)
button.setImage(UIImage(named: "Checked"), forState: .Selected)
// ...
#IBAction func buttonPressed(sender: AnyObject) {
if let button = sender as? UIButton {
if button.selected {
// set deselected
button.selected = false
} else {
// set selected
button.selected = true
}
}
}
You dont need to set selected in condition. I just doing with following method in swift:
func selectDeselect(sender: UIButton){
sender.selected = !sender.selected
if(sender.selected == true)
{
sender.setImage(UIImage(named:"select_heart"), forState: UIControlState.Normal)
}
else
{
sender.setImage(UIImage(named:"heart"), forState: UIControlState.Normal)
}
}
Here is Working code for swift 4.
Make Sure you need to connect Button IBAction Outlet as UIButton and set default button image from storyboard whatever you want.
#IBAction func btnTapped(_ sender: UIButton) {
if sender.currentImage == UIImage(named: "radio_unchecked"){
sender.setImage(UIImage(named: "radio_checked"), for: .normal)
}else{
sender.setImage(UIImage(named: "radio_unchecked"), for: .normal)
}
}
update for Swift 4+ :
let button = UIButton()
button.setImage(UIImage(named: "Unchecked"), forState: .Normal)
button.setImage(UIImage(named: "Checked"), forState: .Selected)
#IBAction func buttonPressed(sender: AnyObject) {
if let button = sender {
if button.isSelected {
// set deselected
button.isSelected = false
} else {
// set selected
button.isSelected = true
}
}
}
Set uncheck image on default state from storyboard and check image on selected state from storyboard.
#IBAction func buttonPressed(sender: AnyObject) {
buttonOutlet.isSelected = !buttonOutlet.isSelected
}
private(set) lazy var myButton: UIButton = {
let button = UIButton()
button.setImage(UIImage(named: "Unchecked"), for: .normal)
button.setImage(UIImage(named: "Checked"), for: .selected)
button.addTarget(self, action: #selector(buttonTapped), for: .touchUpInside)
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
#objc
func buttonTapped(sender: AnyObject) {
sender.isSelected.toggle()
}
To select only the pressed button out of three buttons and deselect the others when designated button is pressed.
#IBAction func buttonPressed(_ sender: UIButton) {
// Deselect all buttons
button1.isSelected = false
button2.isSelected = false
button3.isSelected = false
// Select the pressed button
sender.isSelected = true
}

Crash with Thread 1: signal SIGABRT

I am creating a class to manage the checkboxes.
This is what I did:
import UIKit
class CheckboxButton: UIButton {
//let checked = ""
//let unchecked = ""
let checked = "bubu"
let unchecked = "baba"
var isChecked:Bool = false{
didSet{
if isChecked == true {
self.setTitle(checked, forState: UIControlState.Normal)
}else{
self.setTitle(unchecked, forState: UIControlState.Normal)
}
}
}
override func awakeFromNib() {
self.titleLabel?.font = UIFont(name: "FontAwesome", size: 20)
self.addTarget(self, action: "buttonClicked", forControlEvents: UIControlEvents.TouchUpInside)
self.isChecked = false
}
func buttonClicked(sender:UIButton){
if(sender == self){
if isChecked == true {
isChecked = false
}else{
isChecked = true
}
}
}
}
Everything is fine, but when I click on the button, the app just crashes with error Thread 1: signal SIGABRT
Is there something wrong?
Thanks for any help!
Since your action function takes parameters func buttonClicked(sender:UIButton) the action of your target should always contain : at the end, so all you have to do is to replace add target line with this
self.addTarget(self, action: "buttonClicked:", forControlEvents: UIControlEvents.TouchUpInside)
Also your buttonClicked function can be simplified like this:
func buttonClicked(sender:UIButton){
if(sender == self){
isChecked = !isChecked
}
}

Resources