2017-08-02 8 views
1

私はストーリーボードがなく、すべてがプログラムです。 3つのTextFieldがあり、そのうちの1つは非表示(isHidden = true)でログインボタンの後ろにあり、ログインボタンの下には登録ボタンがあります。登録ボタンをタップすると、ログインボタンが登録ボタンの下にスライドし、隠されたtextFieldがlayoutSubViews()を使用して表示され、isHiddenをfalseに設定して表示されます。アニメーション表示は、テキストフィールドをタップした後に位置をリセットします

私の問題は、テキストフィールドのいずれかをタップするとloginButtonが元の位置に戻ることです。私はviewControllerにテキストフィールドデリゲートを移動しようとしましたが、willLayoutSubviewsとdidLayoutSubviewsでsetup()を呼び出していましたが、同じことが起こります。

のViewController:

class WelcomeScreenViewController: UIViewController { 

    private var currentUser: SplitterUser? { 
     didSet { 
      let nextViewController = MyBillsViewController() 
      nextViewController.currentUser = self.currentUser 
      present(nextViewController, animated: true) 
     } 
    } 

    // swiftlint:disable line_length 
    private let titleLogoLabel = TitleLabelLogo(frame: CGRect.zero, accessID: AccesID.titleLogoLabel) 
    private let emailTextField = SplitterTextField(frame: CGRect.zero, accessID: AccesID.emailTextField) 
    private let passwordTextField = SplitterTextField(frame: CGRect.zero, accessID: AccesID.passwordTextField) 
    private let confirmPasswordTextField = SplitterTextField(frame: CGRect.zero, accessID: AccesID.confirmPasswordTextField) 
    private let loginButton = SplitterButton(frame: CGRect.zero, accessID: AccesID.loginButton) 
    private let registerButton = SplitterButton(frame: CGRect.zero, accessID: AccesID.registerButton) 
    // swiftlint:enable line_length 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     setup() 
    } 

    private func setup() { 
     view.backgroundColor = Color.mainBackground 

     view.addSubview(titleLogoLabel) 
     view.addSubview(emailTextField) 
     view.addSubview(passwordTextField) 
     view.addSubview(confirmPasswordTextField) 
     view.addSubview(loginButton) 
     view.addSubview(registerButton) 

     applyCommonLayoutFeaturesToAllViews() 
     placeTitleLogoLabel() 
     placeEmailTextField() 
     placePasswordTextField() 
     placePasswordConfirmationTextField() 
     placeLoginButton() 
     placeRegisterButton() 
     setupKeyboard() 
    } 

    private func applyCommonLayoutFeaturesToAllViews() { 
     view.subviews.forEach { subview in 
      subview.pinToSuperview(edges: [.left, .right]) 
      subview.translatesAutoresizingMaskIntoConstraints = false 
     } 
    } 

    private func placeTitleLogoLabel() { 
     let titleLogoLabelY = view.frame.height/4.5 
     titleLogoLabel.pinTop(to: view, constant: titleLogoLabelY) 
     titleLogoLabel.addHeightConstraint(with: Layout.titleLogoTextHeight) 
    } 

    private func placeEmailTextField() { 
     emailTextField.centerYToSuperview() 
     emailTextField.addHeightConstraint(with: Layout.textFieldHeight) 
    } 

    private func placePasswordTextField() { 
     passwordTextField.pinTop(to: emailTextField, 
           constant: Layout.textFieldHeight + Layout.spacer, 
           priority: .required, 
           relatedBy: .equal) 
     passwordTextField.addHeightConstraint(with: Layout.textFieldHeight) 
    } 

    private func placePasswordConfirmationTextField() { 
     confirmPasswordTextField.pinTop(to: passwordTextField, 
             constant: Layout.textFieldHeight + Layout.spacer, 
             priority: .required, 
             relatedBy: .equal) 
     confirmPasswordTextField.addHeightConstraint(with: Layout.textFieldHeight) 
     confirmPasswordTextField.isHidden = true 
    } 

    private func placeLoginButton() { 
     loginButton.pinTop(to: passwordTextField, 
          constant: Layout.textFieldHeight + Layout.spacer, 
          priority: .required, 
          relatedBy: .equal) 
     loginButton.addHeightConstraint(with: Layout.buttonHeight) 
     loginButton.addTarget(self, action: #selector(loginButtonTapped), for: .touchUpInside) 
    } 

    private func placeRegisterButton() { 
     registerButton.pinTop(to: loginButton, 
           constant: Layout.buttonHeight + Layout.spacer, 
           priority: .required, 
           relatedBy: .equal) 
     registerButton.addHeightConstraint(with: Layout.buttonHeight) 
     registerButton.addTarget(self, action: #selector(registerButtonTapped), for: .touchUpInside) 
    } 

    @objc private func registerButtonTapped() { 
     if confirmPasswordTextField.isHidden { 
      animateLoginButton() 
     } else { 
      registerNewUser() 
     } 
    } 

    @objc private func loginButtonTapped() { 
     if !confirmPasswordTextField.isHidden { 
      animateLoginButton() 
      self.view.layoutSubviews() 
     } else { 
      //segue to next vc 
     } 
    } 

    private func animateLoginButton() { 
     if confirmPasswordTextField.isHidden { 
      moveLoginButtonDown() 
     } else { 
      moveLoginButtonUp() 
     } 
    } 

    private func moveLoginButtonDown() { 
     //Move loginButton down revealing confirmationPasswordTextView behind it 
     UIView.animate(withDuration: 0.3, animations: { 
      self.loginButton.frame.origin.y += Layout.loginButtonYMovement 
      self.confirmPasswordTextField.isHidden = false 
     }) 
    } 

    private func moveLoginButtonUp() { 
     //Move the loginButton up, when it has finished moving hide the confirmationPasswordTextView 
     UIView.animate(withDuration: 0.3, animations: { 
      self.loginButton.frame.origin.y -= Layout.loginButtonYMovement 
     }, completion: { _ in 
      self.confirmPasswordTextField.isHidden = true 
     }) 
    } 
} 

extension UIViewController { 
    func setupKeyboard() { 
     NotificationCenter.default.addObserver(self, 
               selector: #selector(keyboardWillShow(sender:)), 
               name: NSNotification.Name.UIKeyboardWillShow, 
               object: nil) 
     NotificationCenter.default.addObserver(self, 
               selector: #selector(keyboardWillHide(sender:)), 
               name: NSNotification.Name.UIKeyboardWillHide, 
               object: nil) 
    } 

    @objc private func keyboardWillShow(sender: NSNotification) { 
     self.view.frame.origin.y = Layout.welcomeScreenKeyboardMovement 
    } 

    @objc private func keyboardWillHide(sender: NSNotification) { 
     self.view.frame.origin.y = 0 
    } 
} 

のTextField:私はしようとする他に何のために失われています

class SplitterTextField: UITextField, UITextFieldDelegate { 

    var accessID: String! 

    required init(frame: CGRect, accessID: String) { 
     super.init(frame: frame) 
     self.accessID = accessID 
     setup() 
    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
    } 

    private func setup() { 
     delegate = self 
     backgroundColor = Color.textFieldBackground 
     accessibilityIdentifier = accessID 
     textAlignment = .center 
     returnKeyType = .done 
     placeholder = NSLocalizedString("\(accessID!)PlaceHolder", comment: "") 
    } 

    func textFieldShouldReturn(_ textField: UITextField) -> Bool { 
     resignFirstResponder() 
     return true 
    } 
} 

。どんなアイデアも素晴らしいだろう。ありがとう

+0

ログインボタンを押すと、位置がリセットされています。 –

+0

ログインボタンと登録ボタンは必要ありませんが、ログインボタンが移動した後にテキストフィールドをタップすると、開始ポイントにリセットされます – Wazza

+0

textFieldShouldReturn以外のコードでテキストフィールドのedlegate関数はありますか? –

答えて

0

いつものようにWelcomeScreenViewControllerと入力したXIBファイル(ストーリーボードはありません)を追加してください。自動レイアウト制約をグラフィカルに作成します(はるかに簡単です)。

これらの制約のいくつかをビューコントローラコードのアウトレットとして使用し、必要に応じて一部のサブビューのalphaと共にアニメーション化します。

私はこれがまったく別の解決策であると認識していますが、あなたは複雑すぎると思います。 UIViewController/XIBのペアは、まだUIを構築するのに非常に便利で簡単な方法です。

+0

タスクの全ポイント(私は自分自身に設定しました)は、グラフィカルなインターフェイスを使用していない会社として使用しないことです。ありがとう、 – Wazza

+0

私は参照してください。なぜ彼らはいないのですか? –

+0

いくつかの理由があります。私は、ストーリーボードなどを含むプロジェクトで複数の人が働いているときにgithubを複雑にして、IBを通して精査しなければならない問題を解決しにくくすることを覚えています。私は – Wazza

0

ビューをレイアウトするための制約を設定しました。自動レイアウトでは、制約を使用してビューのフレームを計算します。

self.loginButton.frame.origin.y += Layout.loginButtonYMovement 

次回の自動レイアウトを実行すると、それが制約に基づいてloginButtonのフレームをリセットします:次に、あなたは直接loginButtonのフレームを変更します。

loginButtonを移動するには、そのフレームを設定する制約を変更する必要があります。たとえば、インスタンス変数には、作成する上部の制約をplaceLoginButtonに保存する必要があります。次にmoveLoginButtonDownで、保存された制約の定数を変更し、アニメーションブロックでself.view.layoutSubviews()を呼び出します。

+0

あなたの言っていることをどのように実装するか分かりませんが、少し助けてもらえますか? – Wazza

関連する問題