0

I'm using BWWalkthrough to build a welcome walkthrough with textfield inside.

There are 2 prebuilt IBOutlets inside the BWWalkthroughViewController that I attached to my elements ( nextButton and prevButton ). Basically, I'm using textfields in my pages to ask them informations.

Inside the class of my page :

class WTnameViewController: UIViewController, UITextFieldDelegate, BWWalkthroughPage {

I added an observer to see when the textfield change.

override func viewDidLoad() {
    super.viewDidLoad()
    //  ...
  NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("textfieldIsNotEmpty:"), name:UITextFieldTextDidChangeNotification, object: textfieldName)
    //  ...
}

and it calls this function :

func textfieldIsNotEmpty(notification: NSNotification) {

    // BWWalkthroughViewController is the master class.
    let nxtBtn = BWWalkthroughViewController()

    if textfieldName.text?.isEmpty == true {
        // Animate the fade-out of the button
        UIView.animateWithDuration(0.4, animations: { () -> Void in
            nxtBtn.nextButton?.layer.opacity = 0
            }, completion: { finished in
                nxtBtn.nextButton?.hidden = true
        })

    } else if textfieldName.text?.isEmpty == false {
        // animate the fade-in of the button in BWWalkthrough
        UIView.animateWithDuration(0.4, animations: { () -> Void in
            nxtBtn.nextButton?.hidden = false
            nxtBtn.nextButton?.layer.opacity = 1
            }, completion: { finished in
        })

    }
}

But the button is a nil.

Also, I add a notification in ViewDidLoad of the the BWWalkthroughViewController class to change the position of the buttons

NSNotificationCenter.defaultCenter().addObserver(self, selector: "keyboardNotification:", name: UIKeyboardWillChangeFrameNotification, object: nil)

and the function :

func keyboardNotification(notification: NSNotification) {

    // Below we define the animation
    let userInfo = notification.userInfo!
    let animationDuration = (userInfo[UIKeyboardAnimationDurationUserInfoKey] as! NSNumber).doubleValue
    let keyboardEndFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).CGRectValue()
    let convertedKeyboardEndFrame = view.convertRect(keyboardEndFrame, fromView: view.window)
    let rawAnimationCurve = (notification.userInfo![UIKeyboardAnimationCurveUserInfoKey] as! NSNumber).unsignedIntValue << 16
    let animationCurve = UIViewAnimationOptions(rawValue: UInt(rawAnimationCurve))

    // I change the constraint of the button with the animation
    buttonNextBottomConstraint!.constant = CGRectGetMaxY(view.bounds) - CGRectGetMinY(convertedKeyboardEndFrame)
    buttonBackBottomConstraint!.constant = CGRectGetMaxY(view.bounds) - CGRectGetMinY(convertedKeyboardEndFrame)
    UIView.animateWithDuration(animationDuration, delay: 0.0, options: [.BeginFromCurrentState, animationCurve], animations: {
        self.view.layoutIfNeeded()
        }, completion: nil)

    // Here I check if 'nextButton' is a nil - Debug only
    print("keyboard : \(nextButton)")
}

The value of nextButton isn't nil here

I also tried to change the button through functions directly inside the BWWalkthroughViewController but it also return me a nil.

Could someone explain me why nextButton is a nil in a function and not another one ?

EDIT :

I created the following function in the BWWalkthroughViewController :

public func textfieldChangeButton() {
        // Do stuff here when receive a notification about a textfield
        UIView.animateWithDuration(0.4, animations: { () -> Void in
            self.nextButton?.hidden = false
            self.nextButton?.layer.opacity = 1
            print("textfieldChangeButton : \(self.nextButton)")
            }, completion: { finished in
        })
    }

When I call it from the actual textfieldIsNotEmpty, nextButton is nil, and when I call it from another function inside BWWalkthroughViewController directly, it works just fine.

tsnkff
  • 786
  • 1
  • 7
  • 20
  • What does the code look like in `textfieldIsNotEmpty` where you call the new function you have in the **EDIT** section? – Phillip Mills Mar 18 '16 at 15:25
  • I call it like that : `BWWalkthroughViewController().textfieldChangeButton()`. Is that the wrong way to call it ? – tsnkff Mar 18 '16 at 15:38
  • I keep saying that `BWWalkthroughViewController()` creates a new, empty object...but you don't seem to believe me. :) – Phillip Mills Mar 18 '16 at 16:11
  • @PhillipMills I do believe you... Since this is exactly my error. I just followed the [answer here](http://stackoverflow.com/questions/26082072/calling-function-from-another-class-swift) . How should I call the function then ? – tsnkff Mar 18 '16 at 16:17

1 Answers1

1

This: let nxtBtn = BWWalkthroughViewController() creates a new object. Since it is not part of the screen display, it doesn't have its view loaded and therefore doesn't have its outlets filled in.

You don't say how textfieldIsNotEmpty is called but you probably want to pass it a reference to an existing BWWalkthroughViewController rather than having it create an empty one.

Phillip Mills
  • 30,888
  • 4
  • 42
  • 57
  • `textfieldIsNotEmpty` is called by the `NSNotification`, am I wrong ? Plus, it makes sense so I tried replacing `nxtBtn.nextButton?.hidden = true` by `BWWalkthroughViewController().nextButton?.hidden = true`, and it didn't work either – tsnkff Mar 18 '16 at 14:34
  • Right about the notification...I was paying more attention to the target method. But `BWWalkthroughViewController()` is still going to create a new, empty object whether it's on a line by itself or not. – Phillip Mills Mar 18 '16 at 14:57
  • I edited my answer with another approach. Thanks for your time. – tsnkff Mar 18 '16 at 15:18