Why doesn't my UILabel change when I press the button? - swift

By pressing a button in my app, the value of a variable falls by 3. While this happens without any issues, the label which uses string interpolation to show that variable as its text (label.text) does not reflect the change.
How can I make it so pressing the button changes the value of the UILabel?
import UIKit
class ViewController: UIViewController {
var token = 5
let theButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("button", for: .normal)
button.backgroundColor = .systemPink
button.addTarget(self, action: #selector(theButtonPressed), for: .touchUpInside)
button.translatesAutoresizingMaskIntoConstraints = false
return button
}()
#objc func theButtonPressed() {
if token >= 3 {
token -= 3
print("ok done")
} else {
print("nope")
}
}
lazy var tokenLabel: UILabel = {
let label = UILabel()
label.text = "\(token)"
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .systemBlue
view.addSubview(tokenLabel)
view.addSubview(theButton)
theButton.heightAnchor.constraint(equalToConstant: 100).isActive = true
theButton.widthAnchor.constraint(equalToConstant: 200).isActive = true
theButton.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
theButton.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
tokenLabel.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: 60).isActive = true
tokenLabel.heightAnchor.constraint(equalToConstant: 300).isActive = true
tokenLabel.widthAnchor.constraint(equalToConstant: 200).isActive = true
tokenLabel.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
}
}

You need to update the label's text when the button is pressed.
#objc func theButtonPressed() {
if token >= 3 {
token -= 3
print("ok done")
tokenLabel.text = "\(token)" // <- update
} else {
print("nope")
}
}
Or, you can observe the property token and change the label when a new value is set.
var token = 5 {
didSet {
tokenLabel.text = "\(token)"
}
}
#objc func theButtonPressed() {
if token >= 3 {
token -= 3
print("ok done")
} else {
print("nope")
}
}

Related

How to make animated cell expansion?

I have cell with UILabel and Button. For the first time label have three rows.
When I tap on the button, number of lines increase and my cell change size, but without animation. how I can correct it?
My code inside cell:
func buttonTap() {
if textIsHide == true {
descriptionLabel.numberOfLines = 100
textIsHide = false
button.setTitle(.localized(for: "posters_postercard_hide"), for: .normal)
} else {
descriptionLabel.numberOfLines = 3
textIsHide = true
button.setTitle(.localized(for: "posters_postercard_showmore"), for: .normal)
}
delegate?.reloadRows()
descriptionLabel.layoutIfNeeded()
}
And this is my UIView, where I update my table:
extension PosterCardView: PosterCardDataManagerDelegate {
func reloadRows() {
tableView.beginUpdates()
tableView.endUpdates()
}
func buttonTap() {
if textIsHide == true {
withAnimation {
descriptionLabel.numberOfLines = 100
textIsHide = false
button.setTitle(.localized(for: "posters_postercard_hide"), for: .normal)
}
} else {
withAnimation{
descriptionLabel.numberOfLines = 3
textIsHide = true
button.setTitle(.localized(for: "posters_postercard_showmore"), for: .normal)
}
}
delegate?.reloadRows()
descriptionLabel.layoutIfNeeded()
}
have you ever tried with an animation?

Save with UserDefaults that checkbox is check or uncheck swift

I solved the problem
override func viewDidLoad() {
super.viewDidLoad()
let save = UserDefaults.standard.bool(forKey: "RememberMe")
self.circleBox.isChecked = save
}
#objc func checkboxvalue(sender: Checkbox) {
if sender.isChecked == true {
labelcheckbox.text = ("Beni")
action((Any).self)
UserDefaults.standard.set(true, forKey:"RememberMe");
}else{
labelcheckbox.text = ("")
UserDefaults.standard.set(false, forKey:"RememberMe");
}
}
I've designed a recall checkbox. But when I log out of the application, I want the checkbox value to be set to UserDefaults as true or false. So I want the checkbox to remember true or false when I get into the application.
lazy var circleBox: Checkbox = {
let squareBox = Checkbox(frame: CGRect(x: 22, y: 290, width: 25, height: 25))
squareBox.tintColor = .black
squareBox.borderStyle = .square
squareBox.checkmarkStyle = .square
squareBox.uncheckedBorderColor = .lightGray
squareBox.borderWidth = 1
squareBox.addTarget(self, action: #selector(checkboxvalue(sender:)), for: .valueChanged)
return squareBox
}()
#objc func checkboxvalue(sender: Checkbox) {
if sender.isChecked == true {
labelcheckbox.text = ("Remember me")
action((Any).self)
}else{
labelcheckbox.text = ("Don't remember")
}
}

Square UIImageView and UITextField in UITableViewCell

I'm trying to create a cell that contains a square UIImageView and a UITextField. If the text fits the width of the screen, then everything works fine. But as soon as I change the text to a longer one, the presentation breaks down. There are no messages in the console about the correctness of the constraints.
When the text in the UITextField fits on the screen or UITextField contains only placeholder everything works fine.
But if the text is long enough, the presentation breaks down.
The code with which I create the view:
extension TextFieldWithImageTVCell {
private func initView() {
selectionStyle = .none
initImgView()
initTextField()
contentView.addSubview(imgView)
contentView.addSubview(textField)
// debug code
imgView.backgroundColor = UIColor.black
textField.backgroundColor = UIColor.blue
}
private func initImgView() {
imgView = UIImageView(frame: CGRect.zero)
imgView.translatesAutoresizingMaskIntoConstraints = false
}
private func initTextField() {
textField = UITextField(frame: CGRect.zero)
textField.translatesAutoresizingMaskIntoConstraints = false
textField.isUserInteractionEnabled = false
}
}
The code with which I create constraints:
extension TextFieldWithImageTVCell {
private func initConstraints() {
initConstraintsImgView()
initConstraintsTextField()
}
private func initConstraintsImgView() {
imgView.heightAnchor.constraint(equalTo: imgView.widthAnchor).isActive = true
let margins = contentView.layoutMarginsGuide
imgView.leadingAnchor.constraint(equalTo: margins.leadingAnchor).isActive = true
imgView.topAnchor.constraint(equalTo: margins.topAnchor).isActive = true
imgView.bottomAnchor.constraint(equalTo: margins.bottomAnchor).isActive = true
}
private func initConstraintsTextField() {
textField.leadingAnchor.constraint(equalTo: imgView.trailingAnchor, constant: 8).isActive = true
let margins = contentView.layoutMarginsGuide
textField.topAnchor.constraint(equalTo: margins.topAnchor).isActive = true
textField.trailingAnchor.constraint(equalTo: margins.trailingAnchor).isActive = true
textField.bottomAnchor.constraint(equalTo: margins.bottomAnchor).isActive = true
}
}
The part of code with which I configure cell:
cell.textContent = subject
cell.placeholder = "Предмет"
cell.isEditingEnabled = true
guard let textField = cell.textField else {
assertionFailure("error in ItemSubject::configureCellForRow")
return
}
textField.delegate = self
textField.clearButtonMode = .always
textField.adjustsFontSizeToFitWidth = true
textField.minimumFontSize = 10
Cell properties:
extension TextFieldWithImageTVCell {
var placeholder: String? {
set { textField.placeholder = newValue }
get { return textField.placeholder }
}
var textContent: String? {
set { textField.text = newValue }
get { return textField.text }
}
var isEditingEnabled: Bool {
set { textField.isUserInteractionEnabled = newValue }
get { return textField.isUserInteractionEnabled }
}
}
What constraints do I need to add to achieve the desired result?
Why are my constraints not enough?

What conditional logic can be used for subclassed booleans in Swift?

I'm subclassing a UITextfield in order to create a overlay button to the right which will toggle the isSecureTextEntry boolean. Typically when creating IBActions in storyboard the boolean is determined based on the sender which I'd implement in Objective-C code like this:
-(IBAction)showPasswordTapped:(UIButton *)sender{
sender.selected = !sender.selected;
self.passwordField.secureTextEntry = !sender.selected;
}
However, now that I'm subclassing I was thinking of using an if else statement but the logic looked as if it would just set the boolean back to true. What would be the appropriate conditional statement if I don't have access to sender?
Here is my subclass in Swift:
class SecurePasswordUITextField : UITextField {
override func awakeFromNib() {
super.awakeFromNib()
self.isSecureTextEntry = true
var overlayButton = UIButton.init(type: UIButtonType.custom)
overlayButton.titleLabel = "Show"
overlayButton.addTarget(self, action: #selector(showSecureCharacters), for: .touchUpInside)
overlayButton = CGRect.init(x: self.bounds.origin.x, y: self.bounds.origin.y, width: 28, height: 28)
self.rightView = overlayButton
self.rightViewMode = UITextFieldViewMode.always
}
func showSecureCharacters(){
if self.isSecureTextEntry {
self.isSecureTextEntry = false
} else {
self.isSecureTextEntry = true
}
if !self.isSecureTextEntry{
self.isSecureTextEntry = true
} else {
self.isSecureTextEntry = false
}
}
}
You can access the sender
overlayButton.addTarget(self, action: #selector(showSecureCharacters(_:)), for: .touchUpInside)
//
#objc func showSecureCharacters(_ sender:UIButton){ --- }
Also this is sufficient
self.isSecureTextEntry = !self.isSecureTextEntry

swift - change label in header when UI Switch changes in the Navigation Bar

I want to change the label in my header to correlate with my UISwitch
though I have have no success as yet?
setLeftNavButton() is called in viewDidLoad()
func setLeftNavButton() {
let switchControl=UISwitch()
//switchControl.isOn = true
//switchControl.setOn(true, animated: false)
switchControl.addTarget(self, action: #selector(switchValueDidChange), for: .valueChanged)
self.navigationItem.leftBarButtonItem = UIBarButtonItem.init(customView: switchControl)
self.switchControl = switchControl
}
var switchControl: UISwitch?
func switchValueDidChange(){
guard let mySwitch = switchControl else { return }
if mySwitch.isOn {
header?.onlineOfflineStatusLabel.text = "on"
}
else {
header?.onlineOfflineStatusLabel.text = "off"
}
self.header?.reloadInputViews()
self.collectionView?.reloadData()
}
try this:
func setLeftNavButton() {
let switchControl = UISwitch()
switchControl.addTarget(self, action: #selector(switchValueDidChange(_:)), for: .valueChanged)
self.navigationItem.leftBarButtonItem = UIBarButtonItem.init(customView: switchControl)
self.switchControl = switchControl
}
#objc
func switchValueDidChange(_ sender: UISwitch){
if sender.isOn {
header?.onlineOfflineStatusLabel.text = "on"
} else {
header?.onlineOfflineStatusLabel.text = "off"
}
self.header?.reloadInputViews()
self.collectionView?.reloadData()
}