为啥文本字段的底线不遵循 Swift 中的约束规则?

Posted

技术标签:

【中文标题】为啥文本字段的底线不遵循 Swift 中的约束规则?【英文标题】:Why bottom line for text field does not follow the constraints rule in Swift?为什么文本字段的底线不遵循 Swift 中的约束规则? 【发布时间】:2021-12-31 05:40:54 【问题描述】:

这是我项目中的实用程序文件,我在其中设置了文本字段的底线:

import Foundation
import UIKit

class Utilities 

    static func styleTextField(_ textfield:UITextField) 
    
        let bottomLine = CALayer()
    
        bottomLine.frame = CGRect(x: 0, y: textfield.frame.height - 2, width: textfield.frame.width, height: 2)
    
        bottomLine.backgroundColor = UIColor.init(red: 255/255, green: 77/255, blue: 0/255, alpha: 1).cgColor
    
        textfield.borderStyle = .none
    
        textfield.layer.addSublayer(bottomLine)
    
    
    static func styleFilledButton(_ button:UIButton) 
    
        button.backgroundColor = UIColor.init(red: 255/255, green: 77/255, blue: 0/255, alpha: 1)
        button.layer.cornerRadius = 25.0
        button.tintColor = UIColor.white
    
    static func styleFilledButtonweb(_ button:UIButton) 
  
        button.backgroundColor = UIColor.init(red: 255/255, green: 77/255, blue: 0/255, alpha: 1)
        button.layer.cornerRadius = 5.0
        button.tintColor = UIColor.white
    
    static func styleHollowButton(_ button:UIButton) 
    
        button.layer.borderWidth = 2
        button.layer.borderColor = UIColor.init(red: 255/255, green: 77/255, blue: 0/255, alpha: 1).cgColor
        button.layer.cornerRadius = 25.0
        button.tintColor = UIColor.init(red: 255/255, green: 77/255, blue: 0/255, alpha: 1)
     

这是我使用 styleTextField 函数的视图控制器文件:

import UIKit
import FirebaseAuth
import Firebase



class SignUpViewController: UIViewController, UITextFieldDelegate 


    @IBOutlet weak var firstNameTextField: UITextField! 
        didSet 
            var whitePlaceholderText = NSMutableAttributedString()
            let Name  = "Ad"

            whitePlaceholderText = NSMutableAttributedString(string:Name, attributes: [NSAttributedString.Key.font:UIFont(name: "Helvetica Neue", size: 15)!]) // Font
            whitePlaceholderText.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.white, range:NSRange(location:0,length:Name.count))    // Color
            firstNameTextField.attributedPlaceholder = whitePlaceholderText
        
    
    @IBOutlet weak var lastNameTextField: UITextField! 
        didSet 
            var whitePlaceholderText = NSMutableAttributedString()
            let Name  = "Soyad"

            whitePlaceholderText = NSMutableAttributedString(string:Name, attributes: [NSAttributedString.Key.font:UIFont(name: "Helvetica Neue", size: 15)!]) // Font
            whitePlaceholderText.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.white, range:NSRange(location:0,length:Name.count))    // Color
            lastNameTextField.attributedPlaceholder = whitePlaceholderText
        
    
    @IBOutlet weak var emailTextField: UITextField! 
        didSet 
            var whitePlaceholderText = NSMutableAttributedString()
            let Name  = "Email"

            whitePlaceholderText = NSMutableAttributedString(string:Name, attributes: [NSAttributedString.Key.font:UIFont(name: "Helvetica Neue", size: 15)!]) // Font
            whitePlaceholderText.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.white, range:NSRange(location:0,length:Name.count))    // Color
            emailTextField.attributedPlaceholder = whitePlaceholderText
        
    
    @IBOutlet weak var passwordTextField: UITextField! 
        didSet 
            var whitePlaceholderText = NSMutableAttributedString()
            let Name  = "Şifre"

            whitePlaceholderText = NSMutableAttributedString(string:Name, attributes: [NSAttributedString.Key.font:UIFont(name: "Helvetica Neue", size: 15)!]) // Font
            whitePlaceholderText.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.white, range:NSRange(location:0,length:Name.count))    // Color
            passwordTextField.attributedPlaceholder = whitePlaceholderText
        
    
    @IBOutlet weak var passworddogrulaTextField: UITextField! 
        didSet 
            var whitePlaceholderText = NSMutableAttributedString()
            let Name  = "Şifreyi Doğrula"

            whitePlaceholderText = NSMutableAttributedString(string:Name, attributes: [NSAttributedString.Key.font:UIFont(name: "Helvetica Neue", size: 15)!]) // Font
            whitePlaceholderText.addAttribute(NSAttributedString.Key.foregroundColor, value: UIColor.white, range:NSRange(location:0,length:Name.count))    // Color
            passworddogrulaTextField.attributedPlaceholder = whitePlaceholderText
        
    

    @IBOutlet weak var signUpButton: UIButton!
    @IBOutlet weak var errorLabel: UILabel!    

    let Button = UIButton(type: .custom)
    let Button1 = UIButton(type: .custom)


    override func viewDidLoad() 
        super.viewDidLoad()
        self.hideKeyboardWhenTappedAround()
        setUpElements()
        show_hide_password(textfield: passwordTextField)
        show_hide_password1(textfield: passworddogrulaTextField)
        self.passwordTextField.delegate = self
        self.passworddogrulaTextField.delegate = self
        self.emailTextField.delegate = self
        self.lastNameTextField.delegate = self
        self.firstNameTextField.delegate = self
    
    

    func textFieldShouldReturn(_ textField: UITextField) -> Bool 
    vself.view.endEditing(true)
        return false
    

    func show_hide_password(textfield: UITextField) 
        textfield.rightViewMode = .unlessEditing
        Button.setImage(UIImage(systemName: "eye.slash.fill"), for: .normal)
        Button.imageEdgeInsets = UIEdgeInsets(top: 5, left: -24, bottom: 5, right: 15)
        Button.frame = CGRect(x: CGFloat(textfield.frame.size.width - 25), y: CGFloat(5), width: CGFloat(15), height: CGFloat(25))
        Button.addTarget(self, action: #selector(self.btnVisibilityClicked), for: .touchUpInside)
        textfield.rightView = Button
        textfield.rightViewMode = .always
    
    func show_hide_password1(textfield: UITextField) 
        textfield.rightViewMode = .unlessEditing
        Button1.setImage(UIImage(systemName: "eye.slash.fill"), for: .normal)
        Button1.imageEdgeInsets = UIEdgeInsets(top: 5, left: -24, bottom: 5, right: 15)
        Button1.frame = CGRect(x: CGFloat(textfield.frame.size.width - 25), y: CGFloat(5), width: CGFloat(15), height: CGFloat(25))
        Button1.addTarget(self, action: #selector(self.btnVisibilityClicked1), for: .touchUpInside)
        textfield.rightView = Button1
        textfield.rightViewMode = .always
    

    @IBAction func btnVisibilityClicked(_ sender: Any) 
        (sender as! UIButton).isSelected = !(sender as! UIButton).isSelected
        if (sender as! UIButton).isSelected
            self.passwordTextField.isSecureTextEntry = false
            Button.setImage(UIImage(systemName: "eye.fill"), for: .normal)
         else 
            self.passwordTextField.isSecureTextEntry = true
            Button.setImage(UIImage(systemName: "eye.slash.fill"), for: .normal)
        
   
    @IBAction func btnVisibilityClicked1(_ sender: Any) 
        (sender as! UIButton).isSelected = !(sender as! UIButton).isSelected
        if (sender as! UIButton).isSelected
            self.passworddogrulaTextField.isSecureTextEntry = false
            Button1.setImage(UIImage(systemName: "eye.fill"), for: .normal)
         else 
            self.passworddogrulaTextField.isSecureTextEntry = true
            Button1.setImage(UIImage(systemName: "eye.slash.fill"), for: .normal)
        
    

    func setUpElements()
        errorLabel.alpha = 0
        Utilities.styleTextField(firstNameTextField)
        Utilities.styleTextField(lastNameTextField)
        Utilities.styleTextField(emailTextField)
        Utilities.styleTextField(passwordTextField)
        Utilities.styleTextField(passworddogrulaTextField)
        Utilities.styleFilledButton(signUpButton)
    

这里是故事板的屏幕截图Connection for the text fields and the screenshot of sign up page storyboard 以及故事板和视图控制器之间的连接:

即使我声明了约束,底线似乎也不正确。我应该怎么做才能让它看起来正确?

这是错误外观的截图:The appearance of the text field in iPhone 12 Pro Max

下面是Xcode for iPhone 11模拟器中正确外观的截图:The simulator of iPhone 11 and the correct appearance

感谢您的帮助!这是草稿的video link。

【问题讨论】:

【参考方案1】:

您在布局设置之前设置这些。如果你在 UIView 类中有你的视图,你可以把它们放在 layoutSubviews() 由于您是在 viewController 中设置这些,因此将 setUpElements() 放入 viewDidAppear() 可能会解决您的问题。

【讨论】:

感谢您的帮助!还有一个问题。当我将 setUpElements() 添加到 viewDidAppear() 中时,设置元素会有一点延迟。如何避免这种延迟? 我认为 viewDidLayoutSubviews() 最适合你

以上是关于为啥文本字段的底线不遵循 Swift 中的约束规则?的主要内容,如果未能解决你的问题,请参考以下文章

富文本字段的使用规则?

为啥 Chrome 不缓存我的动态表单字段?

在 Swift 中显示 UITextField 的底部边框不适用于约束。

为啥我无法在 Swift 的登录按钮中验证 textFields

Swift 多文本字段参数

将 uipangesture 应用于 uitextfield