Skip to content

Commit 42742d0

Browse files
authored
Adds refreshView function and refreshes view on each major change to vars (#13)
1 parent da3ed1d commit 42742d0

File tree

1 file changed

+56
-59
lines changed

1 file changed

+56
-59
lines changed

Sources/LCLabel/LCLabel.swift

Lines changed: 56 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -53,39 +53,64 @@ final public class LCLabel: UIView {
5353
/// A LCLabel delegate that responses to link interactions within
5454
/// the view
5555
public weak var delegate: LCLabelDelegate?
56+
public override var frame: CGRect {
57+
didSet {
58+
refreshView()
59+
}
60+
}
5661
/// Text ``Alignment`` within the frame
57-
public var textAlignment: LCLabel.Alignment = .center
62+
public var textAlignment: LCLabel.Alignment = .center {
63+
didSet {
64+
refreshView()
65+
}
66+
}
5867
/// Texts inset within the Frame
5968
public var textInsets: UIEdgeInsets = .zero {
6069
didSet {
61-
layoutIfNeeded()
70+
refreshView()
6271
}
6372
}
6473
/// The attributes to apply to links.
6574
public var linkAttributes: [NSAttributedString.Key: Any]? {
6675
didSet {
6776
guard renderedStorage != nil else { return }
6877
setupRenderStorage()
69-
layoutIfNeeded()
78+
refreshView()
7079
}
7180
}
7281
/// Exclues underlines attributes from text
7382
public var shouldExcludeUnderlinesFromText = true {
7483
didSet {
7584
guard renderedStorage != nil else { return }
7685
setupRenderStorage()
77-
layoutIfNeeded()
86+
refreshView()
7887
}
7988
}
8089
/// Validates if the user passed an attributed string of type .link and switches
8190
/// it to .lclabelLink
82-
public var linkStyleValidation: LinksStyleValidation = .skip
91+
public var linkStyleValidation: LinksStyleValidation = .skip {
92+
didSet {
93+
refreshView()
94+
}
95+
}
8396
/// Line breaking mode the label uses, default is `.byTruncatingTail`
84-
public var lineBreakMode: NSLineBreakMode = .byTruncatingTail
97+
public var lineBreakMode: NSLineBreakMode = .byTruncatingTail {
98+
didSet {
99+
refreshView()
100+
}
101+
}
85102
/// Line padding at the beginning of the view
86-
public var lineFragmentPadding: CGFloat = 0
103+
public var lineFragmentPadding: CGFloat = 0 {
104+
didSet {
105+
refreshView()
106+
}
107+
}
87108
/// Number of lines allowed
88-
public var numberOfLines = 1
109+
public var numberOfLines = 1 {
110+
didSet {
111+
refreshView()
112+
}
113+
}
89114
/// Text to be displayed
90115
public var attributedText: NSAttributedString? {
91116
get {
@@ -102,14 +127,13 @@ final public class LCLabel: UIView {
102127
isHidden = true
103128
}
104129
setupRenderStorage()
105-
layoutIfNeeded()
106-
setNeedsLayout()
107-
setNeedsDisplay()
130+
refreshView()
108131
}
109132
}
110133

111134
/// Current text to be displayed
112-
private var renderedStorage: NSTextStorage!
135+
private var renderedStorage: NSTextStorage?
136+
private var textContainer: NSTextContainer?
113137
private var currentCalculatedFrame: CGRect?
114138

115139
/// Current LayoutManager
@@ -124,12 +148,10 @@ final public class LCLabel: UIView {
124148

125149
public init() {
126150
super.init(frame: .zero)
127-
setupLabel()
128151
}
129152

130153
public override init(frame: CGRect) {
131154
super.init(frame: frame)
132-
setupLabel()
133155
}
134156

135157
public required init?(coder: NSCoder) {
@@ -146,19 +168,28 @@ final public class LCLabel: UIView {
146168
return
147169
}
148170

149-
// Removes the current text container and replace it with a newer one
150-
if !layoutManager.textContainers.isEmpty {
151-
layoutManager.removeTextContainer(at: 0)
152-
}
153-
154171
let bounds = textRect(forBounds: rect)
155172

156173
currentCalculatedFrame = bounds
157-
let container = NSTextContainer(size: bounds.size)
174+
175+
let container: NSTextContainer
176+
// Check if the current text container is still valid
177+
// with the proper size.
178+
if let textContainer = textContainer,
179+
textContainer.size == bounds.size
180+
{
181+
container = textContainer
182+
} else {
183+
// Removes the current text container and replace it with a newer one
184+
if !layoutManager.textContainers.isEmpty {
185+
layoutManager.removeTextContainer(at: 0)
186+
}
187+
container = NSTextContainer(size: bounds.size)
188+
layoutManager.addTextContainer(container)
189+
}
158190
container.maximumNumberOfLines = numberOfLines
159191
container.lineBreakMode = lineBreakMode
160192
container.lineFragmentPadding = lineFragmentPadding
161-
layoutManager.addTextContainer(container)
162193
storage.addLayoutManager(layoutManager)
163194
let range = layoutManager.glyphRange(for: container)
164195

@@ -197,12 +228,9 @@ final public class LCLabel: UIView {
197228
return newBounds
198229
}
199230

200-
private func setupLabel() {
201-
let tapGesture = UILongPressGestureRecognizer(
202-
target: self,
203-
action: #selector(handleUserInput))
204-
tapGesture.delegate = self
205-
addGestureRecognizer(tapGesture)
231+
private func refreshView() {
232+
setNeedsDisplay()
233+
setNeedsLayout()
206234
}
207235

208236
/// The following functions replaces
@@ -297,37 +325,6 @@ extension LCLabel {
297325
return getLink(at: touch.location(in: self))
298326
}
299327

300-
}
301-
302-
// MARK: - UIGestureRecognizerDelegate
303-
304-
extension LCLabel: UIGestureRecognizerDelegate {
305-
306-
public func gestureRecognizer(
307-
_ gestureRecognizer: UIGestureRecognizer,
308-
shouldReceive touch: UITouch) -> Bool
309-
{
310-
return getLink(at: touch.location(in: self)) != nil
311-
}
312-
313-
@objc
314-
private func handleUserInput(_ gesture: UILongPressGestureRecognizer) {
315-
let point = gesture.location(in: self)
316-
switch gesture.state {
317-
case .began:
318-
checkoutLink(at: point)
319-
default:
320-
break
321-
}
322-
}
323-
324-
private func checkoutLink(at point: CGPoint) {
325-
guard let url = getLink(at: point) else {
326-
return
327-
}
328-
delegate?.didPress(url: url, at: point)
329-
}
330-
331328
private func getLink(at point: CGPoint) -> URL? {
332329
// Check if the point is within the bounds of the text
333330
// container before converting it
@@ -354,7 +351,7 @@ extension LCLabel: UIGestureRecognizerDelegate {
354351
// .link attribute at an index (x)
355352
// (Note): we are using attachment since i couldnt remove the default
356353
// link coloring with TextKit
357-
guard let url = renderedStorage.attribute(
354+
guard let url = renderedStorage?.attribute(
358355
.lclabelLink,
359356
at: index,
360357
effectiveRange: nil)

0 commit comments

Comments
 (0)