1

Here is my code , I am adding UITextfield programtically in scrollview. But UITextField is unable to open keyboard. It looks like UITextField is not enabling even added user interaction enabled true. I only use the constraints, no storyboard, no xibs. Only through Constraints Programmatically. Below is my code :

class SignupViewController : UIViewController {
    var backButton : UIButton!
    var titleLabel : UILabel!
    var navBarView : UIView!
    var scrollView : UIScrollView!
    var scrollMainView : UIView!
    var emailfieldView : UIView!
    var emailTextField : UITextField = UITextField() override func viewDidLoad() {
        super.viewDidLoad()
        setDesign()
    }
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)
    }func setDesign(){
        setNavegationBar()
        setBackgroundImage()
        addScrollView()
    }
    func setBackgroundImage(){
        let backgroundImage = UIImageView(image: UIImage(named: "loginbg.png"))
        self.view.addSubview(backgroundImage)
        backgroundImage.translatesAutoresizingMaskIntoConstraints = false
        let leadingConst = backgroundImage.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 0)
        let trailingConst = backgroundImage.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 0)
        let topConst = backgroundImage.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 0)
        let bottomConst = backgroundImage.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0)
        NSLayoutConstraint.activate([leadingConst,trailingConst,topConst,bottomConst])
    }
        func setNavegationBar(){
        navigationItem.title = "Join"
        view.backgroundColor = UIColor.white
        navigationController?.navigationBar.isHidden = true
        navigationController?.navigationBar.tintColor = UIColor.white
        navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor: UIColor.white]
        setNavBarView()
    }
    func setNavBarView(){
        navBarView = UIView()
        self.view.addSubview(navBarView)
        navBarView.translatesAutoresizingMaskIntoConstraints = false
        let guide = view.safeAreaLayoutGuide
        let heightCost  = navBarView.heightAnchor.constraint(equalToConstant: 64.0)
        let leadingCost = navBarView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 0.0)
        let trailingConst = navBarView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 0)
        let topCost = navBarView.topAnchor.constraint(equalTo: guide.topAnchor, constant: 0.0)
        NSLayoutConstraint.activate([trailingConst,heightCost,topCost,leadingCost])
        setBackButton()
        setNavTitle()
    }
    func setBackButton(){
        backButton = UIButton(type: UIButtonType.custom)
        backButton.setImage(UIImage(named: "join_back"), for: UIControlState.normal)
        navBarView.addSubview(backButton)
        backButton.translatesAutoresizingMaskIntoConstraints = false
        let widthCost   = backButton.widthAnchor.constraint(equalToConstant: 44.0)
        let heightCost  = backButton.heightAnchor.constraint(equalToConstant: 44.0)
        let leadingCost = backButton.leadingAnchor.constraint(equalTo: navBarView.leadingAnchor, constant: 0.0)
        let topCost = backButton.topAnchor.constraint(equalTo: navBarView.topAnchor, constant: 0.0)
        NSLayoutConstraint.activate([widthCost,heightCost,topCost,leadingCost])
        backButton.addTarget(self, action: #selector(self.backButtonPress), for: UIControlEvents.touchUpInside)
    }
    func setNavTitle(){
        titleLabel = UILabel()
        titleLabel.text = "Join Dubai Store"
        titleLabel.font = UIFont(name: "Dubai-Regular", size: 22.0)
        titleLabel.textAlignment = NSTextAlignment.center
        titleLabel.tintColor = UIColor(hexString: "#353535")
        navBarView.addSubview(titleLabel)
        titleLabel.translatesAutoresizingMaskIntoConstraints = false
        let heightCost  = titleLabel.heightAnchor.constraint(equalToConstant: 44.0)
        let topCost = titleLabel.topAnchor.constraint(equalTo: navBarView.topAnchor, constant: 0.0)
        let centerCost  =  titleLabel.centerXAnchor.constraint(equalTo: navBarView.centerXAnchor)
        NSLayoutConstraint.activate([heightCost,topCost,centerCost])
    }
    @objc func backButtonPress(){
        self.view.endEditing(true)
        self.dismissView()
    }
    func addScrollView(){
        scrollView = UIScrollView()
        view.addSubview(scrollView)
        scrollView.layer.borderWidth = 1.0
        scrollView.layer.borderColor = UIColor.red.cgColor
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        let leadingConst = scrollView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 0)
        let trailingConst = scrollView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 0)
        let topConst = scrollView.topAnchor.constraint(equalTo: navBarView.bottomAnchor, constant: 0)
        let bottomConst = scrollView.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: 0)
        NSLayoutConstraint.activate([leadingConst,trailingConst,topConst,bottomConst])
        addScrollMainView()
    }
    func addScrollMainView() {
        scrollMainView = UIView()
        scrollView.addSubview(scrollMainView)
        scrollMainView.translatesAutoresizingMaskIntoConstraints = false
        let leadingConst = scrollMainView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor, constant: 0)
        let trailingConst = scrollMainView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 0)
        let topConst = scrollMainView.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 0)
        let bottomConst = scrollMainView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: 0)
        NSLayoutConstraint.activate([topConst,leadingConst,trailingConst,bottomConst])
        emailFieldView()
    }
    func emailFieldView(){
        emailfieldView = UIView()
        emailfieldView.isUserInteractionEnabled = true
        emailfieldView.translatesAutoresizingMaskIntoConstraints = false
        scrollMainView.addSubview(emailfieldView)

        let topCost     = emailfieldView.topAnchor.constraint(equalTo: scrollMainView.topAnchor, constant: 0.0)
        let leadingConst = emailfieldView.leadingAnchor.constraint(equalTo: scrollMainView.leadingAnchor, constant: 0)
        let trailingConst = emailfieldView.trailingAnchor.constraint(equalTo: scrollMainView.trailingAnchor, constant: 0)
        let heightCost  = emailfieldView.heightAnchor.constraint(equalToConstant: 62.0)
        NSLayoutConstraint.activate([trailingConst,heightCost,topCost,leadingConst])

        //emailTextField = UITextField(frame: CGRect(x: 10, y: 0, width: SCREEN_WIDTH, height: 50))
        emailTextField.placeholder  = "Email"
        emailTextField.layer.borderColor = UIColor.red.cgColor
        emailTextField.layer.borderWidth = 1.0
        //        emailTextField.font         = UIFont.systemFont(ofSize: 15)
        //        emailTextField.borderStyle  = UITextBorderStyle.none
        //        emailTextField.keyboardType    = UIKeyboardType.default
        //        emailTextField.returnKeyType   = UIReturnKeyType.done
        //        //emailTextField.clearButtonMode = UITextFieldViewMode.whileEditing
        emailTextField.isUserInteractionEnabled = true
        emailTextField.allowsEditingTextAttributes = true
        //emailTextField.contentVerticalAlignment = UIControlContentVerticalAlignment.center

        emailTextField.addTarget(self, action:  #selector(self.textFieldShouldBeginEditing), for: UIControlEvents.touchUpInside)
        emailfieldView.addSubview(emailTextField)

        emailTextField.translatesAutoresizingMaskIntoConstraints = false
        emailTextField.contentMode = UIViewContentMode.left
        emailTextField.delegate = self
        let etopCost     = emailTextField.topAnchor.constraint(equalTo: emailfieldView.topAnchor, constant: 0.0)
        let eleadingConst = emailTextField.leadingAnchor.constraint(equalTo: emailfieldView.leadingAnchor, constant: 10)
        let etrailingConst = emailTextField.trailingAnchor.constraint(equalTo: emailfieldView.trailingAnchor, constant: -10)
        let eheightCost  = emailTextField.heightAnchor.constraint(equalToConstant: 50.0)
        NSLayoutConstraint.activate([etopCost,eleadingConst,etrailingConst,eheightCost])
        self.scrollMainView.bringSubview(toFront: emailTextField)
        emailTextField.isAccessibilityElement = true
    } }
    extension SignupViewController: UITextFieldDelegate {

    func textFieldShouldBeginEditing(_ textField: UITextField) -> Bool {
        // return NO to disallow editing.
        print("TextField should begin editing method called")
        return true
    }

    func textFieldDidBeginEditing(_ textField: UITextField) {
        // became first responder
        print("TextField did begin editing method called")
    }

    func textFieldShouldEndEditing(_ textField: UITextField) -> Bool {
        // return YES to allow editing to stop and to resign first responder status. NO to disallow the editing session to end
        print("TextField should snd editing method called")
        return true
    }

    func textFieldDidEndEditing(_ textField: UITextField) {
        // may be called if forced even if shouldEndEditing returns NO (e.g. view removed from window) or endEditing:YES called
        print("TextField did end editing method called")
    }

    func textFieldDidEndEditing(_ textField: UITextField, reason: UITextFieldDidEndEditingReason) {
        // if implemented, called in place of textFieldDidEndEditing:
        print("TextField did end editing with reason method called")
    }

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {
        // return NO to not change text
        print("While entering the characters this method gets called")
        return true
    }

    func textFieldShouldClear(_ textField: UITextField) -> Bool {
        // called when clear button pressed. return NO to ignore (no notifications)
        print("TextField should clear method called")
        return true
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        // called when 'return' key pressed. return NO to ignore.
        print("TextField should return method called")
        // may be useful: textField.resignFirstResponder()
        return true
    }
}
dlggr
  • 741
  • 7
  • 15
Humza Shahid
  • 33
  • 11

1 Answers1

0

I just run your code, it looks like scrollMainView is not visible in the views' hierarchy. Just change the constraints. Here is the code:

func addScrollMainView() {
        scrollMainView = UIView()
        scrollView.addSubview(scrollMainView)
        scrollMainView.translatesAutoresizingMaskIntoConstraints = false
        let leadingConst = scrollMainView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 0)
        let trailingConst = scrollMainView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: 0)
        let topConst = scrollMainView.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 0)
        let bottomConst = scrollMainView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0)
        NSLayoutConstraint.activate([topConst,leadingConst,trailingConst,bottomConst])
        emailFieldView()
    }

BTW, It is not related to your question, but it is better to create bg at the beginning. Just use the code below:

func setDesign(){
        setBackgroundImage()
        setNavegationBar()
        addScrollView()
    }
Razib Mollick
  • 4,617
  • 2
  • 22
  • 20
  • nice to know that, it works. please accept my answer – Razib Mollick Oct 21 '18 at 05:00
  • Why you used this : view.bottomAnchor , it should be scrollView.bottomAnchor. – Humza Shahid Oct 21 '18 at 12:28
  • From viewDidLoad, The only active layout is self.view. If you print your scrollview bounds, you will see all zeros. Settings active constraints will not happen instantly. For accepting answer, just click the gray check marked. – Razib Mollick Oct 21 '18 at 16:18