-1

Ok, the changes I made to the code as @sweepez suggested seem more logical, except now when I simulate the app, I can't even open the first textfield to start typing if that makes sense. Is there a way to set an active TextField for the first one or based on what the user taps on?

  if (textField == quarterNum){
        doneButton.tag = 25
    } else if (textField == dimeNum) {
        doneButton.tag = 10
    } else if (textField == nickelNum) {
        doneButton.tag = 5
    } else {
        doneButton.tag = 1
    }
    return false
}
func doneBttnPressed (barButton: UIBarButtonItem) {
    if (barButton.tag == 25) {
        dimeNum.becomeFirstResponder()
    } else if (barButton.tag == 10) {
        nickelNum.becomeFirstResponder()
    } else if (barButton.tag == 5) {
        pennyNum.becomeFirstResponder()
    }
}

here is what I encounter when I move all of that into the viewDidLoad fuction. I have nothing to compare to the textfields in order to set the tag on them.

  override func viewDidLoad() {
    super.viewDidLoad()
    quarterNum.delegate = self
    dimeNum.delegate = self
    nickelNum.delegate = self
    pennyNum.delegate = self
    ////Background image///////
    self.view.backgroundColor = UIColor(patternImage: UIImage(named: "money1.png")!)

    //Making A toolbar
    let keyboardDoneButtonShow = UIToolbar(frame: CGRectMake(0, 0,  self.view.frame.size.width, self.view.frame.size.height/17))
    //Setting the style for the toolbar
    keyboardDoneButtonShow.barStyle = UIBarStyle.Black
    //Making the done button and calling the textFieldShouldReturn native method for hidding the keyboard.
    let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Done, target: self, action: "doneBttnPressed:")
    let flexSpace = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.FlexibleSpace, target: nil, action: nil)
    let toolbarButton = [flexSpace,doneButton]
    keyboardDoneButtonShow.setItems(toolbarButton, animated: false)
    quarterNum.inputAccessoryView = keyboardDoneButtonShow
    dimeNum.inputAccessoryView = keyboardDoneButtonShow
    nickelNum.inputAccessoryView = keyboardDoneButtonShow
    pennyNum.inputAccessoryView = keyboardDoneButtonShow

    if (textField == quarterNum){
        doneButton.tag = 25
    } else if (textField == dimeNum) {
        doneButton.tag = 10
    } else if (textField == nickelNum) {
        doneButton.tag = 5
    } else {
        doneButton.tag = 1
    }
}
  • Which line does it crash on? `resignFirstResponder` or `becomeFirstResponder`? I think the button loses first responder status when it hides the keyboard. – William Rosenbloom Mar 19 '16 at 06:27
  • It just ends up throwing uncaught NSException. but i know it is that specific code when i try to implement in some fashion that causes it. –  Mar 19 '16 at 06:31
  • You should find, and then report, the actual stack trace. I guarantee you it tells you what line it's failing on. I also guarantee that if you wade through the nonsense it spews out there will be something near the top worth reading. – William Rosenbloom Mar 19 '16 at 06:33
  • 2016-03-19 01:07:00.400 ChangeCalculator[9944:300380] -[UIBarButtonItem resignFirstResponder]: unrecognized selector sent to instance 0x7f80dbd0a440 2016-03-19 01:07:00.405 ChangeCalculator[9944:300380] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIBarButtonItem resignFirstResponder]: unrecognized selector sent to instance 0x7f80dbd0a440' –  Mar 19 '16 at 06:35
  • I believe that is what it is, but I have absolutely no idea how to fix it to do what I want without causing this. –  Mar 19 '16 at 06:35

3 Answers3

1

EDIT: Also it would be better to create the toolbar/buttons on viewDidLoad, and simply change its tag once you start editing the textfield.

When you create the 'Done button based on the textfield you are on, say the quarterNum field, then set a tag to it, i.e. 25, or if the dimeNum field then say tag 10... Also the action function has to be changed.

func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
    // NOTE: Do all the stuff you are already doing to create the toolbar and buttons
    // except the action function for the done button has to be a different method
    // one of your own.
    let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Done, target: self, action: "doneBttnPressed:")
    // ...

    // Then set a tag to the done button based on the textfield that created it.
    if (textField == quarterNum) {
        doneButton.tag = 25
    } else if (textField == dimeNum) {
        doneButton.tag = 10
    } etc etc

}

// Choose which textField to become active once 'Done' is pressed
func doneBttnPressed (barButton: UIBarButtonItem) {

    if barButton.tag == 25 {
        dimeNum.becomeFirstResponder()
    } else if barButton.tag == 10 {
        nickelNum.becomeFirstResponder()
    } etc etc
}
sweepez
  • 585
  • 1
  • 4
  • 17
  • With this implemented, clicking the "Done" key only dismisses the keyboard from the screen. I still have to manually click on the next text field. –  Mar 19 '16 at 07:12
  • well yes, because it is false for all the if statements (other textfields), so it runs the last else which just hides the keyboard. are the textviews properly connected? did you use interface builder? – sweepez Mar 19 '16 at 07:14
  • the textviews are properly connected as best as i can tell, the application itself works exactly the way I need it to as far as output and receiving input. –  Mar 19 '16 at 07:17
  • is your swift file very long?, is it under ~150 lines? would you mind updating your question and posting the whole file? – sweepez Mar 19 '16 at 07:19
  • I updated my question with my entire ViewController.swift file provided as well @sweepez –  Mar 19 '16 at 07:49
  • Sorry, yeah, just saw it. Never got a notification that you updated the post. Anyways, I'm not quite sure, everything seems ok to me, at this point personally I would start testing why the if statements are not evaluating to true i.e. if (textField == quarterNum) . I would start by commenting out the whole textFieldShouldBeginEditing function and see how that affects the textFieldShouldReturn. – sweepez Mar 19 '16 at 07:51
  • I know that you want the custom button, but what happens when you comment out the whole textFieldShouldBeginEditing function, does the return button correctly focuses on to the next textfield? – sweepez Mar 19 '16 at 08:01
  • Because the keyboard I have it set to using is a NumberPad for each text field, there is no return key on the keyboard. All there is, is a backspace button and the 10 number keys. That is the reason I am wanting to create a Done key that acts as one. –  Mar 19 '16 at 12:38
  • I see, I overlooked that, in that case you can not use textFieldShouldReturn, you need to use a function that you create to tell it what to do based on the uibarbutton that was clicked. I have updated my answer with a way I would attempt it, let me know how it goes. – sweepez Mar 20 '16 at 03:30
0

As you use a custom done button, did you add a touch event to that button?You should do something in the touch event method.

something like this

[button addTarget:self selector:@selector(buttonAction:) controlEvent:UIControlEventTouchUpInside];
sKhan
  • 9,694
  • 16
  • 55
  • 53
Levi Han
  • 21
  • 5
  • let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.Done, target: self, action: Selector("textFieldShouldReturn:")) –  Mar 19 '16 at 06:39
  • is that what you are talking about? –  Mar 19 '16 at 06:39
  • As your message in console ,you maybe use a wrong object . what's the class of quarterNum /dimeNum/nickelNum ? – Levi Han Mar 19 '16 at 06:51
  • this is an typically mistake of message send. Send a wrong message to an object. you should check your code and use `resignFirstResponder` like sweepez said. – Levi Han Mar 19 '16 at 06:55
0

In your stack trace I read

ChangeCalculator[9944:300380] -[UIBarButtonItem resignFirstResponder]: unrecognized selector sent to instance 0x7f80dbd0a440 2016-03-19 01:07:00.405 ChangeCalculator[9944:300380] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIBarButtonItem resignFirstResponder]: unrecognized selector sent to instance 0x7f80dbd0a440'

This tells me one of three things is happening.

Option 1

You have a ChangeCalculator object that fails to extend NSObject and therefore cannot respond to selectors, which is a mistake that has gotten the better of me many times.

Option 2

You are having your UIBarButtonItem resign first responder after it's already lost first responder status.

Option 3

You have written a selector incorrectly. I couldn't help but notice what you posted in the comments to the answer above.

In Swift Selectors are written without the Selector wrapping that you're applying. You should just use a String literal.

William Rosenbloom
  • 2,506
  • 1
  • 14
  • 37
  • Ok, i changed that, but how can i now make it to where the button moves the cursor to the next TextField when it is pressed, that is my only issue right now. –  Mar 19 '16 at 06:50
  • check my posted answer – sweepez Mar 19 '16 at 06:51
  • @JordonInman That depends. It seems like this `UITextFieldDelegate` you're using is shared between all the text fields? Is that the case? If so I have a little more advice for you, but in any case you should refer to [this question about switch text field focus](http://stackoverflow.com/questions/7525437/how-to-set-focus-to-a-textfield-in-iphone). – William Rosenbloom Mar 19 '16 at 06:53
  • Yes, the UITextFieldDelegate is being shared. Is there a different way? I have not been using swift for very long so I am very limited on what to do. –  Mar 19 '16 at 07:06
  • @JordonInman sweepez is right you should look at his answer. You can't just call `resignFirstResponder` to figure out which text field is the event's sender. You need to figure that out by comparisons. – William Rosenbloom Mar 19 '16 at 07:08