diff --git a/YDS-Storybook/AtomSampleViewController/TextViewViewController.swift b/YDS-Storybook/AtomSampleViewController/TextViewViewController.swift index d8f2b7b6..94080a97 100644 --- a/YDS-Storybook/AtomSampleViewController/TextViewViewController.swift +++ b/YDS-Storybook/AtomSampleViewController/TextViewViewController.swift @@ -37,7 +37,16 @@ class TextViewViewController: StoryBookViewController { return button }() - private lazy var textView = YDSTextView(maxHeight: maxHeight) + private lazy var textView: YDSTextView = { + let textView = YDSTextView(maxHeight: maxHeight) + textView.delegate = self + textView.isScrollEnabled = false + textView.isEditable = true + textView.textContainerInset = .init(top: 12, left: 0, bottom: 12, right: 0) + textView.placeholder = YDSPlaceholder.comment + return textView + }() + private lazy var titleLabel: YDSLabel = { let label = YDSLabel(style: .subtitle2) label.textColor = YDSColor.textPrimary @@ -53,14 +62,8 @@ class TextViewViewController: StoryBookViewController { override func viewDidLoad() { super.viewDidLoad() - textView.delegate = self - textView.isScrollEnabled = false - textView.isEditable = true - textView.textContainerInset = .init(top: 12, left: 0, bottom: 12, right: 0) - textView.placeholder = YDSPlaceholder.comment - setupView() - stateLabel.text = textView.attributedText.isEmpty.description + addOptions() } private let maxHeight: CGFloat = 150 @@ -72,6 +75,7 @@ class TextViewViewController: StoryBookViewController { private func setViewProperty() { title = "TextView" + stateLabel.text = textView.attributedText.isEmpty.description } private func setViewLayouts() { @@ -112,6 +116,34 @@ class TextViewViewController: StoryBookViewController { } } + private func addOptions() { + addOption(description: "textColor", + cases: textColors.items, + defaultIndex: 0) { [weak self] colorInfo in + self?.textView.textColor = colorInfo.color + } + + addOption(description: "lineBreakMode", + cases: NSLineBreakMode.allCases, + defaultIndex: 0) { [weak self] value in + self?.textView.lineBreakMode = value + } + + if #available(iOS 14.0, *) { + addOption(description: "lineBreakStrategy", + cases: NSParagraphStyle.LineBreakStrategy.allCases, + defaultIndex: 2) { [weak self] value in + self?.textView.lineBreakStrategy = value + } + } + + addOption(description: "placeholder", + cases: textColors.items, + defaultIndex: 2) { [weak self] colorInfo in + self?.textView.placeholderColor = colorInfo.color + } + } + override func touchesBegan(_ touches: Set, with event: UIEvent?) { super.touchesBegan(touches, with: event) guard let touch = touches.first else { return } diff --git a/YDS/Source/Atom/YDSTextView.swift b/YDS/Source/Atom/YDSTextView.swift index 89f28dda..88679495 100644 --- a/YDS/Source/Atom/YDSTextView.swift +++ b/YDS/Source/Atom/YDSTextView.swift @@ -11,22 +11,43 @@ import SnapKit public class YDSTextView: UITextView { public override var text: String? { - didSet { setNeedsLayout() } + didSet { textDidChange() } } public override var attributedText: NSAttributedString? { - didSet { setNeedsLayout() } + didSet { textDidChange() } } public override var textColor: UIColor! { - didSet { setNeedsLayout() } + didSet { textColorDidChange() } } - @SetNeeds(.layout) public var style: String.TypoStyle = .body1 - @SetNeeds(.layout) public var lineBreakMode: NSLineBreakMode? = nil - @SetNeeds(.layout) public var lineBreakStrategy: NSParagraphStyle.LineBreakStrategy? = nil - @SetNeeds(.layout) public var placeholder: String? = nil - @SetNeeds(.layout) public var placeholderColor: UIColor = YDSColor.textTertiary + public var style: String.TypoStyle = .body1 { + didSet { setTextStyle() } + } + public var lineBreakMode: NSLineBreakMode? = nil { + didSet { setTextStyle() } + } + public var lineBreakStrategy: NSParagraphStyle.LineBreakStrategy? = nil { + didSet { setTextStyle() } + } + + public var placeholder: String? = nil { + didSet { + + if let placeholder = placeholder { + registerPlaceholder(placeholder) + } else { + removePlaceholder() + } + } + } + + public var placeholderColor: UIColor! = YDSColor.textTertiary { + didSet { + placeholderLabel?.textColor = placeholderColor + } + } private var placeholderLabel: YDSLabel? private let maxHeight: CGFloat? @@ -38,7 +59,7 @@ public class YDSTextView: UITextView { self.maxHeight = maxHeight super.init(frame: .zero, textContainer: nil) self.tintColor = YDSColor.textPointed - setTextStyle() + typingAttributes = makeTextStyle() } required init?(coder: NSCoder) { @@ -57,17 +78,6 @@ public class YDSTextView: UITextView { if isScrollEnabled == false { invalidateIntrinsicContentSize() } - - setTextStyle() - textDidChange() - - if let placeholder = placeholder { - registerPlaceholder(placeholder) - } else { - removePlaceholder() - } - - placeholderLabel?.textColor = placeholderColor } // MARK: - Public func @@ -131,10 +141,26 @@ public class YDSTextView: UITextView { return contentSize.height >= maxHeight } + private func makeTextStyle() -> [NSAttributedString.Key : Any] { + return style.style(color: textColor, + lineBreakMode: lineBreakMode, + lineBreakStrategy: lineBreakStrategy) + } + private func setTextStyle() { - typingAttributes = style.style(color: textColor, - lineBreakMode: lineBreakMode, - lineBreakStrategy: lineBreakStrategy) + let attributes = makeTextStyle() + + if let attributedText = attributedText { + let attributedString = NSAttributedString(string: attributedText.string, attributes: attributes) + self.attributedText = attributedString + } + typingAttributes = attributes + } + + private func textColorDidChange() { + if let textColor = textColor { + typingAttributes.updateValue(textColor, forKey: .foregroundColor) + } } @objc