【问题标题】:Load keyboard programmatically with textField and send button using swift使用 textField 以编程方式加载键盘并使用 swift 发送按钮
【发布时间】:2021-10-17 03:10:05
【问题描述】:

我是 swift 新手,正在尝试完成一项相当简单的任务。我正在创建一个 iPad 应用程序,我想在其中以编程方式打开键盘。

  1. 键盘顶部应有一个 textField 栏,用于记录使用键盘输入的内容。
  2. textField旁边应该有一个按钮。(如图所示)

我试图达到同样的效果,但这样做:

lazy var textFieldPanel: UIView = {
        let view = UIView(frame: CGRect(x: 0.0, y: self.view.bounds.height, width: self.view.bounds.width, height: 50.0))
        self.view.addSubview(view)
        view.backgroundColor = UIColor.white
        view.borderColor = UIColor.blue
        view.borderWidth = 2.0
        
        let fieldBottomConstraint = NSLayoutConstraint(item: view, attribute: .bottom, relatedBy: .equal, toItem: self.view, attribute: .bottom, multiplier: 1.0, constant: 0.0)
        customTextFieldBottomConstraint = fieldBottomConstraint
        
        view.translatesAutoresizingMaskIntoConstraints = false
        self.view.addConstraint(.init(item: view, attribute: .left, relatedBy: .equal, toItem: self.view, attribute: .left, multiplier: 1.0, constant: 0.0))
        self.view.addConstraint(.init(item: view, attribute: .right, relatedBy: .equal, toItem: self.view, attribute: .right, multiplier: 1.0, constant: 0.0))
        self.view.addConstraint(fieldBottomConstraint)
        self.view.addConstraint(.init(item: view, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1.0, constant: 50.0))
        
        return view
    }()

    lazy var customTextField: UITextField = {
        let field = UITextField(frame: CGRect(x: 0.0, y: 0.0, width: self.view.bounds.width - 300 , height: 50.0))
        textFieldPanel.addSubview(field)
        
        field.translatesAutoresizingMaskIntoConstraints = false
        self.view.addConstraint(.init(item: field, attribute: .left, relatedBy: .equal, toItem: textFieldPanel, attribute: .left, multiplier: 1.0, constant: 8.0))
        self.view.addConstraint(.init(item: field, attribute: .right, relatedBy: .equal, toItem: textFieldPanel, attribute: .right, multiplier: 1.0, constant: 8.0))
        self.view.addConstraint(.init(item: field, attribute: .top, relatedBy: .equal, toItem: textFieldPanel, attribute: .top, multiplier: 1.0, constant: 2.0))
        self.view.addConstraint(.init(item: field, attribute: .bottom, relatedBy: .equal, toItem: textFieldPanel, attribute: .bottom, multiplier: 1.0, constant: 2.0))
        let button = UIButton(frame: CGRect(x: self.view.bounds.width - 350, y: 0.0, width: 200 , height: 50.0))
        button.backgroundColor = UIColor.clear
        button.setTitle("Send", for: .normal)
        button.borderWidth = 2.0
        button.borderColor = UIColor.blue
        button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
        textFieldPanel.addSubview(button)
        
        button.translatesAutoresizingMaskIntoConstraints = false
        return field
    }()

然后在 IBAction 中调用它:

customTextField.becomeFirstResponder()
customTextFieldBottomConstraint?.constant = -360.0

我面临的问题如下:

  1. 视图完全扭曲。 (如图)
  2. 发送按钮视图扭曲,如图片所示。
  3. 隐藏键盘时,textField 视图仍然保留,我希望将其移除。
  4. 键盘启动时视图未向上移动。

谁能帮我看看我在这里做错了什么。任何帮助将不胜感激。

【问题讨论】:

    标签: ios swift


    【解决方案1】:

    我将从更好的代码可读性建议开始:

    1. 与其使用init 创建约束,还有一种更简洁的方法:
    .init(item: view, attribute: .left, relatedBy: .equal, toItem: self.view, attribute: .left, multiplier: 1.0, constant: 0.0)
    
    // vs 
    
    view.leftAnchor.constraint(equalTo: self.view.leftAnchor),
    
    1. 不用self.view.addConstraint(...) 每个约束,您可以像这样轻松激活它们的列表:
    NSLayoutConstraint.activate([
        view.leftAnchor.constraint(equalTo: self.view.leftAnchor),
        view.rightAnchor.constraint(equalTo: self.view.rightAnchor),
        fieldBottomConstraint,
        view.heightAnchor.constraint(equalToConstant: 50),
    ])
    

    现在谈谈你的错误。

    1. 您正在使用frame 创建视图。当您使用约束时,这完全没有意义,因为自动布局会用约束计算的帧覆盖原始帧。
    2. 您没有对按钮提供任何限制,这就是它完全放错位置的原因
    3. 您需要将文本字段右侧附加到按钮左侧而不是超级视图右侧
    4. 如果您希望在没有键盘的情况下隐藏视图,则需要将 fieldBottomConstraint 常量设置为容器高度

    所以你的固定代码约束代码将如下所示:

    var customTextFieldBottomConstraint: NSLayoutConstraint!
    lazy var textFieldPanel: UIView = {
        let view = UIView(frame: CGRect(x: 0.0, y: self.view.bounds.height, width: self.view.bounds.width, height: 50.0))
        self.view.addSubview(view)
        view.backgroundColor = UIColor.white
        
        let fieldBottomConstraint = view.bottomAnchor.constraint(equalTo: self.view.safeAreaLayoutGuide.bottomAnchor, constant: -100)
        customTextFieldBottomConstraint = fieldBottomConstraint
        
        view.translatesAutoresizingMaskIntoConstraints = false
        NSLayoutConstraint.activate([
            view.leftAnchor.constraint(equalTo: self.view.leftAnchor),
            view.rightAnchor.constraint(equalTo: self.view.rightAnchor),
            fieldBottomConstraint,
            view.heightAnchor.constraint(equalToConstant: 50),
        ])
        return view
    }()
    
    lazy var customTextField: UITextField = {
        let field = UITextField()
        field.translatesAutoresizingMaskIntoConstraints = false
        textFieldPanel.addSubview(field)
        
        let button = UIButton()
        button.backgroundColor = UIColor.clear
        button.setTitle("Send", for: .normal)
        button.addTarget(self, action: #selector(buttonAction), for: .touchUpInside)
        button.translatesAutoresizingMaskIntoConstraints = false
        textFieldPanel.addSubview(button)
        
        NSLayoutConstraint.activate([
            field.leftAnchor.constraint(equalTo: textFieldPanel.leftAnchor),
            field.topAnchor.constraint(equalTo: textFieldPanel.topAnchor),
            field.bottomAnchor.constraint(equalTo: textFieldPanel.bottomAnchor),
            button.widthAnchor.constraint(equalToConstant: 200),
            button.leftAnchor.constraint(equalTo: field.rightAnchor),
            button.rightAnchor.constraint(equalTo: textFieldPanel.rightAnchor),
            button.topAnchor.constraint(equalTo: textFieldPanel.topAnchor),
            button.bottomAnchor.constraint(equalTo: textFieldPanel.bottomAnchor),
        ])
        return field
    }()
    

    最后一件事。当期望键盘出现时,您正在向约束中添加一个常量。但是键盘大小在不同的设备上是不同的,甚至在不同的系统设置下也是如此

    我建议你使用我的KeyboardNotifier。这个助手类将根据键盘出现/消失更新您的约束常量。不再需要在becomeFirstResponder 期间更新它。像这样初始化它:

    KeyboardNotifier(
        parentView: view,
        constraint: customTextFieldBottomConstraint
    )
    

    【讨论】:

    • 感谢您的回复。但是,您能否让我知道在此用例中如何使用keyboardNotifier。因为我想在 IBAction 中打开它。我不确定如何设置 customTextFieldBottomConstraint。
    • @dper 查看KeyboardNotifier 实现下的示例您需要在viewDidLoad 中初始化它并在viewWillAppear/viewWillDisappear 中启用/禁用它
    • 这很好,但是相同的约束值会是什么。使其适用于 iPad 的所有屏幕尺寸。
    • @dper 我不明白这个问题。它适用于所有设备,但不确定 iPad 分体键盘。
    • 我的意思是 customTextFieldBottomConstraint 的值,需要设置它才能初始化。很抱歉之前的混乱。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-16
    • 1970-01-01
    • 2011-08-20
    • 1970-01-01
    • 1970-01-01
    • 2015-05-01
    • 1970-01-01
    相关资源
    最近更新 更多