Merge branch 'mbruce/textArea' into 'feature/TextArea'
allow overriding See merge request BPHV_MIPS/vds_ios!161
This commit is contained in:
commit
2ff683e087
@ -398,13 +398,18 @@ open class Notification: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func setConstraints() {
|
private func setConstraints() {
|
||||||
|
maxWidthConstraint?.deactivate()
|
||||||
|
labelViewAndButtonViewConstraint?.deactivate()
|
||||||
|
labelViewBottomConstraint?.deactivate()
|
||||||
|
buttonGroupCenterYConstraint?.deactivate()
|
||||||
|
buttonGroupBottomConstraint?.deactivate()
|
||||||
maxWidthConstraint?.constant = maxViewWidth
|
maxWidthConstraint?.constant = maxViewWidth
|
||||||
maxWidthConstraint?.isActive = UIDevice.isIPad
|
maxWidthConstraint?.isActive = UIDevice.isIPad
|
||||||
labelViewAndButtonViewConstraint?.isActive = layout == .vertical && !buttonGroup.buttons.isEmpty
|
labelViewAndButtonViewConstraint?.isActive = layout == .vertical && !buttonGroup.buttons.isEmpty
|
||||||
typeIconWidthConstraint?.constant = typeIcon.size.dimensions.width
|
|
||||||
closeIconWidthConstraint?.constant = closeButton.size.dimensions.width
|
|
||||||
labelViewBottomConstraint?.isActive = layout == .horizontal || buttonGroup.buttons.isEmpty
|
labelViewBottomConstraint?.isActive = layout == .horizontal || buttonGroup.buttons.isEmpty
|
||||||
buttonGroupCenterYConstraint?.isActive = layout == .horizontal
|
buttonGroupCenterYConstraint?.isActive = layout == .horizontal
|
||||||
buttonGroupBottomConstraint?.isActive = layout == .vertical
|
buttonGroupBottomConstraint?.isActive = layout == .vertical
|
||||||
|
typeIconWidthConstraint?.constant = typeIcon.size.dimensions.width
|
||||||
|
closeIconWidthConstraint?.constant = closeButton.size.dimensions.width
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -180,6 +180,12 @@ open class EntryFieldBase: Control, Changeable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Override this to conveniently get/set the textfield(s).
|
||||||
|
open var text: String? {
|
||||||
|
get { nil }
|
||||||
|
set { fatalError("You MUST override EntryField's 'text' variable in your subclass.") }
|
||||||
|
}
|
||||||
|
|
||||||
open var tooltipModel: Tooltip.TooltipModel? { didSet { setNeedsUpdate() } }
|
open var tooltipModel: Tooltip.TooltipModel? { didSet { setNeedsUpdate() } }
|
||||||
|
|
||||||
open var transparentBackground: Bool = false { didSet { setNeedsUpdate() } }
|
open var transparentBackground: Bool = false { didSet { setNeedsUpdate() } }
|
||||||
|
|||||||
@ -78,6 +78,14 @@ open class InputField: EntryFieldBase, UITextFieldDelegate {
|
|||||||
/// Representing the type of input.
|
/// Representing the type of input.
|
||||||
open var fieldType: FieldType = .text { didSet { setNeedsUpdate() } }
|
open var fieldType: FieldType = .text { didSet { setNeedsUpdate() } }
|
||||||
|
|
||||||
|
/// The text of this textField.
|
||||||
|
open override var text: String? {
|
||||||
|
get { textField.text }
|
||||||
|
set {
|
||||||
|
textField.text = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var _showError: Bool = false
|
var _showError: Bool = false
|
||||||
/// Whether not to show the error.
|
/// Whether not to show the error.
|
||||||
open override var showError: Bool {
|
open override var showError: Bool {
|
||||||
|
|||||||
@ -107,20 +107,21 @@ open class TextArea: EntryFieldBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The text of this textField.
|
||||||
|
open override var text: String? {
|
||||||
|
get { textView.text }
|
||||||
|
set {
|
||||||
|
textView.text = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// UITextView shown in the TextArea.
|
/// UITextView shown in the TextArea.
|
||||||
open var textView = UITextView().with {
|
open var textView = TextView().with {
|
||||||
$0.translatesAutoresizingMaskIntoConstraints = false
|
$0.translatesAutoresizingMaskIntoConstraints = false
|
||||||
$0.font = TextStyle.bodyLarge.font
|
|
||||||
$0.sizeToFit()
|
$0.sizeToFit()
|
||||||
$0.isScrollEnabled = false
|
$0.isScrollEnabled = false
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Color configuration for the textView.
|
|
||||||
open var textViewTextColorConfiguration: AnyColorable = ViewColorConfiguration().with {
|
|
||||||
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forDisabled: true)
|
|
||||||
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forDisabled: false)
|
|
||||||
}.eraseToAnyColorable() { didSet { setNeedsUpdate() } }
|
|
||||||
|
|
||||||
/// Color configuration for error icon.
|
/// Color configuration for error icon.
|
||||||
internal var iconColorConfiguration = ControlColorConfiguration().with {
|
internal var iconColorConfiguration = ControlColorConfiguration().with {
|
||||||
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .normal)
|
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forState: .normal)
|
||||||
@ -185,7 +186,9 @@ open class TextArea: EntryFieldBase {
|
|||||||
super.updateView()
|
super.updateView()
|
||||||
|
|
||||||
textView.isEditable = isEnabled
|
textView.isEditable = isEnabled
|
||||||
textView.textColor = textViewTextColorConfiguration.getColor(self)
|
textView.isEnabled = isEnabled
|
||||||
|
textView.surface = surface
|
||||||
|
|
||||||
//set the width constraints
|
//set the width constraints
|
||||||
if let width {
|
if let width {
|
||||||
widthConstraint?.constant = width
|
widthConstraint?.constant = width
|
||||||
@ -258,12 +261,18 @@ open class TextArea: EntryFieldBase {
|
|||||||
|
|
||||||
open func highlightCharacterOverflow() {
|
open func highlightCharacterOverflow() {
|
||||||
let count = textView.text.count
|
let count = textView.text.count
|
||||||
guard let maxLength,
|
guard let maxLength, count > maxLength else {
|
||||||
count > maxLength,
|
textView.textAttributes = nil
|
||||||
let text = textView.attributedText?.mutableCopy() as? NSMutableAttributedString else { return }
|
return
|
||||||
text.addAttribute(NSAttributedString.Key.backgroundColor, value: highlightBackgroundColor.getColor(self), range: NSRange(location:maxLength, length: (count - maxLength)))
|
}
|
||||||
text.addAttribute(NSAttributedString.Key.foregroundColor, value: highlightTextColor.getColor(self), range: NSRange(location:maxLength, length: (count - maxLength)))
|
|
||||||
textView.attributedText = text
|
var textAttributes = [any LabelAttributeModel]()
|
||||||
|
let location = maxLength
|
||||||
|
let length = count - maxLength
|
||||||
|
textAttributes.append(ColorLabelAttribute(location: location, length: length, color: highlightBackgroundColor.getColor(self), isForegroundColor: false))
|
||||||
|
textAttributes.append(ColorLabelAttribute(location: location, length: length, color: highlightTextColor.getColor(self), isForegroundColor: true))
|
||||||
|
|
||||||
|
textView.textAttributes = textAttributes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,3 +317,143 @@ extension TextArea: UITextViewDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Will move this into a new file, need to talk with Scott/Kyle
|
||||||
|
open class TextView: UITextView, ViewProtocol {
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Initializers
|
||||||
|
//--------------------------------------------------
|
||||||
|
required public init() {
|
||||||
|
super.init(frame: .zero, textContainer: nil)
|
||||||
|
initialSetup()
|
||||||
|
}
|
||||||
|
|
||||||
|
public override init(frame: CGRect, textContainer: NSTextContainer?) {
|
||||||
|
super.init(frame: frame, textContainer: textContainer)
|
||||||
|
initialSetup()
|
||||||
|
}
|
||||||
|
|
||||||
|
public required init?(coder: NSCoder) {
|
||||||
|
super.init(coder: coder)
|
||||||
|
initialSetup()
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Combine Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
/// Set of Subscribers for any Publishers for this Control.
|
||||||
|
open var subscribers = Set<AnyCancellable>()
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Private Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
private var initialSetupPerformed = false
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Properties
|
||||||
|
//--------------------------------------------------
|
||||||
|
/// Key of whether or not updateView() is called in setNeedsUpdate()
|
||||||
|
open var shouldUpdateView: Bool = true
|
||||||
|
|
||||||
|
open var surface: Surface = .light { didSet { setNeedsUpdate() } }
|
||||||
|
|
||||||
|
/// Array of LabelAttributeModel objects used in rendering the text.
|
||||||
|
open var textAttributes: [any LabelAttributeModel]? { didSet { setNeedsUpdate() } }
|
||||||
|
|
||||||
|
/// TextStyle used on the titleLabel.
|
||||||
|
open var textStyle: TextStyle { .defaultStyle }
|
||||||
|
|
||||||
|
/// Will determine if a scaled font should be used for the titleLabel font.
|
||||||
|
open var useScaledFont: Bool = false { didSet { setNeedsUpdate() } }
|
||||||
|
|
||||||
|
open var isEnabled: Bool = true { didSet { setNeedsUpdate() } }
|
||||||
|
|
||||||
|
open var textColorConfiguration: AnyColorable = ViewColorConfiguration().with {
|
||||||
|
$0.setSurfaceColors(VDSColor.interactiveDisabledOnlight, VDSColor.interactiveDisabledOndark, forDisabled: true)
|
||||||
|
$0.setSurfaceColors(VDSColor.elementsPrimaryOnlight, VDSColor.elementsPrimaryOndark, forDisabled: false)
|
||||||
|
}.eraseToAnyColorable(){ didSet { setNeedsUpdate() }}
|
||||||
|
|
||||||
|
open override var textColor: UIColor? {
|
||||||
|
get { textColorConfiguration.getColor(self) }
|
||||||
|
set { }
|
||||||
|
}
|
||||||
|
|
||||||
|
override public var text: String! {
|
||||||
|
get { super.text }
|
||||||
|
set {
|
||||||
|
super.text = newValue
|
||||||
|
updateLabel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override public var textAlignment: NSTextAlignment {
|
||||||
|
didSet {
|
||||||
|
if textAlignment != oldValue {
|
||||||
|
// Text alignment can be part of our paragraph style, so we may need to
|
||||||
|
// re-style when changed
|
||||||
|
updateLabel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Lifecycle
|
||||||
|
//--------------------------------------------------
|
||||||
|
open func initialSetup() {
|
||||||
|
if !initialSetupPerformed {
|
||||||
|
backgroundColor = .clear
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
accessibilityCustomActions = []
|
||||||
|
setup()
|
||||||
|
setNeedsUpdate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
open func setup() {
|
||||||
|
translatesAutoresizingMaskIntoConstraints = false
|
||||||
|
}
|
||||||
|
|
||||||
|
open func updateView() {
|
||||||
|
updateLabel()
|
||||||
|
}
|
||||||
|
|
||||||
|
open func updateAccessibility() {}
|
||||||
|
|
||||||
|
open func reset() {
|
||||||
|
shouldUpdateView = false
|
||||||
|
surface = .light
|
||||||
|
text = nil
|
||||||
|
accessibilityCustomActions = []
|
||||||
|
shouldUpdateView = true
|
||||||
|
setNeedsUpdate()
|
||||||
|
}
|
||||||
|
|
||||||
|
//--------------------------------------------------
|
||||||
|
// MARK: - Private Methods
|
||||||
|
//--------------------------------------------------
|
||||||
|
private func updateLabel() {
|
||||||
|
|
||||||
|
//clear the arrays holding actions
|
||||||
|
accessibilityCustomActions = []
|
||||||
|
if let text, !text.isEmpty {
|
||||||
|
//create the primary string
|
||||||
|
let mutableText = NSMutableAttributedString.mutableText(for: text,
|
||||||
|
textStyle: textStyle,
|
||||||
|
useScaledFont: useScaledFont,
|
||||||
|
textColor: textColor!,
|
||||||
|
alignment: textAlignment,
|
||||||
|
lineBreakMode: .byWordWrapping)
|
||||||
|
//apply any attributes
|
||||||
|
if let attributes = textAttributes {
|
||||||
|
mutableText.apply(attributes: attributes)
|
||||||
|
}
|
||||||
|
attributedText = mutableText
|
||||||
|
} else {
|
||||||
|
attributedText = nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user