Swift - Hide & Show Object - ios

When I press the button hide to my text, after I press button to show my text. Where is my fault? My English very bad, sorry...
#IBOutlet weak var myHiddenText: UILabel!
#IBAction func showBtn(sender: AnyObject) {
myHiddenText.hidden = true
if myHiddenText.hidden == true {
myHiddenText.hidden = false
}
if myHiddenText.hidden == false {
myHiddenText.hidden = true
}
}

If you want the button to toggle the hidden property of the label, simply do this:
#IBAction func showBtn(sender: AnyObject) {
myHiddenText.hidden = !myHiddenText.hidden
}
Your main issue was this line:
myHiddenText.hidden = true
This was hiding the label every time then your if statement would always be true and show your label. Then the second if statement would be true and hide the label again.
So another option to fix your code would be:
#IBAction func showBtn(sender: AnyObject) {
if myHiddenText.hidden == true {
myHiddenText.hidden = false
} else {
myHiddenText.hidden = true
}
}

I know this may not help you but it may help someone else. If you want to hide multiple objects you could do this.
Step 1: Reference all the objects you want to hide with #IBOutlet
Step 2: Declare this variable
var buttons_are_hidden: Bool = false
Step 3: Put this code where you need it
if self.buttons_are_hidden == true {
self.first_object.isHidden = true
self.second_object.isHidden = true
self.third_object.isHidden = true
self.buttons_are_hidden = true
} else {
self.first_object.isHidden = true
self.second_object.isHidden = true
self.third_object.isHidden = true
self.buttons_are_hidden = true
}
Hope it helps someone!

With UIKitPlus library you can do it simply like this
class MyViewController: ViewController {
#State var hiddency = false
override func buildUI() {
super.buildUI()
body {
VStack {
View().height(10).background(.red).hidden($hiddency)
View().height(10).background(.green).hidden($hiddency)
View().height(10).background(.blue).hidden($hiddency)
Button("toggle").onTapGesture {
self.hiddency.toggle()
}
}
}
}
}
Take a look at it, it works since iOS9+ and have LivePreview.

Related

How to create OTP verification screen and detect delete backward on multiple uitextfield is Swift

so i make this otp screen but i have some catch,
i make this otp screen with bunch of uitextfield and i make the logic of it, but i just cant delete on of the num in the textfield that i make
the textfield wont delete when i fill like the first 2 of my num, even i pressess backButton it wont work.....but it will work when i fill the whole num of textfield, in my case is six.
so i have to fill all six of the number and i can delete the number from the textfield, it wont work if only half fill in the textfield.
heres my code :
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
if ((textField.text?.count)! < 1) && (string.count > 0) {
if textField == txtOTP1 {
txtOTP2.becomeFirstResponder()
}
if textField == txtOTP2 {
txtOTP3.becomeFirstResponder()
}
if textField == txtOTP3 {
txtOTP4.becomeFirstResponder()
}
if textField == txtOTP4 {
txtOTP5.becomeFirstResponder()
}
if textField == txtOTP5{
txtOTP6.becomeFirstResponder()
}
if textField == txtOTP6{
txtOTP6.resignFirstResponder()
}
textField.text = string
return false
}else if ((textField.text?.count)! >= 1) && (string.count == 0) {
if textField == txtOTP2{
txtOTP1.becomeFirstResponder()
}
if textField == txtOTP3{
txtOTP2.becomeFirstResponder()
}
if textField == txtOTP4{
txtOTP3.becomeFirstResponder()
}
if textField == txtOTP5{
txtOTP4.becomeFirstResponder()
}
if textField == txtOTP6{
txtOTP5.becomeFirstResponder()
}
if textField == txtOTP1{
txtOTP1.resignFirstResponder()
}
textField.text = ""
return false
}
else if (textField.text?.count)! >= 1 {
textField.text = string
return false
}
return true
}
thats the code i use to make the otp uitextField logic......please tell me i know theres something wrong with my logic, thanks.
i watch a tutorial to make this otp screen in this vid
https://www.youtube.com/watch?v=gZnBXh0TRO8
and according to the maker, he said that to fix this issue i just need to "set user interactions for textfield false and make first textfield first responder", i think i just did that but i maybe i did it wrong....
i really need to fix this guys, thanks.
Instead of fixing that code I prefer to create a custom text field that would inform when the deleteBackward key is pressed. So first subclass a UITextField:
import UIKit
class SingleDigitField: UITextField {
// create a boolean property to hold the deleteBackward info
var pressedDelete = false
// customize the text field as you wish
override func willMove(toSuperview newSuperview: UIView?) {
keyboardType = .numberPad
textAlignment = .center
backgroundColor = .blue
isSecureTextEntry = true
isUserInteractionEnabled = false
}
// hide cursor
override func caretRect(for position: UITextPosition) -> CGRect { .zero }
// hide selection
override func selectionRects(for range: UITextRange) -> [UITextSelectionRect] { [] }
// disable copy paste
override func canPerformAction(_ action: Selector, withSender sender: Any?) -> Bool { false }
// override deleteBackward method, set the property value to true and send an action for editingChanged
override func deleteBackward() {
pressedDelete = true
sendActions(for: .editingChanged)
}
}
Now in your ViewCOntroller:
import UIKit
class ViewController: UIViewController {
// connect the textfields outlets
#IBOutlet weak var firstDigitField: SingleDigitField!
#IBOutlet weak var secondDigitField: SingleDigitField!
#IBOutlet weak var thirdDigitField: SingleDigitField!
#IBOutlet weak var fourthDigitField: SingleDigitField!
override func viewDidLoad() {
super.viewDidLoad()
// add a target for editing changed for each field
[firstDigitField,secondDigitField,thirdDigitField,fourthDigitField].forEach {
$0?.addTarget(self, action: #selector(editingChanged), for: .editingChanged)
}
// make the firsDigitField the first responder
firstDigitField.isUserInteractionEnabled = true
firstDigitField.becomeFirstResponder()
}
// here you control what happens to each change that occurs to the fields
#objc func editingChanged(_ textField: SingleDigitField) {
// check if the deleteBackwards key was pressed
if textField.pressedDelete {
// reset its state
textField.pressedDelete = false
// if the field has text empty its content
if textField.hasText {
textField.text = ""
} else {
// otherwise switch the field, resign the first responder and activate the previous field and empty its contents
switch textField {
case secondDigitField, thirdDigitField, fourthDigitField:
textField.resignFirstResponder()
textField.isUserInteractionEnabled = false
switch textField {
case secondDigitField:
firstDigitField.isUserInteractionEnabled = true
firstDigitField.becomeFirstResponder()
firstDigitField.text = ""
case thirdDigitField:
secondDigitField.isUserInteractionEnabled = true
secondDigitField.becomeFirstResponder()
secondDigitField.text = ""
case fourthDigitField:
thirdDigitField.isUserInteractionEnabled = true
thirdDigitField.becomeFirstResponder()
thirdDigitField.text = ""
default:
break
}
default: break
}
}
}
// make sure there is only one character and it is a number otherwise delete its contents
guard textField.text?.count == 1, textField.text?.last?.isWholeNumber == true else {
textField.text = ""
return
}
// switch the textField, resign the first responder and make the next field active
switch textField {
case firstDigitField, secondDigitField, thirdDigitField:
textField.resignFirstResponder()
textField.isUserInteractionEnabled = false
switch textField {
case firstDigitField:
secondDigitField.isUserInteractionEnabled = true
secondDigitField.becomeFirstResponder()
case secondDigitField:
thirdDigitField.isUserInteractionEnabled = true
thirdDigitField.becomeFirstResponder()
case thirdDigitField:
fourthDigitField.isUserInteractionEnabled = true
fourthDigitField.becomeFirstResponder()
default: break
}
case fourthDigitField:
fourthDigitField.resignFirstResponder()
default: break
}
}
}
Xcode 12 sample project

How to restrict button click

I have a VC like this
for the checkBoxes i have embedded UIButtons and i am changing their image on click. Here's my code
#IBOutlet weak var bestSellerButton: UIButton!
#IBOutlet weak var trendingButton: UIButton!
#IBOutlet weak var lowToHighButton: UIButton!
#IBOutlet weak var highToLowButton: UIButton!
var isBoxClicked = Bool()
func updateCheckImageOnClick(button: UIButton) {
if isBoxClicked == true {
isBoxClicked = false
button.setImage(UIImage.init(named: "checkmark"), for: UIControlState.normal)
}
else {
isBoxClicked = true
button.setImage(UIImage(), for: UIControlState.normal)
}
}
#IBAction func clickedBestSellerBtn(_ sender: Any) {
updateCheckImageOnClick(button: bestSellerButton)
}
#IBAction func clickedTrendingBtn(_ sender: Any) {
updateCheckImageOnClick(button: trendingButton)
}
likewise for the rest two. Now the check mark image is being set properly every time on click gets set and unset, but i want to restrict the user like if he clicks on best seller btn he's unable to choose the rest, likewise if he clicks trending he can't select any other. How would i do that?
Make the Other button disabled in particular scenario.
isUserInteractionEnabled = false
You could rename updateCheckImageOnClick(button: UIButton) to something generic in order to add some logic inside, like:
func update(button: UIButton) {
isBoxClicked = !isBoxClicked
button.setImage(isBoxClicked ? UIImage(named: "checkmark") : UIImage(), for: UIControlState.normal)
if button == bestSellerButton {
trendingButton.isEnabled = false
lowToHighButton.isEnabled = false
highToLowButton.isEnabled = false
} else if button == trendingButton {
bestSellerButton.isEnabled = false
lowToHighButton.isEnabled = false
highToLowButton.isEnabled = false
} else if button == highToLowButton {
trendingButton.isEnabled = false
lowToHighButton.isEnabled = false
bestSellerButton.isEnabled = false
} else {
bestSellerButton.isEnabled = false
trendingButton.isEnabled = false
highToLowButton.isEnabled = false
}
}
Usama I've implemented a simple button action for all those buttons which may accomplish your need. Here is the step by step implementation -
First, Declare these variables -
var buttonSelected:Bool = false
var selectedButton : UIButton?
Second, Add a single #IBAction for all buttons -
Third, Here is the action method -
#IBAction func btnSelection(_ sender: UIButton) {
if(buttonSelected){
if(selectedButton == sender){
buttonSelected = false
selectedButton = nil
sender.setImage(UIImage(), for: UIControlState.normal)
}
else{
// It's not the previously selected button
//Do your stuff
}
}
else{
buttonSelected = true
selectedButton = sender
sender.setImage(UIImage.init(named: "checkmark"), for: UIControlState.normal)
}
}
Hope it will help you to start with.

Have to press twice for Swift 3 button action

I have two radio buttons, each with it's own IBAction. The first performs flawlessly. The second has an if-else condition and doesn't respond to the first tap but then responds to each tap thereafter. From looking at similar questions, I have sense that the first tap is just evaluating my function before performing the action but I am unable to figure out a way to get the button to respond on the first tap.
#IBAction func radioSchedule(_ sender: Any) {
print(timePicker.isHidden)
if timePicker.isHidden == true {
timePicker.isHidden = false
hideButton.isHidden = true
timeView.isHidden = false
itemTypeField.text = "Schedule"
saveButton.isHidden = false
} else {
timePicker.isHidden = true
timeView.isHidden = true
}
}
My guess is your timePicker sits inside your timeView and timeView is initially hidden, but your timePicker is not, and that is what is causing your issue.
If so, you could probably fix this by just judging your if/else off of your timeView, and then you wouldn't even have to worry about setting the timePicker to hidden or not.
i.e.:
#IBAction func radioSchedule(_ sender: Any) {
print(timeView.isHidden)
if timeView.isHidden {
hideButton.isHidden = true
timeView.isHidden = false
itemTypeField.text = "Schedule"
saveButton.isHidden = false
} else {
timeView.isHidden = true
}
}
Looks like setting timepicker.ishidden is creating the problem modify your code something like this:-
#IBAction func radioSchedule(_ sender: Any) {
print(timePicker.isHidden)
//Here updating the isHidden property first. If its false then initially will set to true.
timePicker.isHidden = !timePicker.isHidden
if timePicker.isHidden == true {
hideButton.isHidden = true
timeView.isHidden = false
itemTypeField.text = "Schedule"
saveButton.isHidden = false
} else {
timeView.isHidden = true
}
}

Button with constraints inside PersonCell hides half of the button Swift

Created a button inside a personCell which either shows Follow / Unfollow.
I've added the following constraints to the button:
Align Center Y to: Superview
Height = 43
Trailing space to: Superview
With or without the constraints it still cuts of a side of the button.
If the button was supposed to display "follow" it would only show "ow"
Code for PersonCell
class PersonCell: UITableViewCell {
#IBOutlet weak var followButton: UIButton!
var isFollowing: Bool?
var user: PFUser?
{
didSet
{
self.configure()
}
}
override func awakeFromNib()
{
super.awakeFromNib()
self.isFollowing = false
self.followButton?.hidden = true
}
override func prepareForReuse()
{
super.prepareForReuse()
self.isFollowing = false
self.followButton?.hidden = true
self.textLabel?.text = ""
self.user = nil
}
func configure()
{
if let constUser = user
{
self.textLabel?.text = constUser.username
// are we following this person?
NetworkManager.sharedInstance.isFollowing(constUser, completionHandler: {
(isFollowing, error) -> () in
if let _ = error
{
// Alert the user, or otherwise modify the UI
}
else
{
self.isFollowing = isFollowing
if isFollowing == true
{
let image = UIImage(named: "UnfollowButton")
self.followButton?.setImage(image, forState: .Normal)
}
else
{
let image = UIImage(named: "FollowButton")
self.followButton?.setImage(image, forState: .Normal)
}
self.followButton?.hidden = false
}
})
}
}
#IBAction func didTapFollow(sender: UIButton)
{
self.followButton?.enabled = false
let newValue = !(self.isFollowing == true)
NetworkManager.sharedInstance.updateFollowValue(newValue, user: self.user!) { (error) -> () in
self.followButton?.enabled = true
let image = (newValue == true) ? UIImage(named: "UnfollowButton") : UIImage(named: "FollowButton")
self.followButton?.setImage(image, forState: .Normal)
self.isFollowing = newValue
}
}
}
Im not yet allowed to post images but see this if you need to view how it looks:
http://postimg.org/image/jnf47mnr1/
Thankx in advance!

hidesBarsOnTap - Navigation Bar hidden/displayed event?

I would like to set the background color of a view to black when the navigation bar is hidden, and to white when the navigation bar is displayed.
The property hidesBarsOnTap is set to true in viewDidLoad. This works fine:
navigationController?.hidesBarsOnTap = true
How can I be notified when the bars are hidden and displayed?
Sorry, I made a mistake. The following code does exactly what you want. If you have a toolbar, you can set it to hide as well.
class ViewController: UIViewController {
var hidden = false {
didSet {
if let nav = navigationController {
nav.setNavigationBarHidden(hidden, animated: true)
nav.setToolbarHidden(hidden, animated: true)
view.backgroundColor = hidden ? UIColor.blackColor() : UIColor.whiteColor()
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
let recognizer = UITapGestureRecognizer(target: self, action: "tap:")
view.addGestureRecognizer(recognizer)
}
func tap(recognizer: UITapGestureRecognizer) {
if recognizer.state == .Ended {
hidden = !hidden
}
}
}
since hidesBarsOnTap is of type boolean, we can easily use it to check and use it as option like in below example:
var set : Bool = navigationController?.hidesBarsOnTap //true or false
if (set){
//do what you want when set
}else{
//do what you want when it is not set
}

Resources