From f88c9d5dd0570a25687f8764da9a14e4ed4ef394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sr=C4=91an=20Ra=C5=A1i=C4=87?= Date: Thu, 12 Mar 2015 21:14:22 +0100 Subject: [PATCH] Add dynAttributedText to UILabel and UITextView. --- Bond.podspec | 4 ++-- Bond/Bond+UILabel.swift | 14 ++++++++++++++ Bond/Bond+UITextView.swift | 22 ++++++++++++++++++++++ Bond/Info.plist | 2 +- BondTests/Info.plist | 2 +- BondTests/UIKitBondTests.swift | 14 ++++++++++++++ BondTests/UIKitDynamicTests.swift | 19 +++++++++++++++++++ README.md | 4 ++-- 8 files changed, 75 insertions(+), 6 deletions(-) diff --git a/Bond.podspec b/Bond.podspec index ed86ecba..7b87758e 100644 --- a/Bond.podspec +++ b/Bond.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = "Bond" - s.version = "3.1.1" + s.version = "3.2.0" s.summary = "A Swift binding framework" s.description = <<-DESC @@ -18,7 +18,7 @@ Pod::Spec.new do |s| s.social_media_url = "http://twitter.com/srdanrasic" s.ios.deployment_target = "8.0" s.osx.deployment_target = "10.10" - s.source = { :git => "https://github.com/SwiftBond/Bond.git", :tag => "v3.1.1" } + s.source = { :git => "https://github.com/SwiftBond/Bond.git", :tag => "v3.2.0" } s.source_files = "Bond" s.osx.exclude_files = "Bond/Bond+UI*" s.framework = 'SystemConfiguration' diff --git a/Bond/Bond+UILabel.swift b/Bond/Bond+UILabel.swift index 1bc6c02e..57bd85c5 100644 --- a/Bond/Bond+UILabel.swift +++ b/Bond/Bond+UILabel.swift @@ -28,6 +28,7 @@ import UIKit private var textDynamicHandleUILabel: UInt8 = 0; +private var attributedTextDynamicHandleUILabel: UInt8 = 0; extension UILabel: Bondable { public var dynText: Dynamic { @@ -43,6 +44,19 @@ extension UILabel: Bondable { } } + public var dynAttributedText: Dynamic { + if let d: AnyObject = objc_getAssociatedObject(self, &attributedTextDynamicHandleUILabel) { + return (d as? Dynamic)! + } else { + let d = InternalDynamic(self.attributedText ?? NSAttributedString(string: ""), faulty: false) + let bond = Bond() { [weak self] v in if let s = self { s.attributedText = v } } + d.bindTo(bond, fire: false, strongly: false) + d.retain(bond) + objc_setAssociatedObject(self, &attributedTextDynamicHandleUILabel, d, objc_AssociationPolicy(OBJC_ASSOCIATION_RETAIN_NONATOMIC)) + return d + } + } + public var designatedBond: Bond { return self.dynText.valueBond } diff --git a/Bond/Bond+UITextView.swift b/Bond/Bond+UITextView.swift index acf7c73e..45016b43 100644 --- a/Bond/Bond+UITextView.swift +++ b/Bond/Bond+UITextView.swift @@ -28,6 +28,7 @@ import UIKit private var textDynamicHandleUITextView: UInt8 = 0; +private var attributedTextDynamicHandleUITextView: UInt8 = 0; extension UITextView: Bondable { @@ -52,6 +53,27 @@ extension UITextView: Bondable { } } + public var dynAttributedText: Dynamic { + if let d: AnyObject = objc_getAssociatedObject(self, &attributedTextDynamicHandleUITextView) { + return (d as? Dynamic)! + } else { + let d: InternalDynamic = dynamicObservableFor(UITextViewTextDidChangeNotification, object: self) { + notification -> NSAttributedString in + if let textView = notification.object as? UITextView { + return textView.attributedText ?? NSAttributedString(string: "") + } else { + return NSAttributedString(string: "") + } + } + + let bond = Bond() { [weak self] v in if let s = self { s.attributedText = v } } + d.bindTo(bond, fire: false, strongly: false) + d.retain(bond) + objc_setAssociatedObject(self, &attributedTextDynamicHandleUITextView, d, objc_AssociationPolicy(OBJC_ASSOCIATION_RETAIN_NONATOMIC)) + return d + } + } + public var designatedDynamic: Dynamic { return self.dynText } diff --git a/Bond/Info.plist b/Bond/Info.plist index 31ea7307..b08ae3e2 100644 --- a/Bond/Info.plist +++ b/Bond/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 3.1.1 + 3.2.0 CFBundleSignature ???? CFBundleVersion diff --git a/BondTests/Info.plist b/BondTests/Info.plist index 14c40fd2..6a5c85a5 100644 --- a/BondTests/Info.plist +++ b/BondTests/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType BNDL CFBundleShortVersionString - 3.1.1 + 3.2.0 CFBundleSignature ???? CFBundleVersion diff --git a/BondTests/UIKitBondTests.swift b/BondTests/UIKitBondTests.swift index 42208035..ac04fbc3 100644 --- a/BondTests/UIKitBondTests.swift +++ b/BondTests/UIKitBondTests.swift @@ -67,6 +67,20 @@ class UIKitTests: XCTestCase { dynamicDriver.value = "c" XCTAssert(label.text == "c", "Value after dynamic change") } + + func testUILabelAttributedTextBond() { + var dynamicDriver = Dynamic(NSAttributedString(string: "b")) + let label = UILabel() + + label.text = "a" + XCTAssert(label.text == "a", "Initial value") + + dynamicDriver ->> label.dynAttributedText + XCTAssert(label.attributedText.string == "b", "Value after binding") + + dynamicDriver.value = NSAttributedString(string: "c") + XCTAssert(label.attributedText.string == "c", "Value after dynamic change") + } func testUIProgressViewBond() { var dynamicDriver = Dynamic(0) diff --git a/BondTests/UIKitDynamicTests.swift b/BondTests/UIKitDynamicTests.swift index 723c6575..49e15936 100644 --- a/BondTests/UIKitDynamicTests.swift +++ b/BondTests/UIKitDynamicTests.swift @@ -101,6 +101,25 @@ class UIKitDynamicTests: XCTestCase { XCTAssert(dynamicDriver.value == "d", "Dynamic value reflects text view value change") } + func testUITextViewAttributedDynamic() { + var dynamicDriver = Dynamic(NSAttributedString(string: "b")) + let textView = UITextView() + + textView.attributedText = NSAttributedString(string: "a") + XCTAssert(textView.attributedText.string == "a", "Initial value") + + dynamicDriver <->> textView.dynAttributedText + XCTAssert(textView.attributedText.string == "b", "Text view value after binding") + + dynamicDriver.value = NSAttributedString(string: "c") + XCTAssert(textView.attributedText.string == "c", "Text view value reflects dynamic value change") + + textView.attributedText = NSAttributedString(string: "d") + NSNotificationCenter.defaultCenter().postNotificationName(UITextViewTextDidChangeNotification, object: textView) + XCTAssert(textView.dynAttributedText.value.string == "d", "Dynamic value reflects text view value change") + XCTAssert(dynamicDriver.value.string == "d", "Dynamic value reflects text view value change") + } + func testUIDatePickerDynamic() { let date1 = NSDate(timeIntervalSince1970: 10) let date2 = NSDate(timeIntervalSince1970: 10000) diff --git a/README.md b/README.md index 4d416437..7c283f7f 100644 --- a/README.md +++ b/README.md @@ -231,14 +231,14 @@ Following table lists all available Dynamics of UIKit objects: |----------------|---------------------------------------------------------|-----------------| | UIView | dynAlpha
dynHidden
dynBackgroundColor | -- | | UISlider | dynValue | dynValue | -| UILabel | dynText | dynText | +| UILabel | dynText
dynAttributedText | dynText | | UIProgressView | dynProgress | dynProgress | | UIImageView | dynImage | dynImage | | UIButton | dynEnabled
dynTitle
dynImageForNormalState | dynEnabled | | UIBarItem | dynEnabled
dynTitle
dynImage | dynEnabled | | UISwitch | dynOn | dynOn | | UITextField | dynText | dynText | -| UITextView | dynText | dynText | +| UITextView | dynText
dynAttributedText | dynText | | UIDatePicker | dynDate | dynDate | | UIActivityIndicatorView | dynIsAnimating | dynIsAnimating |