0
如何創建一個IBDesignable UITextView
,以便我可以調整界面構建器中文本的內插值?我已經添加了檢查屬性topInset
,bottomInset
等,但現在我無法弄清楚如何實際更新UITextView
這樣的插圖,這些變化反映在IBUITextView IBDesignable填充
import UIKit
private let kPlaceholderTextViewInsetSpan: CGFloat = 8
@IBDesignable class UIDesignableTextView: UITextView {
// variables
@IBInspectable var topInset: CGFloat = 0.0
@IBInspectable var leftInset: CGFloat = 0.0
@IBInspectable var bottomInset: CGFloat = 0.0
@IBInspectable var rightInset: CGFloat = 0.0
var insets: UIEdgeInsets {
get {
return UIEdgeInsetsMake(topInset, leftInset, bottomInset, rightInset)
}
set {
topInset = newValue.top
leftInset = newValue.left
bottomInset = newValue.bottom
rightInset = newValue.right
}
}
@IBInspectable var placeholder: NSString? { didSet { setNeedsDisplay() } }
@IBInspectable var placeholderColor: UIColor = UIColor.lightGray
override var text: String! { didSet { setNeedsDisplay() } }
override var attributedText: NSAttributedString! { didSet { setNeedsDisplay() } }
override var contentInset: UIEdgeInsets { didSet { setNeedsDisplay() } }
override var font: UIFont? { didSet { setNeedsDisplay() } }
override var textAlignment: NSTextAlignment { didSet { setNeedsDisplay() } }
// MARK: - Lifecycle
/** Override coder init, for IB/XIB compatibility */
#if !TARGET_INTERFACE_BUILDER
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
listenForTextChangedNotifications()
}
/** Override common init, for manual allocation */
override init(frame: CGRect, textContainer: NSTextContainer?) {
super.init(frame: frame, textContainer: textContainer)
listenForTextChangedNotifications()
}
#endif
/** Initializes the placeholder text view, waiting for a notification of text changed */
func listenForTextChangedNotifications() {
NotificationCenter.default.addObserver(self, selector: #selector(UIDesignableTextView.textChangedForPlaceholderTextView(_:)), name:NSNotification.Name.UITextViewTextDidChange , object: self)
NotificationCenter.default.addObserver(self, selector: #selector(UIDesignableTextView.textChangedForPlaceholderTextView(_:)), name:NSNotification.Name.UITextViewTextDidBeginEditing , object: self)
}
/** willMoveToWindow will get called with a nil argument when the window is about to dissapear */
override func willMove(toWindow newWindow: UIWindow?) {
super.willMove(toWindow: newWindow)
if newWindow == nil { NotificationCenter.default.removeObserver(self) }
else { listenForTextChangedNotifications() }
}
func textChangedForPlaceholderTextView(_ notification: Notification) {
setNeedsDisplay()
setNeedsLayout()
}
override func draw(_ rect: CGRect) {
super.draw(rect)
if text.characters.count == 0 && self.placeholder != nil {
let baseRect = placeholderBoundsContainedIn(self.bounds)
let font = self.font ?? self.typingAttributes[NSFontAttributeName] as? UIFont ?? UIFont.systemFont(ofSize: UIFont.systemFontSize)
self.placeholderColor.set()
var customParagraphStyle: NSMutableParagraphStyle!
if let defaultParagraphStyle = typingAttributes[NSParagraphStyleAttributeName] as? NSParagraphStyle {
customParagraphStyle = defaultParagraphStyle.mutableCopy() as! NSMutableParagraphStyle
} else { customParagraphStyle = NSMutableParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle }
// set attributes
customParagraphStyle.lineBreakMode = NSLineBreakMode.byTruncatingTail
customParagraphStyle.alignment = self.textAlignment
let attributes = [NSFontAttributeName: font, NSParagraphStyleAttributeName: customParagraphStyle.copy() as! NSParagraphStyle, NSForegroundColorAttributeName: self.placeholderColor]
// draw in rect.
self.placeholder?.draw(in: baseRect, withAttributes: attributes)
}
}
func placeholderBoundsContainedIn(_ containerBounds: CGRect) -> CGRect {
// get the base rect with content insets.
let baseRect = UIEdgeInsetsInsetRect(containerBounds, UIEdgeInsetsMake(kPlaceholderTextViewInsetSpan, kPlaceholderTextViewInsetSpan/2.0, 0, 0))
// adjust typing and selection attributes
if let paragraphStyle = typingAttributes[NSParagraphStyleAttributeName] as? NSParagraphStyle {
baseRect.offsetBy(dx: paragraphStyle.headIndent, dy: paragraphStyle.firstLineHeadIndent)
}
return baseRect
}
這是否幫助回答你的問題?讓我知道你是否仍在試圖弄清楚這一點。 – eschos24