Swift PresentViewController解散键盘

时间:2015-10-14 23:03:15

标签: ios swift uiviewcontroller wizard presentviewcontroller

我正在创建一个包含多个UIViewControllers的注册向导。

我目前已将其设置为用户输入他的电子邮件,点击" Go"键盘上的按钮和用户将输入其姓名的右侧的下一个UIViewController幻灯片。但问题是,当我呼叫presentViewController以使下一个UIViewController进入时,它会解除键盘的问题。

我希望键盘在切换ViewControllers时保持打开状态。如果你看看Facebook的iOS应用程序,他们会按照我的注册页面进行操作。

任何帮助或建议将不胜感激。我读了一些关于使用覆盖窗口的内容,但我不知道该怎么做,因为我的注册向导中会有多个UIViewController

这是我在注册向导中的初始控制器:

class SignUpEmailViewController: UIViewController {
    var titleLabel = UILabel.newAutoLayoutView()
    var emailField = SignUpTextField(placeholder: "Enter your email address")
    var emailLabel = UILabel.newAutoLayoutView()
    var continueButton = SignUpContinueButton.newAutoLayoutView()
    var footerView = SignUpFooterView.newAutoLayoutView()

    let presentAnimationController = PushInFromLeftAnimationController()
    let dismissAnimationController = PushInFromRightAnimationController()

    override func viewDidLoad() {
        super.viewDidLoad()
        setupViews()
        setupGestures()
    }

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        emailField.becomeFirstResponder()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func setupViews() {
        view.backgroundColor = UIColor.colorFromCode(0xe9eaed)

        titleLabel.text = "Get Started"
        titleLabel.font = UIFont(name: "AvenirNextLTPro-Demi", size: 18)
        titleLabel.textColor = Application.greenColor

        emailField.enablesReturnKeyAutomatically = true
        emailField.returnKeyType = .Go
        emailField.delegate = self

        emailLabel.text = "You'll use this email when you log in and if you ever need to reset your password."
        emailLabel.font = UIFont(name: "AvenirNextLTPro-Regular", size: 13)
        emailLabel.textColor = .colorFromCode(0x4e5665)
        emailLabel.numberOfLines = 0
        emailLabel.textAlignment = .Center

        continueButton.addTarget(self, action: "continueButtonPressed", forControlEvents: .TouchUpInside)
        continueButton.hidden = true

        view.addSubview(titleLabel)
        view.addSubview(emailField)
        view.addSubview(emailLabel)
        view.addSubview(continueButton)
        view.addSubview(footerView)
        setupConstraints()
    }

    func setupGestures() {
        let gestureRecognizer = UISwipeGestureRecognizer(target: self, action: "swipeHandler")
        gestureRecognizer.direction = .Down
        view.addGestureRecognizer(gestureRecognizer)

        let tapGesture = UITapGestureRecognizer(target: self, action: "dismissKeyboard")
        view.addGestureRecognizer(tapGesture)
    }

    func setupConstraints() {
        titleLabel.autoAlignAxisToSuperviewAxis(.Vertical)
        titleLabel.autoPinEdgeToSuperviewEdge(.Top, withInset: screenSize.height * 0.2)

        emailField.autoAlignAxisToSuperviewAxis(.Vertical)
        emailField.autoPinEdge(.Top, toEdge: .Bottom, ofView: titleLabel, withOffset: 15)
        emailField.autoSetDimensionsToSize(CGSize(width: screenSize.width * 0.85, height: 40))

        emailLabel.autoAlignAxisToSuperviewAxis(.Vertical)
        emailLabel.autoPinEdge(.Top, toEdge: .Bottom, ofView: emailField, withOffset: 10)
        emailLabel.autoSetDimension(.Width, toSize: screenSize.width * 0.85)

        continueButton.autoAlignAxisToSuperviewAxis(.Vertical)
        continueButton.autoPinEdge(.Top, toEdge: .Bottom, ofView: emailField, withOffset: 10)
        continueButton.autoSetDimensionsToSize(CGSize(width: screenSize.width * 0.85, height: 30))

        footerView.autoSetDimension(.Height, toSize: 44)
        footerView.autoPinEdgeToSuperviewEdge(.Bottom)
        footerView.autoPinEdgeToSuperviewEdge(.Leading)
        footerView.autoPinEdgeToSuperviewEdge(.Trailing)
    }

    override func prefersStatusBarHidden() -> Bool {
        return true
    }

    func swipeHandler() {
        dismissViewControllerAnimated(true, completion: nil)
    }

    func continueButtonPressed() {
        presentNextViewController()
    }

    func dismissKeyboard() {
        view.endEditing(true)
    }

    func presentNextViewController() {
        let toViewController = SignUpNameViewController()
        toViewController.transitioningDelegate = self
        toViewController.firstNameField.becomeFirstResponder()
        presentViewController(toViewController, animated: true, completion: nil)
    }
}

extension SignUpEmailViewController: UIViewControllerTransitioningDelegate {
    func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return presentAnimationController
    }

    func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return dismissAnimationController
    }
}

extension SignUpEmailViewController: UITextFieldDelegate {
    func textFieldShouldReturn(textField: UITextField) -> Bool {
        presentNextViewController()
        return true
    }

    func textFieldShouldBeginEditing(textField: UITextField) -> Bool {
        continueButton.hidden = true
        emailLabel.hidden = false
        return true
    }

    func textFieldShouldEndEditing(textField: UITextField) -> Bool {
        continueButton.hidden = false
        emailLabel.hidden = true
        return true
    }
}

这是我试图呈现的控制器:

class SignUpNameViewController: UIViewController, UIViewControllerTransitioningDelegate {
    var titleLabel = UILabel.newAutoLayoutView()
    var textFieldContainer = UIView.newAutoLayoutView()
    var firstNameField = SignUpTextField(placeholder: "First name")
    var lastNameField = SignUpTextField(placeholder: "Last name")
    var continueButton = SignUpContinueButton.newAutoLayoutView()
    var footerView = SignUpFooterView.newAutoLayoutView()

    let presentAnimationController = PushInFromLeftAnimationController()
    let dismissAnimationController = PushInFromRightAnimationController()

    override func viewDidAppear(animated: Bool) {
        super.viewDidAppear(animated)
        firstNameField.becomeFirstResponder()
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        setupViews()
        setupGestures()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func setupViews() {
        view.backgroundColor = UIColor.colorFromCode(0xe9eaed)

        titleLabel.text = "What's your name?"
        titleLabel.font = UIFont(name: "AvenirNextLTPro-Demi", size: 18)
        titleLabel.textColor = Application.greenColor

        firstNameField.returnKeyType = .Next
        firstNameField.enablesReturnKeyAutomatically = true

        lastNameField.returnKeyType = .Next
        lastNameField.enablesReturnKeyAutomatically = true

        continueButton.addTarget(self, action: "continueButtonPressed", forControlEvents: .TouchUpInside)

        view.addSubview(titleLabel)
        view.addSubview(textFieldContainer)
        textFieldContainer.addSubview(firstNameField)
        textFieldContainer.addSubview(lastNameField)
        view.addSubview(continueButton)
        view.addSubview(footerView)
        setupConstraints()
    }

    func setupGestures() {
        let gestureRecognizer = UISwipeGestureRecognizer(target: self, action: "swipeHandler")
        gestureRecognizer.direction = .Right
        view.addGestureRecognizer(gestureRecognizer)

        let tapGesture = UITapGestureRecognizer(target: self, action: "dismissKeyboard")
        view.addGestureRecognizer(tapGesture)
    }

    func setupConstraints() {
        titleLabel.autoAlignAxisToSuperviewAxis(.Vertical)
        titleLabel.autoPinEdgeToSuperviewEdge(.Top, withInset: screenSize.height * 0.2)

        textFieldContainer.autoPinEdge(.Top, toEdge: .Bottom, ofView: titleLabel, withOffset: 15)
        textFieldContainer.autoAlignAxisToSuperviewAxis(.Vertical)
        textFieldContainer.autoSetDimensionsToSize(CGSize(width: screenSize.width * 0.8, height: 40))

        let spaceBetweenTextFields: CGFloat = 5
        let textFieldSize = ((screenSize.width * 0.8) - spaceBetweenTextFields) / 2
        let textFields: NSArray = [firstNameField, lastNameField]
        textFields.autoDistributeViewsAlongAxis(.Horizontal, alignedTo: .Horizontal, withFixedSize: textFieldSize, insetSpacing: false)

        firstNameField.autoPinEdgeToSuperviewEdge(.Top)
        firstNameField.autoPinEdgeToSuperviewEdge(.Bottom)

        lastNameField.autoPinEdgeToSuperviewEdge(.Top)
        lastNameField.autoPinEdgeToSuperviewEdge(.Bottom)

        continueButton.autoAlignAxisToSuperviewAxis(.Vertical)
        continueButton.autoPinEdge(.Top, toEdge: .Bottom, ofView: textFieldContainer, withOffset: 10)
        continueButton.autoSetDimensionsToSize(CGSize(width: screenSize.width * 0.8, height: 30))

        footerView.autoSetDimension(.Height, toSize: 44)
        footerView.autoPinEdgeToSuperviewEdge(.Bottom)
        footerView.autoPinEdgeToSuperviewEdge(.Leading)
        footerView.autoPinEdgeToSuperviewEdge(.Trailing)
    }

    override func prefersStatusBarHidden() -> Bool {
        return true
    }

    func dismissKeyboard() {
        view.endEditing(true)
    }

    func swipeHandler() {
        dismissViewControllerAnimated(true, completion: nil)
    }

    func continueButtonPressed() {
        let toViewController = SignUpPasswordViewController()
        toViewController.transitioningDelegate = self
        presentViewController(toViewController, animated: true, completion: {})
    }

    func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return presentAnimationController
    }

    func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return dismissAnimationController
    }
}

这是我的自定义转换:

class PushInFromLeftAnimationController: NSObject, UIViewControllerAnimatedTransitioning {
    func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval {
        return 0.35
    }

    func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
        let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)!
        let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)!
        let finalFrameForVC = transitionContext.finalFrameForViewController(toViewController)
        let containerView = transitionContext.containerView()
        let bounds = UIScreen.mainScreen().bounds
        toViewController.view.frame = CGRectOffset(finalFrameForVC, bounds.size.width, 0)
        containerView!.addSubview(toViewController.view)

        UIView.animateWithDuration(transitionDuration(transitionContext), delay: 0.0, options: UIViewAnimationOptions.CurveLinear, animations: {
            fromViewController.view.frame = CGRectOffset(finalFrameForVC, -bounds.size.width, 0)
            toViewController.view.frame = finalFrameForVC
            }, completion: {
                finished in
                transitionContext.completeTransition(true)
        })
    }
}

1 个答案:

答案 0 :(得分:0)

我认为键盘被解除了,因为相应的UIResponder会在ViewController消失的同时辞职。

您是否尝试将下一个UITextField(在下一个ViewController中)设置为第一个响应者?因此键盘将在前一个UIR应答器结束编辑之前链接到新的UIR应答器......