Error converting "Swift invokes UIDatePicker from UITextField" to swift3(2)

Asked 2 years ago, Updated 2 years ago, 119 views

The NSCalendar.Unit "dateToString Method Is Like This" code that you answered the other day shows the day of the week in the initial value of the text (GTM+9)."After further modification, I ran ""code like this"" to make the day of the week display more appropriate.In both cases, the simulator will start, but if you move the date picker to change the date, or tap the Finish button or today's button, the simulator will end with an error.
I recreated the text field on the storyboard and re-outputted it, or deleted it in connections inspector and re-attach it.I have reviewed the method name and tried it in my own way, but it has not improved.I'm sorry to trouble you, but could you tell me?Thank you.
Viewing Debugging Areas
2016-12....path is...Reading from private effective user settings.
2016-...- [...App.ViewController tappedToolBarBtn:]—unrecognized selector sent to instance...
*Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[...App.ViewController taggedToolBarBtn:]:unrecognized selector sent to instance...
*
First throw call stack:)
libc++abi.dylib:terminating with uncaught exception of type NSException

//ViewController.swift Code

import UIKit
classViewController:UIViewController, UIToolbarDelegate {    
@IBOutlet weak var textField: UITextField!
// var textField —UITextField!
var toolBar —UIToolbar!
var myDatePicker —UIDatePicker!

override func viewDidLoad(){
    super.viewDidLoad()        
    // Setting Up the Input field settings
    // textField=UITextField(frame:CGRectMake(self.view.frame.size.width/3,100,0,0))
    textField.placeholder=dateToString(date:(NSDate() as Date as NSDate) as Date)
    textField.text=dateToString(date:(NSDate() as Date as NSDate) as Date)
    // textField.sizeToFit()
    self.view.addSubview(textField)

    // Configuring UIDatePicker
    myDatePicker=UIDatePicker()
    myDatePicker.addTarget(self, action:Selector(("changedDateEvent:")), for:UIControlEvents.valueChanged)
    myDatePicker.datePickerMode=UIDatePickerMode.date
    textField.inputView=myDatePicker

    // Configuring UIToolBar     
    toolBar = UIToolbar (frame: CGRect (x:0, y:self.view.frame.size.height/6, width:self.view.frame.size.width, height:40.0))

    toolBar.layer.position = CGPoint (x:self.view.frame.size.width/2, y:self.view.frame.size.height-20.0)
    toolBar.barStyle=.blackTranslucent
    toolBar.tintColor=UIColor.white
    toolBar.backgroundColor=UIColor.black

    let toolBarBtn = UIBarButtonItem(title: "Completed", style: .plain, target:self, action:Selector(("tappedToolBarBtn:"))
    let toolBarBtnToday=UIBarButtonItem(title: "Today", style: .plain, target:self, action:Selector(("tappedToolBarBtnToday:"))        
    toolBarBtn.tag =1
    toolBar.items = [ toolBarBtn, toolBarBtnToday]        
    textField.inputAccessoryView=toolBar
}

override funcdidReceiveMemoryWarning(){
    super.didReceiveMemoryWarning()
}

// Press Finish to close
functappedToolBarBtn(sender:UIBarButtonItem){
    textField.resignFirstResponder()
}    
// Press "Today" to set today's date
functappedToolBarBtnToday(sender:UIBarButtonItem){
    myDatePicker.date = NSDate() as Date
    changeLabelDate(date:NSDate())
}
func changedDateEvent(sender:AnyObject?){        
funcdateToString (date:Date) - > String {
    // DateFormatter is a reference type, so let is appropriate
    let date_formatter=DateFormatter()
    // If you want to write a single character for the day of the week, you don't need an array of weekdays.

    date_formatter.locale=Locale(identifier: "ja")
    date_formatter.dateFormat="yyyyy MM month dd day (E)"//<-`E` is the format character for the day of the week output.
    return date_formatter.string (from:date as Date)
}

}

xcode swift3

2022-09-30 19:09

1 Answers

If you are writing questions related to previous questions, it is recommended that you include links to previous questions as "auxiliary information(Even in that case, it is preferable that it is completed as one question without looking at the link like this one.)

Also, your code this time is a copy error, so it's a little missing.

func changedDateEvent(sender:AnyObject?){        
funcdateToString (date:Date) - > String {

I have restored the following link from the article in the related question.

func changedDateEvent(sender:AnyObject?){

var dateSelector:UIDatePicker=sender as!UIDatePicker
    self.changeLabelDate(date:myDatePicker.date as NSDate)
}

funcchangeLabelDate(date:NSDate){
    textField.text=self.dateToString(date:date as Date)
}

func dateToString (date:Date)->String {

Now let's get down to the point.

The problem with your code is this part:

myDatePicker.addTarget(self, action:Selector(("changedDateEvent:"), for:UIControlEvents.valueChanged)
let toolBarBtn=UIBarButtonItem(title: "Completed", style: .plain, target:self, action: Selector("tappedToolBarBtn:") let toolBarBtnToday=UIBarButtonItem(title: "Today", style: .plain, target:self, action: Selector("tappedToolBarBtnToday:")

and this part:

functappedToolBarBtn(sender:UIBarButtonItem){
functappedToolBarBtnToday(sender:UIBarButtonItem){
funcchangedDateEvent(sender:AnyObject?){

This is due to inconsistent selectors and methods in and .

If it is consistent, it can work, so you can modify either of them, but both of them are not standard in Swift3, so let's fix both.

When describing the action method, it is better to make it compatible with Swift2.

functappedToolBarBtn(_sender:UIBarButtonItem){
functappedToolBarBtnToday(_sender:UIBarButtonItem){
funcchangedDateEvent(_sender:UIDatePicker){

Note that all three methods have sender preceded by an "underline" or "space".In Swift3, the language specification was modified so that all arguments in the method have an external name (parameter label) by default.Therefore, in order for the caller to be the same (including using a selector) as before Swift 2, _ must precede the leading argument and declare that this leading argument has no external name.

By the way, regarding the third method, we have also modified the argument type.This is part of Swift2 where sender is always an UIDatePicker instance in the action method from UIDatePicker, so it is not necessary to receive it in AnyObject and convert it to UIDatePicker in the cast.

The order has changed, but then you have to modify the selector notation to match the method above.The first thing I want you to remember is

Swift 2.2 and later should not use the selector notation (Selector((("changedDateEvent:")) using the initializer of Selector as much as possible

Yes. Be sure to use the #selector syntax.

*Think Swift's "double parentheses" candidate in the Suggestion is for experts who understand that they have no choice but to use Selector(...).

The #selector syntax for the above three action methods (of course modified) from the same class is as follows:

#selector(tappedToolBarBtn(_:))
#selector(tappedToolBarBtnToday(_:))
#selector(changedDateEvent(_:))

For your code, there is no ambiguity in each method, so you can also write in abbreviations as follows:

#selector(tappedToolBarBtn)
#selector(tappedToolBarBtnToday)
#selector(changedDateEvent)

逆 On the contrary, you may see that it is longer, but you don't have to force it to be longer.

By the way, the biggest benefit of using the #selector syntax is that if you specify a method that does not exist it will result in a compilation error.As in your case, unrecognized selector sent to instance for the first time in a run, which greatly reduces the likelihood of encountering an error.

If you modify other parts of the cast that are useless, your code will look like this:

class ViewController:UIViewController, UIToolbarDelegate{
    @IBOutlet weak var textField: UITextField!
    var toolBar —UIToolbar!
    var myDatePicker —UIDatePicker!
    
    override func viewDidLoad(){
        super.viewDidLoad()
        // Setting Up the Input field settings
        textField.placeholder=dateToString(date:Date())//<-`dateToString` parameter is `Date` type, so pass `Date()` from the beginning
        textField.text=dateToString(date:Date())//<- Same as above
        self.view.addSubview(textField)
        
        // Configuring UIDatePicker
        myDatePicker=UIDatePicker()
        myDatePicker.addTarget(self, action:#selector(changedDateEvent), for:UIControlEvents.valueChanged)
        myDatePicker.datePickerMode=UIDatePickerMode.date
        textField.inputView=myDatePicker
        
        // Configuring UIToolBar
        toolBar = UIToolbar (frame: CGRect (x:0, y:self.view.frame.size.height/6, width:self.view.frame.size.width, height:40.0))
        
        toolBar.layer.position = CGPoint (x:self.view.frame.size.width/2, y:self.view.frame.size.height-20.0)
        toolBar.barStyle=.blackTranslucent
        toolBar.tintColor=UIColor.white
        toolBar.backgroundColor=UIColor.black
        
        let toolBarBtn = UIBarButtonItem(title: "Completed", style: .plain, target:self, action:#selector(tappedToolBarBtn))
        let toolBarBtnToday=UIBarButtonItem(title: "Today", style: .plain, target:self, action:#selector(tappedToolBarBtnToday))
        toolBarBtn.tag =1
        toolBar.items = [ toolBarBtn, toolBarBtnToday]
        textField.inputAccessoryView=toolBar
    }
    
    override funcdidReceiveMemoryWarning(){
        super.didReceiveMemoryWarning()
    }
    
    // Press Finish to close
    functappedToolBarBtn(_sender:UIBarButtonItem){
        textField.resignFirstResponder()
    }
    // Press "Today" to set today's date
    functappedToolBarBtnToday(_sender:UIBarButtonItem){
        myDatePicker.date=Date()//<- If you want to put the current time in the property of Type DatePicker, simply pass `Date()`.
        ChangeLabelDate(date:Date()) // <- When passing the current time to the argument of type Date, only `Date()` is OK.
    }
    Action `sender` from func changedDateEvent(_sender:UIDatePicker) {//<-`UIDatePicker` is always `UIDatePicker`
        // You can use `sender` directly as `UIDatePicker`, so no cast is required
        self.changeLabelDate(date:sender.date)
    }

    Replace with `Date` everywhere using funcchangeLabelDate(date:Date) {//<-`NSDate`
        textField.text=self.dateToString(date:date)
    }
    
    funcdateToString (date:Date) - > String {
        // DateFormatter is a reference type, so let is appropriate
        let date_formatter=DateFormatter()
        // If you want to write a single character for the day of the week, you don't need an array of weekdays.
        
        date_formatter.locale=Locale(identifier: "ja")
        date_formatter.dateFormat="yyyyy MM month dd day (E)"//<-`E` is the format character for the day of the week output.
        return date_formatter.string (from:date as Date)
    }
}

In detail, there is still room for correction, but this should be enough to try "Calling UIDatePicker from UITextField on Swift 3".Try it.


2022-09-30 19:09

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.