2015-10-14 69 views
0

我正在创建一个注册向导,其中包含多个UIViewControllersSwift PresentViewController取消键盘

我现在已经设置好了,所以用户输入他的电子邮件,点击键盘上的“开始”按钮,然后下一个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) 
     }) 
    } 
} 
+0

请参阅我对此问题的评论:http://stackoverflow.com/q/33127863/341994 – matt

+0

嘿@matt,我检查你的答案,并更新我的问题,以显示我的代码。任何想法如何Facebook似乎保持键盘打开,因为他们从ViewController切换到ViewController的注册向导?也许他们不是真的切换视图控制器,而是只是动画TextFields滑入? – Thomas

+0

或者是将UITextField添加到获得第一响应者角色的窗口的唯一解决方案?这看起来很凌乱 – Thomas

回答

0

我认为键盘被解雇是因为相应的UIResponder会在相同的ti上辞职我的ViewController会消失。

您是否曾尝试将下一个UITextField(在下一个ViewController中)设置为第一响应者呢?从而键盘将链接到一个新的UIResponder之前,前一个将结束编辑...

+0

是的我尝试设置为ViewController.firstNameField。在调用presentViewController()之前调用FirstFirstResponder(),而发生的事情是键盘向下移动一点就像它辞职,然后移回到原来的位置 – Thomas

+0

mmm ...是的,我期待着这样的事情......而我想知道如何通过明智地选择操作的顺序来避免这种情况......因为我想到的另一个解决方案有点难看:在键盘背后有一个临时的uitextfield,它可以在第一响应者viewcontroller进出。 – Alde

+0

是的,我开始认为这可能是唯一的解决方案 – Thomas