diff --git a/CardParts.podspec b/CardParts.podspec index 0d3e665e..13ab02da 100644 --- a/CardParts.podspec +++ b/CardParts.podspec @@ -8,7 +8,7 @@ Pod::Spec.new do |s| s.name = 'CardParts' - s.version = '2.4.2' + s.version = '2.5.0' s.platform = :ios s.summary = 'iOS Card UI framework.' @@ -32,6 +32,5 @@ CardParts is an iOS Card UI framework that uses MVVM and automatic data binding s.dependency 'RxCocoa', '~> 4.0' s.dependency 'RxDataSources', '~> 3.0' s.dependency 'RxGesture', '~> 1.2' - s.dependency 'TTTAttributedLabel' end diff --git a/CardParts/src/Classes/Card Parts/CardPartTextView.swift b/CardParts/src/Classes/Card Parts/CardPartTextView.swift index 3bfa4059..c7f3f657 100644 --- a/CardParts/src/Classes/Card Parts/CardPartTextView.swift +++ b/CardParts/src/Classes/Card Parts/CardPartTextView.swift @@ -9,7 +9,26 @@ import UIKit import RxSwift import RxCocoa -import TTTAttributedLabel + +public class CardPartLabel: UILabel { + public var textInsets = UIEdgeInsets.zero { + didSet { invalidateIntrinsicContentSize() } + } + + override public func textRect(forBounds bounds: CGRect, limitedToNumberOfLines numberOfLines: Int) -> CGRect { + let insetRect = UIEdgeInsetsInsetRect(bounds, textInsets) + let textRect = super.textRect(forBounds: insetRect, limitedToNumberOfLines: numberOfLines) + let invertedInsets = UIEdgeInsets(top: -textInsets.top, + left: -textInsets.left, + bottom: -textInsets.bottom, + right: -textInsets.right) + return UIEdgeInsetsInsetRect(textRect, invertedInsets) + } + + override public func drawText(in rect: CGRect) { + super.drawText(in: UIEdgeInsetsInsetRect(rect, textInsets)) + } +} public enum CardPartTextType { case small @@ -19,7 +38,7 @@ public enum CardPartTextType { case detail } -public class CardPartTextView : UIView, CardPartView, TTTAttributedLabelDelegate { +public class CardPartTextView : UIView, CardPartView { public var text: String? { didSet { @@ -65,12 +84,11 @@ public class CardPartTextView : UIView, CardPartView, TTTAttributedLabelDelegate public var margins: UIEdgeInsets = CardParts.theme.cardPartMargins - public var label: TTTAttributedLabel - + public var label: CardPartLabel public init(type: CardPartTextType) { - label = TTTAttributedLabel(frame: CGRect.zero) + label = CardPartLabel(frame: .zero) label.translatesAutoresizingMaskIntoConstraints = false label.numberOfLines = 0 @@ -79,10 +97,8 @@ public class CardPartTextView : UIView, CardPartView, TTTAttributedLabelDelegate super.init(frame: CGRect.zero) - label.delegate = self addSubview(label) - setupLinkAttributes() setDefaultsForType(type) setNeedsUpdateConstraints() } @@ -98,14 +114,6 @@ public class CardPartTextView : UIView, CardPartView, TTTAttributedLabelDelegate super.updateConstraints() } - func setupLinkAttributes() { - let linkBlueColor = UIColor.turboBlueColor - let activeLinkBlueColor = UIColor.turboBlueColor.withAlphaComponent(0.5) - - label.linkAttributes = [kCTForegroundColorAttributeName as String : linkBlueColor] - label.activeLinkAttributes = [kCTForegroundColorAttributeName as String : activeLinkBlueColor] - } - func setDefaultsForType(_ type: CardPartTextType) { isUserInteractionEnabled = true @@ -140,9 +148,8 @@ public class CardPartTextView : UIView, CardPartView, TTTAttributedLabelDelegate mutableAttrText.addAttributes([NSAttributedStringKey.paragraphStyle: paragraphStyle], range: NSRange(location: 0, length: mutableAttrText.length)) - label.textAlignment = textAlignment - label.setText(mutableAttrText) - + label.attributedText = mutableAttrText + label.textAlignment = textAlignment } else if let labelText = text { let mutableAttrText = NSMutableAttributedString(string: labelText, attributes: [NSAttributedStringKey.font: font, NSAttributedStringKey.foregroundColor: textColor]) @@ -153,17 +160,12 @@ public class CardPartTextView : UIView, CardPartView, TTTAttributedLabelDelegate mutableAttrText.addAttributes([NSAttributedStringKey.paragraphStyle: paragraphStyle], range: NSRange(location: 0, length: mutableAttrText.length)) label.font = font - label.textAlignment = textAlignment - label.setText(mutableAttrText) - + label.attributedText = mutableAttrText + label.textAlignment = textAlignment } else { - label.setText(nil) + label.attributedText = nil } } - - public func attributedLabel(_ label: TTTAttributedLabel!, didSelectLinkWith url: URL!) { - UIApplication.shared.open(url, options: [:], completionHandler: nil) - } } extension Reactive where Base: CardPartTextView { diff --git a/Example/Tests/CardPartTextViewTests.swift b/Example/Tests/CardPartTextViewTests.swift index df4bd8c9..818c958a 100644 --- a/Example/Tests/CardPartTextViewTests.swift +++ b/Example/Tests/CardPartTextViewTests.swift @@ -29,18 +29,18 @@ class CardPartTextViewTests: XCTestCase { var textPart = CardPartTextView(type: .normal) textPart.text = "hello" - XCTAssertEqual(textPart.label.attributedText.attribute(NSFontAttributeName, at:0, effectiveRange:nil) as? UIFont, CardParts.theme.normalTextFont) - XCTAssertEqual(textPart.label.attributedText.attribute(NSForegroundColorAttributeName, at:0, effectiveRange:nil) as? UIColor, CardParts.theme.normalTextColor) + XCTAssertEqual(textPart.label.attributedText?.attribute(NSFontAttributeName, at:0, effectiveRange:nil) as? UIFont, CardParts.theme.normalTextFont) + XCTAssertEqual(textPart.label.attributedText?.attribute(NSForegroundColorAttributeName, at:0, effectiveRange:nil) as? UIColor, CardParts.theme.normalTextColor) textPart = CardPartTextView(type: .title) textPart.text = "hello" - XCTAssertEqual(textPart.label.attributedText.attribute(NSFontAttributeName, at:0, effectiveRange:nil) as? UIFont, CardParts.theme.titleTextFont) - XCTAssertEqual(textPart.label.attributedText.attribute(NSForegroundColorAttributeName, at:0, effectiveRange:nil) as? UIColor, CardParts.theme.titleTextColor) + XCTAssertEqual(textPart.label.attributedText?.attribute(NSFontAttributeName, at:0, effectiveRange:nil) as? UIFont, CardParts.theme.titleTextFont) + XCTAssertEqual(textPart.label.attributedText?.attribute(NSForegroundColorAttributeName, at:0, effectiveRange:nil) as? UIColor, CardParts.theme.titleTextColor) textPart = CardPartTextView(type: .detail) textPart.text = "hello" - XCTAssertEqual(textPart.label.attributedText.attribute(NSFontAttributeName, at:0, effectiveRange:nil) as? UIFont, CardParts.theme.detailTextFont) - XCTAssertEqual(textPart.label.attributedText.attribute(NSForegroundColorAttributeName, at:0, effectiveRange:nil) as? UIColor, CardParts.theme.detailTextColor) + XCTAssertEqual(textPart.label.attributedText?.attribute(NSFontAttributeName, at:0, effectiveRange:nil) as? UIFont, CardParts.theme.detailTextFont) + XCTAssertEqual(textPart.label.attributedText?.attribute(NSForegroundColorAttributeName, at:0, effectiveRange:nil) as? UIColor, CardParts.theme.detailTextColor) } func testTextProperty() { @@ -67,26 +67,26 @@ class CardPartTextViewTests: XCTestCase { let attrText = NSAttributedString(string: "hello", attributes: [NSFontAttributeName : UIFont.boldSystemFont(ofSize: 50), NSForegroundColorAttributeName : UIColor.red]) textPart.attributedText = attrText - XCTAssertEqual(attrText.string, textPart.label.attributedText.string) + XCTAssertEqual(attrText.string, textPart.label.attributedText?.string) XCTAssertEqual(attrText.attribute(NSFontAttributeName, at:0, effectiveRange:nil) as! UIFont, - textPart.label.attributedText.attribute(NSFontAttributeName, at:0, effectiveRange:nil) as! UIFont) + textPart.label.attributedText?.attribute(NSFontAttributeName, at:0, effectiveRange:nil) as! UIFont) XCTAssertEqual(attrText.attribute(NSForegroundColorAttributeName, at:0, effectiveRange:nil) as! UIColor, - textPart.label.attributedText.attribute(NSForegroundColorAttributeName, at:0, effectiveRange:nil) as! UIColor) + textPart.label.attributedText?.attribute(NSForegroundColorAttributeName, at:0, effectiveRange:nil) as! UIColor) let textProperty = Variable(NSAttributedString(string: "testing", attributes: [NSFontAttributeName : UIFont.boldSystemFont(ofSize: 50), NSForegroundColorAttributeName : UIColor.blue])) textProperty.asObservable().bind(to: textPart.rx.attributedText).disposed(by: bag) - XCTAssertEqual(textProperty.value.string, textPart.label.attributedText.string) + XCTAssertEqual(textProperty.value.string, textPart.label.attributedText?.string) XCTAssertEqual(textProperty.value.attribute(NSFontAttributeName, at:0, effectiveRange:nil) as! UIFont, - textPart.label.attributedText.attribute(NSFontAttributeName, at:0, effectiveRange:nil) as! UIFont) + textPart.label.attributedText?.attribute(NSFontAttributeName, at:0, effectiveRange:nil) as! UIFont) XCTAssertEqual(textProperty.value.attribute(NSForegroundColorAttributeName, at:0, effectiveRange:nil) as! UIColor, - textPart.label.attributedText.attribute(NSForegroundColorAttributeName, at:0, effectiveRange:nil) as! UIColor) + textPart.label.attributedText?.attribute(NSForegroundColorAttributeName, at:0, effectiveRange:nil) as! UIColor) textProperty.value = NSAttributedString(string: "newValue", attributes: [NSFontAttributeName : UIFont.boldSystemFont(ofSize: 50), NSForegroundColorAttributeName : UIColor.green]) - XCTAssertEqual(textProperty.value.string, textPart.label.attributedText.string) + XCTAssertEqual(textProperty.value.string, textPart.label.attributedText?.string) XCTAssertEqual(textProperty.value.attribute(NSFontAttributeName, at:0, effectiveRange:nil) as! UIFont, - textPart.label.attributedText.attribute(NSFontAttributeName, at:0, effectiveRange:nil) as! UIFont) + textPart.label.attributedText?.attribute(NSFontAttributeName, at:0, effectiveRange:nil) as! UIFont) XCTAssertEqual(textProperty.value.attribute(NSForegroundColorAttributeName, at:0, effectiveRange:nil) as! UIColor, - textPart.label.attributedText.attribute(NSForegroundColorAttributeName, at:0, effectiveRange:nil) as! UIColor) + textPart.label.attributedText?.attribute(NSForegroundColorAttributeName, at:0, effectiveRange:nil) as! UIColor) } func testFontProperty() { @@ -97,14 +97,14 @@ class CardPartTextViewTests: XCTestCase { textPart.text = "hello" textPart.font = UIFont.boldSystemFont(ofSize: 20) - XCTAssertEqual(textPart.font, textPart.label.attributedText.attribute(NSFontAttributeName, at:0, effectiveRange:nil) as? UIFont) + XCTAssertEqual(textPart.font, textPart.label.attributedText?.attribute(NSFontAttributeName, at:0, effectiveRange:nil) as? UIFont) let fontProperty = Variable(UIFont.boldSystemFont(ofSize: 50)) fontProperty.asObservable().bind(to: textPart.rx.font).disposed(by: bag) - XCTAssertEqual(fontProperty.value, textPart.label.attributedText.attribute(NSFontAttributeName, at:0, effectiveRange:nil) as? UIFont) + XCTAssertEqual(fontProperty.value, textPart.label.attributedText?.attribute(NSFontAttributeName, at:0, effectiveRange:nil) as? UIFont) fontProperty.value = UIFont.boldSystemFont(ofSize: 10) - XCTAssertEqual(fontProperty.value, textPart.label.attributedText.attribute(NSFontAttributeName, at:0, effectiveRange:nil) as? UIFont) + XCTAssertEqual(fontProperty.value, textPart.label.attributedText?.attribute(NSFontAttributeName, at:0, effectiveRange:nil) as? UIFont) } func testTextColorProperty() { @@ -115,14 +115,14 @@ class CardPartTextViewTests: XCTestCase { textPart.text = "hello" textPart.textColor = UIColor.red - XCTAssertEqual(textPart.textColor, textPart.label.attributedText.attribute(NSForegroundColorAttributeName, at:0, effectiveRange:nil) as? UIColor) + XCTAssertEqual(textPart.textColor, textPart.label.attributedText?.attribute(NSForegroundColorAttributeName, at:0, effectiveRange:nil) as? UIColor) let colorProperty = Variable(UIColor.green) colorProperty.asObservable().bind(to: textPart.rx.textColor).disposed(by: bag) - XCTAssertEqual(colorProperty.value, textPart.label.attributedText.attribute(NSForegroundColorAttributeName, at:0, effectiveRange:nil) as? UIColor) + XCTAssertEqual(colorProperty.value, textPart.label.attributedText?.attribute(NSForegroundColorAttributeName, at:0, effectiveRange:nil) as? UIColor) colorProperty.value = UIColor.blue - XCTAssertEqual(colorProperty.value, textPart.label.attributedText.attribute(NSForegroundColorAttributeName, at:0, effectiveRange:nil) as? UIColor) + XCTAssertEqual(colorProperty.value, textPart.label.attributedText?.attribute(NSForegroundColorAttributeName, at:0, effectiveRange:nil) as? UIColor) } func testTextAlignmentProperty() { @@ -151,14 +151,14 @@ class CardPartTextViewTests: XCTestCase { textPart.text = "hello" textPart.lineSpacing = 5.0 - XCTAssertEqual(textPart.lineSpacing, (textPart.label.attributedText.attribute(NSParagraphStyleAttributeName, at:0, effectiveRange:nil) as? NSParagraphStyle)?.lineSpacing) + XCTAssertEqual(textPart.lineSpacing, (textPart.label.attributedText?.attribute(NSParagraphStyleAttributeName, at:0, effectiveRange:nil) as? NSParagraphStyle)?.lineSpacing) let lineSpacingProperty = Variable(2.5) lineSpacingProperty.asObservable().bind(to: textPart.rx.lineSpacing).disposed(by: bag) - XCTAssertEqual(textPart.lineSpacing, (textPart.label.attributedText.attribute(NSParagraphStyleAttributeName, at:0, effectiveRange:nil) as? NSParagraphStyle)?.lineSpacing) + XCTAssertEqual(textPart.lineSpacing, (textPart.label.attributedText?.attribute(NSParagraphStyleAttributeName, at:0, effectiveRange:nil) as? NSParagraphStyle)?.lineSpacing) lineSpacingProperty.value = 1.0 - XCTAssertEqual(textPart.lineSpacing, (textPart.label.attributedText.attribute(NSParagraphStyleAttributeName, at:0, effectiveRange:nil) as? NSParagraphStyle)?.lineSpacing) + XCTAssertEqual(textPart.lineSpacing, (textPart.label.attributedText?.attribute(NSParagraphStyleAttributeName, at:0, effectiveRange:nil) as? NSParagraphStyle)?.lineSpacing) } func testLineHeightMultipleProperty() { @@ -169,14 +169,14 @@ class CardPartTextViewTests: XCTestCase { textPart.text = "hello" textPart.lineHeightMultiple = 5.0 - XCTAssertEqual(textPart.lineHeightMultiple, (textPart.label.attributedText.attribute(NSParagraphStyleAttributeName, at:0, effectiveRange:nil) as? NSParagraphStyle)?.lineHeightMultiple) + XCTAssertEqual(textPart.lineHeightMultiple, (textPart.label.attributedText?.attribute(NSParagraphStyleAttributeName, at:0, effectiveRange:nil) as? NSParagraphStyle)?.lineHeightMultiple) let lineHeightMultipleProperty = Variable(2.5) lineHeightMultipleProperty.asObservable().bind(to: textPart.rx.lineHeightMultiple).disposed(by: bag) - XCTAssertEqual(textPart.lineHeightMultiple, (textPart.label.attributedText.attribute(NSParagraphStyleAttributeName, at:0, effectiveRange:nil) as? NSParagraphStyle)?.lineHeightMultiple) + XCTAssertEqual(textPart.lineHeightMultiple, (textPart.label.attributedText?.attribute(NSParagraphStyleAttributeName, at:0, effectiveRange:nil) as? NSParagraphStyle)?.lineHeightMultiple) lineHeightMultipleProperty.value = 1.0 - XCTAssertEqual(textPart.lineHeightMultiple, (textPart.label.attributedText.attribute(NSParagraphStyleAttributeName, at:0, effectiveRange:nil) as? NSParagraphStyle)?.lineHeightMultiple) + XCTAssertEqual(textPart.lineHeightMultiple, (textPart.label.attributedText?.attribute(NSParagraphStyleAttributeName, at:0, effectiveRange:nil) as? NSParagraphStyle)?.lineHeightMultiple) } }