当我向其添加约束时,Swift 3中自定义UITextField的右占位符无法显示

时间:2016-10-07 08:01:18

标签: ios xcode ibdesignable

我是Swift 3的初学者,我打算在XCode 8中编写几个自定义控件(IBDesignable)。当我编写自定义文本字段时,我想为它添加正确的占位符。但是,只有当此文本字段没有约束时,才能成功显示正确的占位符。我不知道发生了什么事。

我希望有人可以帮我解决这个问题,非常感谢。

import UIKit

@IBDesignable
class RMLDesignableUITextField: UITextField {
    // MARK: PROPERTIES
    @IBInspectable var insetX: CGFloat = 0
    @IBInspectable var insetY: CGFloat = 0
    @IBInspectable var placeholderColor: UIColor = UIColor.white {
        didSet {
            if let placeholder = self.placeholder {
                let attributes = [NSForegroundColorAttributeName: placeholderColor]
                attributedPlaceholder = NSAttributedString(string: placeholder, attributes: attributes)
            }
        }
    }

    // MARK: Border
    var bottomBorder = CALayer()
    var rightBorder = CALayer()
    var topBorder = CALayer()
    var leftBorder = CALayer()
    @IBInspectable var showsTopBorder: Bool = false {
        didSet {
            setupSubviews()
        }
    }
    @IBInspectable var showsBottomBorder: Bool = false {
        didSet {
            setupSubviews()
        }
    }
    @IBInspectable var showsLeftBorder: Bool = false {
        didSet {
            setupSubviews()
        }
    }
    @IBInspectable var showsRightBorder: Bool = false {
        didSet {
            setupSubviews()
        }
    }
    @IBInspectable var borderColor: UIColor = UIColor.clear
    @IBInspectable var borderWidth: CGFloat = 0.0 {
        didSet {
            self.setNeedsDisplay()
        }
    }


    @IBInspectable var cornerRadius: CGFloat = 0 {
        didSet {
            layer.cornerRadius = cornerRadius
        }
    }

    @IBInspectable var rightPlaceholder: String = "" {
        didSet {
            rightPlaceholderLabel.text = rightPlaceholder
        }
    }

    fileprivate var fakePlaceholderLabel: UILabel!
    fileprivate var rightPlaceholderLabel: UILabel!
    fileprivate var translateX: CGFloat!
    {
        get {
            let attributes = [NSFontAttributeName: font!]
            let rightPlaceholderTextSize = rightPlaceholderLabel.text!.size(attributes: attributes)
            let rightPlaceholderTextWidth = rightPlaceholderTextSize.width
            let translateX = textRect(forBounds: bounds).width - rightPlaceholderTextWidth
            return translateX
        }
    }

    // MARK: Initializers
    override init(frame: CGRect) {
        super.init(frame: frame)
        // self.setNeedsDisplay()
    }

    required init(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)!
        // self.setNeedsDisplay()

        fakePlaceholderLabel = UILabel(frame: placeholderRect(forBounds: bounds))
        fakePlaceholderLabel.font = font
        fakePlaceholderLabel.text = placeholder
        fakePlaceholderLabel.textColor = UIColor.lightGray
        fakePlaceholderLabel.alpha = 0.0


        rightPlaceholderLabel = UILabel(frame: placeholderRect(forBounds: bounds))
        rightPlaceholderLabel.font = font
        rightPlaceholderLabel.text = rightPlaceholder
        rightPlaceholderLabel.textColor = UIColor.lightGray
        rightPlaceholderLabel.alpha = 0.0

    }

    override func layoutSubviews() {
        super.layoutSubviews()

        addSubview(fakePlaceholderLabel)
        addSubview(rightPlaceholderLabel)
        setupSubviews()
        setNeedsDisplay()
    }
}

// MARK: - Lifecycle
extension RMLDesignableUITextField {

    override func awakeFromNib() {
        super.awakeFromNib()
    }

    override var intrinsicContentSize : CGSize {
        return CGSize(width: UIViewNoIntrinsicMetric, height: UIViewNoIntrinsicMetric)
    }

    override func prepareForInterfaceBuilder() {
        //setupSubviews()
    }
}

// MARK: - Delegate Methods
extension RMLDesignableUITextField {
    // placeholder position
    override func textRect(forBounds bounds: CGRect) -> CGRect {
        return bounds.insetBy(dx: insetX, dy: insetY)
    }

    // text position
    override func editingRect(forBounds bounds: CGRect) -> CGRect {
        return bounds.insetBy(dx: insetX, dy: insetY)
    }
}

// MARK: - UITextField Observing
extension RMLDesignableUITextField {

    override internal func willMove(toSuperview newSuperview: UIView!) {
        if newSuperview != nil {
            NotificationCenter.default.addObserver(self, selector: #selector(RMLDesignableUITextField.didBeginEditing(_:)), name: NSNotification.Name.UITextFieldTextDidBeginEditing, object: self)

            NotificationCenter.default.addObserver(self, selector: #selector(RMLDesignableUITextField.didEndEditing(_:)), name: NSNotification.Name.UITextFieldTextDidEndEditing, object: self)
        } else {
            NotificationCenter.default.removeObserver(self)
        }
    }

    func didBeginEditing(_ notification: Notification) {
        placeholder = nil

        if notification.object as! RMLDesignableUITextField === self{
            UIView.animate(withDuration: 0.5, delay: 0.0, usingSpringWithDamping: 0.4, initialSpringVelocity: 0, options: .curveEaseIn, animations: { () -> Void in
                if self.text!.isEmpty {
                    self.fakePlaceholderLabel.transform = self.fakePlaceholderLabel.transform.translatedBy(x: self.translateX, y: 0.0)
                    self.fakePlaceholderLabel.alpha = 0.0

                    self.rightPlaceholderLabel.transform = self.rightPlaceholderLabel.transform.translatedBy(x: self.translateX, y: 0.0)
                    self.rightPlaceholderLabel.alpha = 1.0
                }
            }, completion: nil)
        }
    }

    func didEndEditing(_ notification: Notification) {
        if notification.object as! RMLDesignableUITextField === self {
            UIView.animate(withDuration: 0.5, delay: 0.0, usingSpringWithDamping: 0.4, initialSpringVelocity: 0, options: .curveEaseIn, animations: { () -> Void in
                if self.text!.isEmpty {
                    self.fakePlaceholderLabel.transform = self.fakePlaceholderLabel.transform.translatedBy(x: -self.translateX, y: 0.0)
                    self.fakePlaceholderLabel.alpha = 1.0

                    self.rightPlaceholderLabel.transform = self.rightPlaceholderLabel.transform.translatedBy(x: -self.translateX, y: 0.0)
                    self.rightPlaceholderLabel.alpha = 0.0
                }
            }, completion: nil)
        }
    }
}

// MARK: - Methods

extension RMLDesignableUITextField {

    fileprivate func pnpAddBorder(_ border: CALayer, color: UIColor, frame: CGRect) {

        border.backgroundColor = color.cgColor
        border.frame = frame

        layer.addSublayer(border)
        // layer.masksToBounds = true
    }

    func pnpAddTopBorder(_ width: CGFloat, color: UIColor = UIColor.black) {
        pnpAddBorder(topBorder, color: color, frame: CGRect(x: 0, y: 0, width: frame.width, height: width))
    }

    func pnpAddBottomBorder(_ width: CGFloat, color: UIColor = UIColor.black) {
        pnpAddBorder(bottomBorder, color: color, frame: CGRect(x: 0, y: frame.height - width, width: frame.width, height: width))
    }

    func pnpAddLeftBorder(_ width: CGFloat, color: UIColor = UIColor.black) {
        pnpAddBorder(leftBorder, color: color, frame: CGRect(x: 0, y: 0, width: width, height: frame.height))
    }

    func pnpAddRightBorder(_ width: CGFloat, color: UIColor = UIColor.black) {
        pnpAddBorder(rightBorder, color: color, frame: CGRect(x: frame.width - width, y: 0, width: width, height: frame.height))
    }

    func setupSubviews() {
        // if (showsTopBorder || showsBottomBorder || showsLeftBorder || showsRightBorder) && borderWidth == 0 {
        // borderWidth = 1
        // }

        if showsTopBorder {
            pnpAddTopBorder(borderWidth, color: borderColor)
        } else {
            topBorder.removeFromSuperlayer()
        }

        if showsBottomBorder {
            pnpAddBottomBorder(borderWidth, color: borderColor)
        } else {
            bottomBorder.removeFromSuperlayer()
        }

        if showsLeftBorder {
            pnpAddLeftBorder(borderWidth, color: borderColor)
        } else {
            leftBorder.removeFromSuperlayer()
        }

        if showsRightBorder {
            pnpAddRightBorder(borderWidth, color: borderColor)
        } else {
            rightBorder.removeFromSuperlayer()
        }

        self.setNeedsDisplay()
    }
}

0 个答案:

没有答案