NavigationBarButton is not getting Hidden but hides when viewWillAppear method is called? - ios

func setupRightNavigationItems()
{
let menuButton = UIButton(type: .system)
menuButton.setImage(#imageLiteral(resourceName: "menu-white").withRenderingMode(.alwaysOriginal),for:.normal)
menuButton.contentMode = .scaleAspectFit
menuButton.frame = CGRect(x:0,y:0,width:25,height:25)
let playButton = UIButton(type: .system)
playButton.setImage(#imageLiteral(resourceName: "nowplaying32").withRenderingMode(.alwaysOriginal), for: .normal)
playButton.contentMode = .scaleAspectFit
playButton.frame = CGRect(x:0,y:0,width:25,height:25)
let nowPlaying = defaults.string(forKey: "NOWPLAYING")
if nowPlaying == "true"
{
playButton.isHidden = false
}
else
{
playButton.isHidden = true
}
menuButton.addTarget(self, action: #selector(menuButtonClicked), for: UIControlEvents.touchUpInside)
playButton.addTarget(self, action: #selector(notificationPlayButtonClicked), for: UIControlEvents.touchUpInside)
navigationItem.rightBarButtonItems = [UIBarButtonItem(customView:menuButton),UIBarButtonItem(customView:playButton)]
}
The button gets hide when i called this function i.e setupRightNavigationItems in viewWillAppear but it does not reflect the changes of button getting hide inside the view, when i call it from another function after checking the condition please help !.

When you want to hide
self.navigationItem.rightBarButtonItem = nil

You can do as below to hide and show a navigation button
Hide:
self.navigationItem.rightBarButtonItem?.tintColor = .clear
self.navigationItem.rightBarButtonItem?.isEnabled = false
Show:
self.navigationItem.rightBarButtonItem?.tintColor = yourbuttonTint color
self.navigationItem.rightBarButtonItem?.isEnabled = true

try to set nil first, then set the buttons to refresh view.
func setupRightNavigationItems() {
// here your rest code
// set nil here >>>
navigationItem.rightBarButtonItems = nil
navigationItem.rightBarButtonItems = [UIBarButtonItem(customView:menuButton),UIBarButtonItem(customView:playButton)]
}

Your code is working good. Just check your condition is correct or not.
class DemoVC: UIViewController {
var flag = "true"
override func viewDidLoad() {
super.viewDidLoad()
setupRightNavigationItems()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
flag = "false"
setupRightNavigationItems()
}
#IBAction func onBtnChange(_ sender : UIButton) {
flag = "true"
setupRightNavigationItems()
}
func setupRightNavigationItems()
{
print("called")
let menuButton = UIButton(type: .system)
menuButton.setImage(#imageLiteral(resourceName: "likesong").withRenderingMode(.alwaysOriginal),for:.normal)
menuButton.contentMode = .scaleAspectFit
menuButton.frame = CGRect(x:0,y:0,width:25,height:25)
let playButton = UIButton(type: .system)
playButton.setImage(#imageLiteral(resourceName: "likesong").withRenderingMode(.alwaysOriginal), for: .normal)
playButton.contentMode = .scaleAspectFit
playButton.frame = CGRect(x:0,y:0,width:25,height:25)
let nowPlaying = "true"//defaults.string(forKey: "NOWPLAYING")
if nowPlaying.lowercased() == flag.lowercased()
{
playButton.isHidden = true
}
else
{
playButton.isHidden = false
}
self.navigationItem.rightBarButtonItems = [UIBarButtonItem(customView:menuButton),UIBarButtonItem(customView:playButton)]
}
}
i'm calling this function from viewDidLoad and working good.i just added static condition for test.
On touchesBegan button get visible and on onBtnChange again get hidden.
Try this, Hope this work.

You are right it won't hide when called from function other than willAppear or didLoad , because both bar button items are already created. You can't simply hide it,
So before calling this function, remove rightBarButtonItem, Now every thing will be OK.
Try this,
#IBAction func hideNavigationBar(_ sender: UIButton) {
navigationItem.rightBarButtonItems = nil
setupRightNavigationItems()
}
Try This too
let nowPlaying = defaults.string(forKey: "NOWPLAYING")
if nowPlaying == "true"
{
navigationItem.rightBarButtonItems = [UIBarButtonItem(customView:menuButton),UIBarButtonItem(customView:playButton)]
}
else
{
navigationItem.rightBarButtonItems = [UIBarButtonItem(customView:menuButton)]
}
Result:

Related

How can a UIButton listen to changes to other Buttons, a change to a UILabel's text, and a change to a UITextView all at the same time

My vc contains:
-1 name textView
-1 label // for flavors
-2 radio buttons // yes and no
-1 nextButton
What I want to do is keep the nextButton disabled until the textView is filled out, the label's text value is changed from its initial title of "Pick a Flavor" to whatever flavor they pick, and 1 of the radio buttons are selected.
I know using a textView's textViewDidEndEditing() I can listen to changes on it after the user finishes editing disable or enable the nextButton.
func textViewDidEndEditing(_ textView: UITextView) {
handleTextInputChanged()
}
#objc func handleTextInputChanged() {
let isFormValid = nameTextView.text?.count ?? 0 > 0
if isFormValid {
nextButton.isEnabled = true
nextButton.backgroundColor = .red
} else {
nextButton.isEnabled = false
nextButton.backgroundColor = .lightgray
}
}
How would I additionally disable or enable the nextButton based on wether or not one of the radio buttons were selected and the label's text is changed in addition to checking the nameTextView has text inside of it?
FYI the label's text is initially set with "Pick a Flavor". I have a gesture recognizer hooked up to it and when its tapped a new vc with a tableView is presented. The user picks a flavor, a protocol sends it back to this vc and the label's text will change to whatever flavor was selected (eg the label's title would say "Butter Pecan" if chosen). The nextButton should be disabled as long as the label's title is still set to "Pick a Flavor".
code:
let flavorLabel: UILabel = {
let label = UILabel()
label.text = "Pick a Flavor"
label.isUserInteractionEnabled = true
return label
}()
let nameTextView: UITextView = {
let textView = UITextView()
return textView
}()
let noButton: DLRadioButton = {
let button = DLRadioButton(type: .custom)
button.setTitle("No", for: .normal)
button.setTitleColor(UIColor.lightGray, for: .normal)
button.addTarget(self, action: #selector(noButtonPressed), for: .touchUpInside)
return button
}()
let yesButton: DLRadioButton = {
let button = DLRadioButton(type: .custom)
button.setTitle("Yes", for: .normal)
button.setTitleColor(UIColor.lightGray, for: .normal)
button.addTarget(self, action: #selector(yesButtonPressed), for: .touchUpInside)
return button
}()
let nextButton: UIButton = {
let button = UIButton(type: .system)
button.setTitle("Next", for: .normal)
button.setTitleColor(UIColor.white, for: .normal)
button.isEnabled = false
button.backgroundColor = .lightGray
button.addTarget(self, action: #selector(nextButtonTapped), for: .touchUpInside)
return button
}()
var choice: Bool?
override func viewDidLoad() {
super.viewDidLoad()
flavorVC.delegate = self
}
func textViewDidEndEditing(_ textView: UITextView) {
handleTextInputChanged()
}
#objc func handleTextInputChanged() {
let isFormValid = nameTextView.text?.count ?? 0 > 0
if isFormValid {
nextButton.isEnabled = true
nextButton.backgroundColor = .red
} else {
nextButton.isEnabled = false
nextButton.backgroundColor = .lightgray
}
}
#objc fileprivate func noButtonPressed() {
choice = false
}
#objc fileprivate func yesButtonPressed() {
choice = true
}
// delegate method from FlavorController
func selectedFlavor(flavor: String) {
flavorLabel.text = flavor // eg. "Butter Pecan"
}
You need to create a function that check all like this
func checkAll() {
nextButto.isEnabled = flavorLabel.text != "Pick a Flavor" &&
nameTextField.text != "" &&
(noButton.someProerty != || yesButton.someProerty != )
}
and call it from textfield and button targets plus
var ob:NSKeyValueObservation?
ob = flavorLabel.observe(\.text,options:[.new], changeHandler: { [unowned self] _, change in
self.checkAll()
}
I left the radio checks because both of them are custom , so you should know what to check , btw you can set tag of selected to 1 inside the target method and check according to it or some other logic you want

UITapGestureRecognizer to hide and unhide the label data with swift4

I need UITapGestureRecognizer to both hide and unhide the value. User with single tap should hide the label value and with the single tap should unhide the label, is there any way I could perform this operation?
Now I have used tap and long-tap gesture to perform this operation. Below is my code,
let tab = UITapGestureRecognizer(target: self, action: #selector(availabelBalance))
tab.numberOfTapsRequired = 1
tab.cancelsTouchesInView = false
accountBalanceView.addGestureRecognizer(tab)
let tabTwo = UILongPressGestureRecognizer(target: self, action: #selector(availabelBalanceTwo))
accountBalanceView.addGestureRecognizer(tabTwo)
If you hide the label then you will not able to touch again that label as it is hidden now.
To hide a label you can you this trick.
When you tap on label then you can check that...
var tempText = "" //temperory property to store value or label
#objc func tapDetected(_ sender: UITapGestureRecognizer) {
if let text = label.text, !text.isEmpty {
tempText = lbl.text.text
label.text = " "
} else {
label.text = tempText
}
}
You only need tapGesture
let tab = UITapGestureRecognizer(target: self, action: #selector(availabelBalance(_:)))
tab.numberOfTapsRequired = 1
tab.cancelsTouchesInView = false
accountBalanceView.addGestureRecognizer(tab)
//
#objc func availabelBalance(_ sender:UITapGestureRecognizer) {
if lbl.text == "" {
lbl.text = value
}
else {
lbl.text = ""
}
}
Here is sample code
import UIKit
class firstViewController: UIViewController {
#IBOutlet var textLbl: UILabel!
var tab : UITapGestureRecognizer?
override func viewDidLoad() {
super.viewDidLoad()
tab = UITapGestureRecognizer(target: self, action: #selector(availabelBalance))
tab?.numberOfTapsRequired = 1
tab?.cancelsTouchesInView = false
self.view.addGestureRecognizer(tab!)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#objc func availabelBalance(_ sender:UITapGestureRecognizer) {
if (tab?.cancelsTouchesInView)! {
textLbl.isHidden = true
tab?.cancelsTouchesInView = false
}else{
textLbl.isHidden = false
tab?.cancelsTouchesInView = true
}
}
}

UIButton addTarget Selector is not working

SquareBox.swift
class SquareBox {
func createBoxes() {
for _ in 0..<xy {
let button = UIButton()
button.backgroundColor = .white
button.setTitleColor(UIColor.black, for: .normal)
button.layer.borderWidth = 0.5
button.layer.borderColor = UIColor.black.cgColor
stack.addArrangedSubview(button)
button.addTarget(self, action: #selector(click(sender:)) , for: .touchUpInside)
}
}
#objc func click(sender : UIButton) {
print("Click")
}
}
ViewController.swift
class GameViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let boxRow = SquareBox()
boxRow.createBoxes()
}
}
Also I've tried #IBAction instead of #objc, it doesn't work, but if I use "click" function in ViewController.swift that I created this object, it's working but I need this function inside of this class.
Now that you have posted relevant information in your question, the problem is quite clear. You have a memory management issue.
In your GameViewController's viewDidLoad you create a local instance of SquareBox. This local instance goes out of scope at the end of viewDidLoad. Since there is no other reference to this instance, it gets deallocated at the end of viewDidLoad.
Since the instance of SquareBox has been deallocated, it is not around to act as the button's target. And your click method is never called.
The solution is to keep a reference in your view controller:
class GameViewController: UIViewController {
let boxRow = SquareBox()
override func viewDidLoad() {
super.viewDidLoad()
boxRow.createBoxes()
}
}
var btnfirst:UIButton!
override func viewDidLoad()
{
super.viewDidLoad()
btnfirst = UIButton(type: .system)
btnfirst.setTitle("Press", for: .normal)
btnfirst.setTitleColor(.red, for: .normal)
btnfirst.frame = CGRect(x: 100, y: 200, width: 100, height: 30)
btnfirst.addTarget(self, action: #selector(benpress( sender:)),for: .touchUpInside)
self.view.addSubview(btnfirst)
}
func benpress( sender :UIButton)
{
//Your Code Here
}
For those who did not find a solution, here is mine.
If you constructed your UIButton as
let button: UIButton = {
return UIButton()
}()
Just convert those into
lazy var button: UIButton = {
return UIButton()
}()
I think this is because of somewhat deallocation as mentioned above.
button.addTarget(self, action:#selector(self.click), for: .touchUpInside)
func click(sender : UIButton) {
// code here
}
I guess the issue is how you are setting up layout of your buttons.
Try this:
func createBoxes() {
stack.backgroundColor = UIColor.red
for _ in 0..<xy {
// Create the button
let button = UIButton()
button.backgroundColor = UIColor.red
// Add constraints
button.translatesAutoresizingMaskIntoConstraints = false
button.heightAnchor.constraint(equalToConstant: 44.0).isActive = true
button.widthAnchor.constraint(equalToConstant: 44.0).isActive = true
// Setup the button action
button.addTarget(self, action: #selector(SquareBox.click(sender:)), for: .touchUpInside)
// Add the button to the stack
stack.addArrangedSubview(button)
}
}
#objc func click(sender : UIButton) {
print("Click")
}
button.addTarget(self, action: #selector(self.buttonTapped), for: .touchUpInside)
func buttonTapped(sender : UIButton) {
// code here
}
Replace with this :
btn.addTarget(self, action: #selector(self.click(sender:)), for: .touchUpInside)
I think something else effect to your selector method try to find in your code because your code also working in my project.

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.
}
}

How to toggle a UITextField secure text entry (hide password) in Swift?

I currently have a UITextfield with an eye icon in it that when pressed is supposed to toggle the secure text entry on and off.
I know you can check mark the "secure text entry" box in the attributes inspector but how to do it so it toggles whenever the icon is pressed?
Use this code,
iconClick is bool variable, or you need other condition check it,
var iconClick = true
eye Action method:
#IBAction func iconAction(sender: AnyObject) {
if iconClick {
passwordTF.secureTextEntry = false
} else {
passwordTF.secureTextEntry = true
}
iconClick = !iconClick
}
hope its helpful
An unintended side-effect of this is that if the user toggles to insecure, and then back to secure, the existing text will be cleared if the user continues typing. The cursor may also end up in the wrong position unless we reset the selected text range.
Below is an implementation that handles these cases (Swift 4)
extension UITextField {
func togglePasswordVisibility() {
isSecureTextEntry = !isSecureTextEntry
if let existingText = text, isSecureTextEntry {
/* When toggling to secure text, all text will be purged if the user
continues typing unless we intervene. This is prevented by first
deleting the existing text and then recovering the original text. */
deleteBackward()
if let textRange = textRange(from: beginningOfDocument, to: endOfDocument) {
replace(textRange, withText: existingText)
}
}
/* Reset the selected text range since the cursor can end up in the wrong
position after a toggle because the text might vary in width */
if let existingSelectedTextRange = selectedTextRange {
selectedTextRange = nil
selectedTextRange = existingSelectedTextRange
}
}
}
This snippet is using the replace(_:withText:) function because it triggers the .editingChanged event, which happens to be useful in my application. Just setting text = existingText should be fine as well.
Why to use an extra var. In the action method of the eye button just do as below
password.secureTextEntry = !password.secureTextEntry
UPDATE
Swift 4.2 (as per #ROC comment)
password.isSecureTextEntry.toggle()
I wrote extension for the same. To provide Password toggle.
In your Assets first add images that you want for toggle.
Add following extension for UITextField.
extension UITextField {
fileprivate func setPasswordToggleImage(_ button: UIButton) {
if(isSecureTextEntry){
button.setImage(UIImage(named: "ic_password_visible"), for: .normal)
}else{
button.setImage(UIImage(named: "ic_password_invisible"), for: .normal)
}
}
func enablePasswordToggle(){
let button = UIButton(type: .custom)
setPasswordToggleImage(button)
button.imageEdgeInsets = UIEdgeInsets(top: 0, left: -16, bottom: 0, right: 0)
button.frame = CGRect(x: CGFloat(self.frame.size.width - 25), y: CGFloat(5), width: CGFloat(25), height: CGFloat(25))
button.addTarget(self, action: #selector(self.togglePasswordView), for: .touchUpInside)
self.rightView = button
self.rightViewMode = .always
}
#IBAction func togglePasswordView(_ sender: Any) {
self.isSecureTextEntry = !self.isSecureTextEntry
setPasswordToggleImage(sender as! UIButton)
}
}
Call extension on your UITextField Outlet
override func viewDidLoad() {
super.viewDidLoad()
txtPassword.enablePasswordToggle()
txtConfirmPassword.enablePasswordToggle()
}
Swift 4 solution
You don't need extra if statement for simple toggle isSecureTextEntry property
func togglePasswordVisibility() {
password.isSecureTextEntry = !password.isSecureTextEntry
}
But there is a problem when you toggle isSecureTextEntry UITextField doesn't recalculate text width and we have extra space to the right of the text. To avoid this you should replace text this way
func togglePasswordVisibility() {
password.isSecureTextEntry = !password.isSecureTextEntry
if let textRange = password.textRange(from: password.beginningOfDocument, to: password.endOfDocument) {
password.replace(textRange, withText: password.text!)
}
}
UPDATE
Swift 4.2
Instead of
password.isSecureTextEntry = !password.isSecureTextEntry
you can do this
password.isSecureTextEntry.toggle()
Use UITextFiled rightView to show toggle button
var rightButton = UIButton(type: .custom)
rightButton.frame = CGRect(x:0, y:0, width:30, height:30)
yourtextfield.rightViewMode = .always
yourtextfield.rightView = rightButton
If you need TextField with similar feature in multiple places its best to subclass the UITextField like follwing example -
import UIKit
class UIShowHideTextField: UITextField {
let rightButton = UIButton(type: .custom)
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
commonInit()
}
required override init(frame: CGRect) {
super.init(frame: frame)
commonInit()
}
func commonInit() {
rightButton.setImage(UIImage(named: "password_show") , for: .normal)
rightButton.addTarget(self, action: #selector(toggleShowHide), for: .touchUpInside)
rightButton.frame = CGRect(x:0, y:0, width:30, height:30)
rightViewMode = .always
rightView = rightButton
isSecureTextEntry = true
}
#objc
func toggleShowHide(button: UIButton) {
toggle()
}
func toggle() {
isSecureTextEntry = !isSecureTextEntry
if isSecureTextEntry {
rightButton.setImage(UIImage(named: "password_show") , for: .normal)
} else {
rightButton.setImage(UIImage(named: "password_hide") , for: .normal)
}
}
}
After which you can use it in any ViewController,
class ViewController: UIViewController {
#IBOutlet var textField: UIShowHideTextField!
override func viewDidLoad() {
super.viewDidLoad()
textField.becomeFirstResponder()
}
}
For Objective c
set image for RightButton In viewdidload Method
[RightButton setImage:[UIImage imageNamed:#"iconEyesOpen"] forState:UIControlStateNormal];
[RightButton setImage:[UIImage imageNamed:#"iconEyesClose"] forState:UIControlStateSelected];
and then set action method for that RightButton
-(IBAction)RightButton:(id)sender
{
if (_rightButton.selected)
{
_rightButton.selected = NO;
_passwordText.secureTextEntry = YES;
if (_passwordText.isFirstResponder) {
[_passwordText resignFirstResponder];
[_passwordText becomeFirstResponder];
}
}
else
{
_rightButton.selected = YES;
_passwordText.secureTextEntry = NO;
if (_passwordText.isFirstResponder) {
[_passwordText resignFirstResponder];
[_passwordText becomeFirstResponder];
}
}
}
Swift 3
// MARK: Btn EyeAction
#IBAction func btnEyeAction(_ sender: Any) {
if(iconClick == true) {
txtPassword.isSecureTextEntry = false
iconClick = false
} else {
txtPassword.isSecureTextEntry = true
iconClick = true
}
}
Shortest!
I think this is the shortest solution for secure entry as well as updating the picture of the button.
#IBAction func toggleSecureEntry(_ sender: UIButton) {
sender.isSelected = !sender.isSelected
textfieldPassword.isSecureTextEntry = !sender.isSelected
}
Assign the show/hide picture of the button according to the state selected /default , no need to create any variable or outlet.
This worked for me on Swift 5.0
#IBAction func changePasswordVisibility(_ sender: UIButton) {
passwordField.isSecureTextEntry.toggle()
if passwordField.isSecureTextEntry {
if let image = UIImage(systemName: "eye.fill") {
sender.setImage(image, for: .normal)
}
} else {
if let image = UIImage(systemName: "eye.slash.fill") {
sender.setImage(image, for: .normal)
}
}
}
Button attributes:
Result:
Swift 3
passwordTF.isSecureTextEntry = true
passwordTF.isSecureTextEntry = false
#IBAction func eye_toggle_clicked(sender: AnyObject)
{
if toggleBtn.tag == 0
{
passwordTxt.secureTextEntry=true
toggleBtn.tag=1
}
else
{
passwordTxt.secureTextEntry=false
toggleBtn.tag=0
}
}
As others have noted, the property is secureTextEntry, but you won't find this in the UITextField documentation, as it is actually inherited by a UITextField through the UITextInputTraits protocol- https://developer.apple.com/library/ios/documentation/UIKit/Reference/UITextInputTraits_Protocol/#//apple_ref/occ/intfp/UITextInputTraits/secureTextEntry
You can simply toggle this value each time your button is tapped:
#IBAction func togglePasswordSecurity(sender: UIButton) {
self.passwordField.secureTextEntry = !self.passwordField.secureTextEntry
}
try this line:
#IBAction func btnClick(sender: AnyObject) {
let btn : UIButton = sender as! UIButton
if btn.tag == 0{
btn.tag = 1
textFieldSecure.secureTextEntry = NO
}
else{
btn.tag = 0
textFieldSecure.secureTextEntry = NO;
}
}
Here is your answer no need to take any bool var:
#IBAction func showHideAction(sender: AnyObject) {
if tfPassword.secureTextEntry{
tfPassword.secureTextEntry = false
}else{
tfPassword.secureTextEntry = true;
}
}
First you need to set image(visible or hide) of button of eye for different state (selected or normal)
than connect IBAction and write code like
#IBAction func btnPasswordVisiblityClicked(_ sender: Any) {
(sender as! UIButton).isSelected = !(sender as! UIButton).isSelected
if (sender as! UIButton).isSelected {
txtfPassword.isSecureTextEntry = false
} else {
txtfPassword.isSecureTextEntry = true
}
}
In Swift 4
var iconClick : Bool!
override func viewDidLoad() {
super.viewDidLoad()
iconClick = true
}
#IBAction func showHideAction(_ sender: Any)
{
let userPassword = userPasswordTextFiled.text!;
if(iconClick == true) {
userPasswordTextFiled.isSecureTextEntry = false
iconClick = false
} else {
userPasswordTextFiled.isSecureTextEntry = true
iconClick = true
}
}
Assignment values change from YES/NO to true/false boolean values.
password.secureTextEntry = true //Visible
password.secureTextEntry = false //InVisible
You can try this code..
i think it's helpful.
Use button with eye image
and make buttonHandler method
set Tag for button with value 1
-(IBAction) buttonHandlerSecureText:(UIButton *)sender{
if(sender.tag ==1){
[self.textField setSecureTextEntry:NO];
sender.tag = 2;
}
else{
[self.textField setSecureTextEntry:YES];
sender.tag = 1;
}
}
For Xamarin folks:
passwordField.SecureTextEntry = passwordField.SecureTextEntry ? passwordField.SecureTextEntry = false : passwordField.SecureTextEntry = true;
Try this code in swift 4, tried to make a reusable code within a controller. I have set different image for buttons in storyboard as shown in the link https://stackoverflow.com/a/47669422/8334818
#IBAction func clickedShowPassword(_ sender: UIButton) {
var textField :UITextField? = nil
print("btn ",sender.isSelected.description)
switch sender {
case encryptOldPswdBtn:
encryptOldPswdBtn.isSelected = !encryptOldPswdBtn.isSelected
textField = oldPasswordTextField
default:
break
}
print("text ",textField?.isSecureTextEntry.description)
textField?.isSecureTextEntry = !(textField?.isSecureTextEntry ?? false)
}
#objc func togglePasscode(){
switch textfield.isSecureTextEntry{
case true:
textfield.isSecureTextEntry = false
case false:
textfield.isSecureTextEntry = true
}
}
Here is a easy and more readable solution using Switch statement.
Hope this is simpler solution rather than creating a BOOL object globally.
#IBAction func passwordToggleButton(sender: UIButton) {
let isSecureTextEntry = passwordTextField.isSecureTextEntry
passwordTextField.isSecureTextEntry = isSecureTextEntry ? false : true
if isSecureTextEntry {
visibilityButton.setImage(UIImage(named: "visibility"), for: .normal)
} else {
visibilityButton.setImage(UIImage(named: "visibility_off"), for: .normal)
}
}
only add this line into your code replace you TextField name with "textfield" Done:
you need to change the isSecureTextEntry propertity to change true for password type textFiled like ......
textField.isSecureTextEntry = true
sender.isSelected = !sender.isSelected
if(sender.isSelected == true) {
RegPasswordField.isSecureTextEntry = false
sender.setBackgroundImage(UIImage(systemName: "eye.fill"), for: .normal)
} else {
RegPasswordField.isSecureTextEntry = true
sender.setBackgroundImage(UIImage(systemName: "eye"), for: .normal)
}
Swift 5 Please use this
var btnClick = true
if(btnClick == true) {
passwordTextField.isSecureTextEntry = false
} else {
passwordTextField.isSecureTextEntry = true
}
btnClick = !btnClick
}
var viewingPassword = true
#IBAction func btnEyeAction(_ sender: Any) {
passwordTF.isSecureTextEntry = viewingPassword ? false : true
viewingPassword.toggle()
}

Resources