Swift UIButton text does not change - swift

I have one UIButton in a UIView and I change its title. However, when I get the button title it is giving me the old title and not the changed one. However, when I call it from somewhere when the method is finished it's true
Thanks,

Wrapping your if statements in a performWithoutAnimation block will prevent any delays in updates to the titleLabel.
UIView.performWithoutAnimation {
if btnOne.titleLabel?.text == "qq" {
btnOne.setTitle("metin", forState: .Normal)
var a = btnOne.titleLabel?.text // "metin"
mergeString += sender.titleLabel!.text!
}
...
}

Related

Cannot display UIActivityIndicatorView

I meet a question. I am using following code to display UIActivityIndicatorView. My requirement is to be able to create an UIActivityIndicatorView and display it when I click the button with tag 1, if I click other buttons the UIActivityIndicatorView will be removed from the super view.
class ViewController: UIViewController {
lazy var acLoad:(UIActivityIndicatorView) = {
let myActivityIndicator = UIActivityIndicatorView(style: UIActivityIndicatorView.Style.white)
myActivityIndicator.center = view.center
myActivityIndicator.hidesWhenStopped = true
myActivityIndicator.startAnimating()
return myActivityIndicator
}()
//more code
#objc func btnAction(sender: UIButton){
switch sender.tag {
case 1:
print("created")
view.addSubview(acLoad)
acLoad.startAnimating()
default:
print("removed")
acLoad.stopAnimating()
acLoad.removeFromSuperview()
}
}
}
The above doesn't work, I can get the print log after click, but UIActivityIndicatorView doesn't display, any ideas?
It seems like your UIActivityIndicatorView might be misplaced (wrong frame value) - so it is not visible to you.
print("created")
view.addSubview(acLoad)
acLoad.startAnimating()
// Add this line in your button tap code
// It will tell you where it is placed inside your view
print(acLoad.frame)
If you find that it's frame is not where you want it to be, just fix your layout code and it will be where you expect it to be.
Another note - myActivityIndicator.hidesWhenStopped = true makes it automatically hide on stopAnimating() call. So you can add it only once, not remove-add every time.
Also check your view.backgroundColor vs acLoad style.

animating a cell when pressed affects other cells

I want to animate a card when pressed.
I made a table view, and added a custom cell to it.
and in custom cells, I created a UIButton and applied .touchUpInside gesture on the button.
when the button is pressed, the background color of the card will turn to red.
but weird thing is, if I press the first button,
6th, 10th, 15th and more cards' background-color also changed.
I check the function called only once but it happens to several cards.
I assume this might be related to dequeueReusableCell cell but not sure...
can anybody please help me out?
#objc func cardPressed(){
changeCardBackground()
}
private func changeCardBackground(){
var color:UIColor = .red
if(isCardRed){
color = .white
}
isCardRed = !isCardRed
UIView.animate(withDuration: 0.3) {
self.cardButton.backgroundColor = color
}
}
TableviewCells are reused you need to add prepareForReuse Method like :
override func prepareForReuse() {
super.prepareForReuse()
self.cardButton.backgroundColor = defaultColor
}

Correct and incorrect answer in Swift

I'm making simple quiz app about countries in Europe, I have a map and three buttons below with names of countries, one of them is correct and of course two incorrect. I want to highlight incorrect (if user click incorrect button) button for red and correct for green, if user click correct button I want to highlight it for green and after maybe 5s come back to the same color that was at first. I know how to change button color but I don't know ho do that for 5s and come back to default color. How can I do that ? Below its code that I use to change button color
UIButtonOutlet.Backgroundcolor.Uicolor.green
But its default green, so I can't set my color.
You can try something like this. First declare one UIButton instance in your class and then scheduledTimer after setting backgroundColor of button for correct's and incorrect and store that button reference with button that you have created first.
var selectedButton = UIButton()
Now use this selectedButton when you are setting button's backgroundcolor.
btnOutlet.backgroundcolor = .green //For correct
btnOutlet.backgroundcolor = .red //For incorrect
self.selectedButton = btnOutlet
//Now scheduled the timer for 5.0 sec
Timer.scheduledTimer(timeInterval: 5.0, target: self, selector: #selector(setButtonBGBack), userInfo: nil, repeats: false)
Add the setButtonBGBack method in your class
func setButtonBGBack() {
self.selectedButton.backgroundcolor = .blue //Set to default here
self.selectedButton = UIButton()
}
Lets say you have your code for changing the color which is in the "changeColor" func:
var correctButton: UIButton
func changeColor() {
if correctButton.backgroundColor == .green {
correctButton.backgroundColor = .lightGray //back to original color
}
}
What this essentially does is changes your correct button color back to its default (whatever that may be) if it is green when the func is called.
Now to use this, we can do a little work inside of the IBAction that is connected to each of your buttons:
#IBAction func buttonClicked(sender: UIButton) {
if sender.titleLabel?.text == "Correct Answer" {
button.backgroundColor = .green
correctButton = button //set the correct button variable so the changeColor func can be used
let timer = Timer.init(timeInterval: 5, target: self, selector: #selector(changeColor), userInfo: nil, repeats: false)
} else if sender.titleLabel?.text == "False Answer 1" || sender.titleLabel?.text == "False Answer 2" {
button.backgroundColor = .red
}
}
So in this code, if you click the button that is the correct answer (you can identify this by tag or other means, but I just decided to use its text) then the color is set to green immediately, and then the correctButton variable is set, but then a timer is initiated that after five seconds will call your changeColor func and then change it back to its original color.
Hope this helps :)
Edit:
Of course, my method assumes that you are using the storyboard to create these buttons. If you are creating them programmatically, then NiravD's method will work better.

How can I implement the same code without using didSet?

I have implemented this code for setting images of the button to implement checkbox using didSet function.
But now I don't want to use didSet function.
Please suggest me other way to implement the same code without using didSet.
//changing image using didSet
didSet
{
if (self.isChecked == true)
{
self.setImage(checked, forState: .Normal)
}
else
{
self.setImage(unChecked, forState: .Normal)
}
}
You can use a UISwitch with custom images set in the storyboard, then you just read the value

Hide UIButton title

I have several UIButtons in a scrollview which I use in order to pass certain information. The information is saved in the title of each uibutton and when the button is clicked, it passes its title into the function.
All I want to do is hide the title of the button so you can not see the button. I have them overlaid over images which I use to show buttons. I have the text set to transparent but it still turns white when it is being clicked.
If you include code in your explanation, please explain where it should go.
After IOS7, If you want to just hide the title on titleLabel of a button you can do as follow. This way the title is still there it just makes it invisible. if you do NSLog("%#",button.currentTitle) you will see the title in terminal. Hope this helps.
[button setTitle:#"Button Title" forState:UIControlStateNormal];
button.titleLabel.layer.opacity = 0.0f;
I found only one correct working way:
//hide
yourButton.setTitleColor(UIColor.clearColor(), forState: .Normal)
//show (put your color)
yourButton.setTitleColor(UIColor.blackColor(), forState: .Normal)
using button.titleLabel.hidden = YES will not work (at least on on iOS 7).
I ended up using:
// remove the button since hiding it doesn't work
[button.titleLabel removeFromSuperview];
// put back when you're done
[button addSubview:button.titleLabel];
You can hide the label inside the button:
button.titleLabel.hidden=YES;
or set the button's title to #"" and save the value somewhere else when you want to retrieve it.
I create a subclass of UIButton and override layoutSubviews method. Hiding titleLabel in layoutSubviews method works.
public class LoadingButton: UIButton {
public var isTitleHidden: Bool = false {
didSet {
titleLabel?.isHidden = isTitleHidden
}
}
public override func layoutSubviews() {
super.layoutSubviews()
titleLabel?.isHidden = isTitleHidden
}
}
if wanna hide titleLabel, just set isTitleHidden = true
I could not remove the title from the titleLabel nor the whole view as I needed it for constraints.
I ended up using
isEnabled = false
titleLabel?.layer.opacity = 0
setTitleColor(.clear, for: .disabled)
to hide the title and
isEnabled = true
titleLabel?.layer.opacity = 1
setTitleColor(titleColor(for: .normal), for: .disabled)
to show it again
To hide a title temporary just setTitle to empty string
setTitle("", for: .normal)
the button title label will be hidden but the title will still in the titleLabel, you can return it back using
setTitle(titleLabel?.text, for: .normal)
If you want to temporary hide the title, while you disabling the button, use:
setTitle("Title", for: .normal)
setTitle("", for: .disabled)
Then, button.isEnabled = false, when you want to hide the title.
I got a problem with title, because used an attributed title and nothing above helped. Then i found a workaround:
button.titleEdgeInsets = .init(top: 0, left: shouldHide ? 1000 : 0, bottom: 0, right: 0)
However it has some disadvantages, but fit my needs.
I've come up with this solution, which allows you to set title label text and use it with button image without showing it and not moving button image to the left.
- (void)hideButtonLabel:(UIButton*)buttonInp {
buttonInp.titleLabel.layer.opacity = 0.0f;
uttonInp.titleLabel.font = [UIFont fontWithName:#"Helvetica-Light" size:0.0];
}
You cannot hide UIButton titleLabel using .hidden property. Instead you can do this.
To Hide:
[self.yourButton setTitle:nil forState:UIControlStateNormal];
To Show:
[self.yourButton setTitle:#"Your Text" forState:UIControlStateNormal];
In Swift-
You don't need to hide nor need to make the opacity to 0.0. Swift gave you a simpler way.
Just set the title as nil. In fact, I got the idea from the documentation.
Command click on the setTitle(_:for:) method and you will see-
open func setTitle(_ title: String?, for state: UIControl.State) // default is nil. title is assumed to be single line
So, I just set it to nil.
setTitle(nil, for: .normal)
Swift 5 to hide button label:
myButton.titleLabel?.isHidden = true
Here myButton is a #IBOutlet of the button.