2015-10-14 74 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