从自定义 @IBDesignable UITextField class 控制占位符文本颜色。 Swift4.2,Xcode10

Controlling place holder text color from custom @IBDesignable UITextField class. Swift 4.2, Xcode 10

我创建了Cocoa触摸Class:

这里是 MyTextFieldStyle.swift 文件:

import UIKit

@IBDesignable

class MyTextFieldStyle: UITextField {

@IBInspectable var FavoriteTextColor : UIColor = UIColor.white {
    didSet {
        self.textColor = FavoriteTextColor
    }
}

override func awakeFromNib() {
    super.awakeFromNib()
    self.textColor = self.FavoriteTextColor
}

}

如何添加这 3 个控件,

喜欢上面的'FavoriteTextColor'? (Swift 4.2 & Xcode 10)

我会 IBDesignables 做不同的事情。我会把我所有的最终任务都放在同一个函数中,例如这里是我自己的自定义 UITextField 我使用。

@IBDesignable public class HooopTextfield: UITextField, UITextFieldDelegate {

    @IBInspectable public var fontName: String? = "AvenirNext-Bold" {
        didSet {
            decorate()
        }
    }

    @IBInspectable public var fontSize: CGFloat = 15 {
        didSet {
            decorate()
        }
    }

    @IBInspectable public var fontColor: UIColor = UIColor.white {
        didSet {
            decorate()
        }
    }

    @IBInspectable public var customTextAlignment: Int = 0 {
        didSet {
            decorate()
        }
    }

    @IBInspectable public var borderColor: UIColor = UIColor.white {
        didSet {
            decorate()
        }
    }

    @IBInspectable public var letterSpacing: CGFloat = 0 {
        didSet {
            decorate()
        }
    }

    @IBInspectable public var cornerRadius: CGFloat = 0 {
        didSet {
            decorate()
        }
    }

    @IBInspectable public var customPlaceholder: String? = nil {
        didSet {
            decorate()
        }
    }

    @IBInspectable public var horizontalInset: CGFloat = 0 {
        didSet {
            decorate()
        }
    }

    @IBInspectable public var verticalInset: CGFloat = 0 {
        didSet {
            decorate()
        }
    }

    @IBInspectable public var selfDelegate: Bool = false {
        didSet {
            if selfDelegate {
                self.delegate = self
            }
        }
    }

    @IBInspectable public var borderWidth: CGFloat = 0 {
        didSet {
            decorate()
        }
    }

    @IBInspectable public var baseLineOffset: CGFloat = 0 {
        didSet {
            decorate()
        }
    }

    @IBInspectable public var placeholderColor: UIColor? = nil {
        didSet {
            decorate()
        }
    }

    @IBInspectable public var requiredColor: UIColor? = nil {
        didSet {
            decorate()
        }
    }

    @IBInspectable public var requiredCharacter: String = "*"{
        didSet {
            decorate()
        }
    }

    @IBOutlet public var nextField:HooopTextfield?

    /*** more inspectable var can be added **/

    override public func textRect(forBounds bounds: CGRect) -> CGRect {
        return bounds.insetBy(dx: horizontalInset, dy: verticalInset)
    }

    override public func editingRect(forBounds bounds: CGRect) -> CGRect {
        return bounds.insetBy(dx: horizontalInset, dy: verticalInset)
    }

    func decorate() {
        // Setup border and corner radius
        self.layer.cornerRadius = cornerRadius
        self.layer.borderWidth = borderWidth
        self.layer.borderColor = borderColor.cgColor
        // Setup text style
        let paragraphStyle: NSMutableParagraphStyle = NSMutableParagraphStyle()
        switch customTextAlignment {
        case 2:
            paragraphStyle.alignment = .right
            break
        case 1:
            paragraphStyle.alignment = .center
            break
        default:
            paragraphStyle.alignment = .left
            break
        }
        var titleAttributes:[NSAttributedStringKey : Any] = [
            NSAttributedStringKey.foregroundColor: fontColor,
            NSAttributedStringKey.kern: letterSpacing,
            NSAttributedStringKey.baselineOffset: baseLineOffset,
            NSAttributedStringKey.paragraphStyle: paragraphStyle
        ]
        if let _ = fontName {
            titleAttributes[NSAttributedStringKey.font] = UIFont(name: fontName!, size: fontSize)
        }
        if let _ = customPlaceholder {
            var placeholderAttributes = titleAttributes
            if let _ = placeholderColor {
                placeholderAttributes[NSAttributedStringKey.foregroundColor] = placeholderColor
            }
            let attributedPlaceholder = NSMutableAttributedString(string: customPlaceholder!, attributes: placeholderAttributes)
            if let _ = requiredColor {
                let range = (customPlaceholder! as NSString).range(of: requiredCharacter)
                attributedPlaceholder.addAttribute(NSAttributedStringKey.foregroundColor, value: requiredColor!, range: range)
            }
            self.attributedPlaceholder = attributedPlaceholder
        }
        self.defaultTextAttributes = titleAttributes
    }

    // MARK: - UITexfieldDelegate

    public func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        if (nextField != nil) {
            nextField?.becomeFirstResponder()
        }
        return true
    }
}

我有一些基本的东西,比如 fontColorfontSizefontName,占位符也是一样。然后我有更多视觉效果,如 borderColorcornerRadiusborderWidth 等。最后我还有一些插入矩形定位,可以根据我的故事板中的意愿对齐所有内容。 我对这些使用 NSMutableAttributedString,因为它们是最可定制的,让我也能够为必填字段等着色。

最后,我还有一个 @IBOutlet,当它与一个名为 selfDelegate.[=33 的布尔值结合使用时,它还允许我使用键盘上的下一个按钮从一个文本字段跳转到下一个文本字段=]

问我任何你想问的关于这个的问题并尝试一下你应该可以用 @IBDesignable 我想做任何你想做的事。

编辑 1: 在我忘记之前,我建议使用 decorate 或等效函数,因为大多数时候应用更改的顺序很重要。

编辑 2: 修复了错误,这很可能是由于 swift 更改了 NSAttributedString 属性的使用方式,但奇怪的是 placeholderAttributes 似乎需要 [NSAttributedStringKey: Any]defaultTextAttributes 需要 [String: Any] 不知道为什么会这样。不过现在应该可以了。

编辑 3: 可能是因为我有不同版本的 Xcode 或者因为它是一个游乐场,我收到了一条关于 defaultTextAttributes 的消息,但我已经通过删除 .rawValue 重新修复它,如果它与需要完成的相反,知道 NSAttributedStringKey.key.rawValue 将是一个字符串,您可以使用 NSAttributedStringKey.init(rawValue:String)

获得 NSAttributedStringKey