swift button hide/show not working - swift

I have the view.
When I click on the btnStartWork, I want to the button is set to hidden (worked) and the label startTime show the start time(worked) and the btnEndWork is showing (worked).
When I clicked on the btnEndWork I no button is hidden and btnEndWork is still showing. Also he set to the endTime Label the end time but update the startTime too. That is really wired.
class FirstViewController: UIViewController {
#IBOutlet weak var startTime: UILabel!
#IBOutlet weak var endTime: UILabel!
#IBOutlet weak var btnStartWorkLabel: UIButton!
#IBOutlet weak var btnEndWorkLabel: UIButton!
#IBAction func btnStartWork(_ sender: Any) {
let currentdate = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
let convertedDate = dateFormatter.string(from: currentdate)
startTime.text = "\(convertedDate)"
btnStartWorkLabel.isHidden = true
btnEndWorkLabel.isHidden = false
}
#IBAction func btnEndWork(_ sender: Any) {
let currentdate = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "HH:mm"
let convertedDate = dateFormatter.string(from: currentdate)
endTime.text = "\(convertedDate)"
btnStartWorkLabel.isHidden = false
btnEndWorkLabel.isHidden = true
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Update Question
How could I save the times, to work with both times, when the btnEndWork is clicked?

Sounds like it is wired wrong, look at the controller in interface builder for multiple connections (if you copy and paste a label or button the connection is copied too) and try adding:
print("Start button pressed")
to
#IBAction func btnStartWork(_ sender: Any)
and
print("End button pressed")
to
#IBAction func btnEndWork(_ sender: Any)
to see if the output is correct when you press the buttons.

Related

Why using this Swift code in Xcode doesn't work?

Have a problem in Swift. I would like to write a program for the school. For odd tails, A week should be displayed and for even days B week. The date can already read it. But if I always program an ee if condition I always get the error message String. I do not know how to transform it. Can anybody help me further?
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var Datum: UILabel!
#IBOutlet weak var Monat: UILabel!
#IBOutlet weak var Woche: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
let jetzt = Date()
let formatter = DateFormatter()
formatter.dateFormat = "d"
Datum.text = formatter.string(from: jetzt)
let jetzt2 = Date()
let formatter2 = DateFormatter()
formatter2.dateFormat = "M"
Monat.text = formatter2.string(from: jetzt2)
// Do any additional setup after loading the view, typically from a nib.
}
#IBAction func Check(_ sender: Any) {
if Datum.text = "3"
Woche.text = "A-Woche"
}
}
Try this
import UIKit
class ViewController: UIViewController {
#IBOutlet weak var Datum: UILabel!
#IBOutlet weak var Monat: UILabel!
#IBOutlet weak var Woche: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
let jetzt = Date()
let formatter = DateFormatter()
formatter.dateFormat = "d"
Datum.text = formatter.string(from: jetzt)
let jetzt2 = Date()
let formatter2 = DateFormatter()
formatter2.dateFormat = "M"
Monat.text = formatter2.string(from: jetzt2)
}
#IBAction func Check(_ sender: Any) {
if Datum.text == "3"{
Woche.text = "A-Woche"
} else {
Woche.text = "B-Woche"
}
}
}

How to change input textfiled [Swift]

In my swift app I've two textfields and as inputView is UIDatePicker().
Here's my code:
class ViewController: UIViewController {
#IBOutlet weak var textField1: UITextField!
#IBOutlet weak var textField2: UITextField!
var timePicker = UIDatePicker()
var timeString = String()
override func viewDidLoad() {
super.viewDidLoad()
timePicker.datePickerMode = .time
}
#objc func formatData(_ datePickerView: UIDatePicker) {
let timeFormatter = DateFormatter()
timeFormatter.timeStyle = .short
timeString = timeFormatter.string(from: datePickerView.date)
}
#IBAction func textFieldChanged(_ sender: UITextField) {
sender.inputView = timePicker
timePicker.addTarget(self, action: #selector(formatData(_:)), for: .valueChanged)
sender.text = timeString
}
}
By this way to change value into text field I've to deselect it and then rettapping on it the value appear.
But it's not correct.
first you take the IBAction of that textfield which you want to change the input view and name should be of your IBAction method didBeginEditing and in that method you can the input view of that textfield which you want to change

Open UIDatePicker when UITextField is tapped from Custom Component

I have a custom UIView component that has a UITextField, UIImageView and another UIView.
I need to change the behavior of the UITextField to display a UIDatePicker when it's tapped. This is the code I'm trying to execute but for some reason the datePicker doesn't open when it's tapped:
class TextFieldWithFeedback : UIView {
#IBOutlet weak var textField: UITextField!
#IBOutlet weak var imageView: UIImageView!
#IBOutlet weak var underlineView: UIView!
override func draw(_ rect: CGRect) {
let datePicker = UIDatePicker()
datePicker.datePickerMode = .date
self.textField.inputView = datePicker
}
}
When I used the same code on my ViewController (code below) it worked:
override func viewDidLoad() {
super.viewDidLoad()
let datePicker = UIDatePicker()
datePicker.datePickerMode = .date
customView.textField.inputView = datePicker
}
Now, this solution works but it's not ideal because I have 8 of those custom views and it would be better to set it once instead of 8 times.
Which method of the View class should I use to set the datePicker up? Since draw doesn't work.
Also, how can I attach a function to modify my UITextField value when the user picks a date?
Managed to solve it like this:
//To control whether or not to use the DatePicker, easily customized on the Storyboard
#IBInspectable var useDatePicker: Bool = false
#IBAction func textFieldEditing(_ sender: UITextField) {
self.textFieldStartedEditing(sender: sender)
}
func textFieldStartedEditing(sender: UITextField) {
if useDatePicker {
let datePickerView:UIDatePicker = UIDatePicker()
datePickerView.datePickerMode = .date
sender.inputView = datePickerView
datePickerView.addTarget(self, action: #selector(self.datePickerValueChanged), for: UIControlEvents.valueChanged)
}
}
func datePickerValueChanged(sender: UIDatePicker) {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd/MM/YYYY"
self.textField.text = dateFormatter.string(from: sender.date)
}
All of the code above inside my customView class.
If anyone else is having trouble with this and needs help feel free to comment, I promise I'll be more helpful than the people who commented on the question :)
what you need to do is addTarget to your Textfield and then in a method Show the UIPickerView
self.textField.addTarget(self, action: #selector(ViewController.openDatesPicker), for: .touchDown)
You should also set tag for your textfield so you can identify it later in the code. Also you should implement this method which stops the keyboard from showing up
func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
if textField.tag == 2 {
return true
} else {
return false
}
}

Transfer TextField data between ViewControllers

I have ViewController, which has a textfield and a button. The user enters his name into the textfield and hits the DONE button. When he hits the button, he is segued to GifteeDetails, which is a different view controller. There is a label in that viewController that is supposed to display his name. But, his name doesn't show up. I don't receive an error.
Here's ViewController:
#IBOutlet weak var textGifteeName: UITextField!
#IBAction func toDetails(_ sender: Any) {
performSegue(withIdentifier: "toDetails", sender: nil)
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
let destDetails: GifteeDetails = segue.destination as! GifteeDetails
destDetails.nametext = textGifteeName.text!
destDetails.agetext = "\(Int(age)! - 2000 + 17)"
destDetails.locationstext = labelGifteeLocationsPreview.text!
destDetails.intereststext = labelGifteeInterestsPreview.text!
}
Here's GifteeDetails:
var nametext = String()
var agetext = String()
var locationstext = String()
var intereststext = String()
#IBOutlet weak var labelGifteeName: UILabel!
#IBOutlet weak var labelGifteeAge: UILabel!
#IBOutlet weak var labelGifteeLocations: UILabel!
#IBOutlet weak var labelGifteeInterests: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
nametext = labelGifteeName.text!
agetext = labelGifteeAge.text!
locationstext = labelGifteeLocations.text!
intereststext = labelGifteeInterests.text!
}
Sorry about all the !. Swift gives me an error unless I have them.
You are updating the strings nametext and others, which are not connected to your labels.
You need to replace this piece of code:
destDetails.nametext = textGifteeName.text!
destDetails.agetext = "\(Int(age)! - 2000 + 17)"
destDetails.locationstext = labelGifteeLocationsPreview.text!
destDetails.intereststext = labelGifteeInterestsPreview.text!
With:
destDetails.labelGifteeName.text = textGifteeName.text!
destDetails.labelGifteeAge.text = "\(Int(age)! - 2000 + 17)"
destDetails.labelGifteeLocations.text = labelGifteeLocationsPreview.text!
destDetails. labelGifteeInterests.text = labelGifteeInterestsPreview.text!
nametext is a String object, and it is different from labelGifteeName.text which is the String of the label you want to update.
If you use segue then pls remove it, and then create action method of that button in the FirstviewController and use pushViewController to move on the SecondviewController.
Swift 3
Example:
#IBAction func toDetails(_ sender: Any)
{
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "SecondView") as! SecondView
UserDefaults.standard.set(self. textGifteeName.text, forKey: "savedStringKey")
UserDefaults.standard.synchronize()
self.navigationController?.pushViewController(vc,
animated: true)
}
In SecondView:
override func viewDidLoad() {
super.viewDidLoad()
self.labelGifteeName.text = UserDefaults.standard.string(forKey: "savedStringKey")!
}
Please Update your func viewDidLoad() method in GifteeDetailsVC with labelGifteeName.text! = nametext , labelGifteeAge.text!= agetext instead of your code because you have already assigned the value in to strings i.e, nametext and agetext in ViewController, you need to display string value in label

Swift datepicker in popovercontroller not updating the correct label

In my app i have added 2 labels and 2 buttons, the buttons are hooked to a function that pops a datepicker in popovercontroller, when user select a date the corresponding label should change.
Everything work except the labels are updated together, what I want is update only the relevant label, i.e. when when button1 is pressed label1 should recieve datepicker date and vice versa.
Here is my code:
import UIKit
class PopoverTestVC: UIViewController, UIPopoverPresentationControllerDelegate {
#IBOutlet weak var dateLabel: UILabel!
#IBOutlet weak var dateLabel2: UILabel!
#IBOutlet weak var selectButton: UIButton!
#IBOutlet weak var selectButton2: UIButton!
#IBOutlet var datePicker: UIDatePicker!
var dateString = ""
let vc = UIViewController()
override func viewDidLoad() {
super.viewDidLoad()
datePicker.timeZone = NSTimeZone(abbreviation: "GMT")
//datePicker.addTarget(self, action: Selector("datePicked:"), forControlEvents: UIControlEvents.ValueChanged)
}
func datePicked(sender: UIDatePicker) {
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd MMM yyyy HH:mm"
dateFormatter.timeZone = NSTimeZone(abbreviation: "GMT")
dateLabel.text = dateFormatter.stringFromDate(datePicker.date)
}
func datePicked2(sender: UIDatePicker) {
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "dd MMM yyyy HH:mm"
dateFormatter.timeZone = NSTimeZone(abbreviation: "GMT")
dateLabel2.text = dateFormatter.stringFromDate(datePicker.date)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func popUp(sender: UIButton)
{
let fr = datePicker.frame
vc.view.frame = fr
vc.view.addSubview(datePicker!)
vc.view.backgroundColor = UIColor.greenColor()
vc.preferredContentSize = datePicker.frame.size
vc.modalPresentationStyle = UIModalPresentationStyle.Popover
if sender == selectButton
{
datePicker.addTarget(self, action: Selector("datePicked:"), forControlEvents: UIControlEvents.ValueChanged)
}
else if sender == selectButton2
{
datePicker.addTarget(self, action: Selector("datePicked2:"), forControlEvents: UIControlEvents.ValueChanged)
}
let popOverPC = vc.popoverPresentationController
vc.popoverPresentationController?.sourceRect = sender.frame
vc.popoverPresentationController?.sourceView = view
popOverPC!.permittedArrowDirections = UIPopoverArrowDirection.Any
popOverPC!.delegate = self
presentViewController(vc, animated: true, completion: nil)
}
func adaptivePresentationStyleForPresentationController(controller: UIPresentationController) -> UIModalPresentationStyle
{
return UIModalPresentationStyle.None
}
}
Appreciate any help or suggestion to do that in better way as the app might have several outlets that use the same datepicker.
I'd move your date picker to a custom class (this also lets you use a xib to do some cool design stuff) call this from your view controller setting a var to the button that called the date picker. Create a protocol in the date picker and implement the delegate in the parent view controller populating whatever labels you require based on the button that called the date picker.
For example, in my app I have several text fields that must contain dates. When the user begins to edit the text field I launch a custom popover from textFieldShouldBeginEditing and assign the text field to a var.
The parent view controller is set as the delegate to a protocol in my custom date picker:
// MARK: - Textfield delegate
func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
textField.backgroundColor = UIColor.whiteColor()
if (textField.tag == 500 || textField.tag == 501)
{
activeTextField = textField
let vc = BGSDatePickerVC(nibName: "BGSDatePickerVC", bundle: nil)
vc.modalPresentationStyle = UIModalPresentationStyle.Popover
if textField.tag == 500{
vc.popoverPresentationController?.sourceView = viewMarkerFromDate
}else
{
vc.popoverPresentationController?.sourceView = viewMarkerToDate
}
vc.popoverPresentationController?.permittedArrowDirections = UIPopoverArrowDirection.Up
vc.preferredContentSize = CGSizeMake(vc.view.frame.width, vc.view.frame.height)
vc.delegate = self
self.presentViewController(vc, animated: true, completion: nil)
return false
}
return true
}
The protocol in my custom date picker popover:
protocol BGSDatePickerVCProtocol
{
func bgsDatePickerUse(date: NSDate, strDate: String)
}
class BGSDatePickerVC: UIViewController {
var delegate:BGSDatePickerVCProtocol! = nil
and the implementation in the calling view controller:
// MARK: - Delegates
// MARK: BGSDatePickerVCProtocol
func bgsDatePickerUse(date: NSDate, strDate: String)
{
if activeTextField.tag == 500
{
dateSelectedFrom = date
}
if activeTextField.tag == 501
{
dateSelectedTo = date
}
activeTextField.text = strDate
}