diff --git a/.jazzy.yml b/.jazzy.yml
index 465c756..ab755d1 100644
--- a/.jazzy.yml
+++ b/.jazzy.yml
@@ -5,6 +5,6 @@ github_url: https://github.com/polydice/ICInputAccessory
github_file_prefix: https://github.com/polydice/ICInputAccessory/blob/develop
xcodebuild_arguments: [-project, ICInputAccessory.xcodeproj, -scheme, ICInputAccessory-iOS]
module: ICInputAccessory
-module_version: 1.3.0
+module_version: 1.4.0
output: docs/output
theme: fullwidth
diff --git a/.travis.yml b/.travis.yml
index b1bfad3..e7c00b8 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -15,6 +15,8 @@ script:
- bundle exec rake ci:build
- make -B carthage
- make -B docs
+after_script:
+ - sh scripts/update-docs.sh
notifications:
email: false
slack:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2505371..61c0c79 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,19 @@
+## v1.4.0
+
+* Added delegate methods:
+
+ ```swift
+ @objc optional func tokenField(_ tokenField: ICTokenField, didChangeInputText text: String)
+ @objc optional func tokenField(_ tokenField: ICTokenField, shouldCompleteText text: String) -> Bool
+ @objc optional func tokenField(_ tokenField: ICTokenField, subsequentDelimiterForCompletedText text: String) -> String
+ ```
+
+* Renamed delegate method:
+
+ ```swift
+ @objc optional func tokenField(_ tokenField: ICTokenField, didCompleteText text: String)
+ ```
+
## v1.3.0
* Swift 3.0
diff --git a/Example/CustomizedTokenViewController.swift b/Example/CustomizedTokenViewController.swift
index 907ef61..b167724 100644
--- a/Example/CustomizedTokenViewController.swift
+++ b/Example/CustomizedTokenViewController.swift
@@ -37,6 +37,8 @@ class CustomizedTokenViewController: UIViewController, ICTokenFieldDelegate {
override func loadView() {
super.loadView()
view.backgroundColor = UIColor.white
+ textView.isEditable = false
+ textView.isSelectable = false
textView.text = "[\n\n]"
textView.font = UIFont.preferredFont(forTextStyle: .subheadline)
textView.frame = view.bounds.insetBy(dx: 10, dy: 10)
@@ -83,16 +85,29 @@ class CustomizedTokenViewController: UIViewController, ICTokenFieldDelegate {
print(#function)
}
- func tokenField(_ tokenField: ICTokenField, didEnterText text: String) {
- print("Add: \"\(text)\"")
+ func tokenField(_ tokenField: ICTokenField, didChangeInputText text: String) {
+ print("Typing \"\(text)\"")
+ }
+
+ func tokenField(_ tokenField: ICTokenField, shouldCompleteText text: String) -> Bool {
+ print("Should add \"\(text)\"?")
+ return text != "42"
+ }
+
+ func tokenField(_ tokenField: ICTokenField, didCompleteText text: String) {
+ print("Added \"\(text)\"")
updateTexts()
}
func tokenField(_ tokenField: ICTokenField, didDeleteText text: String, atIndex index: Int) {
- print("Delete: \"\(text)\"")
+ print("Deleted \"\(text)\"")
updateTexts()
}
+ func tokenField(_ tokenField: ICTokenField, subsequentDelimiterForCompletedText text: String) -> String {
+ return " ,"
+ }
+
// MARK: - UIResponder Callbacks
@objc fileprivate func dismiss(_ sender: UIBarButtonItem) {
diff --git a/Example/Info.plist b/Example/Info.plist
index eee55eb..4a13d88 100644
--- a/Example/Info.plist
+++ b/Example/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 1.3.0
+ 1.4.0
CFBundleSignature
????
CFBundleVersion
diff --git a/ICInputAccessory.podspec b/ICInputAccessory.podspec
index f5a705d..cfbbaf8 100644
--- a/ICInputAccessory.podspec
+++ b/ICInputAccessory.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "ICInputAccessory"
- s.version = "1.3.0"
+ s.version = "1.4.0"
s.summary = "A customized token text field used in the iCook app."
s.description = <<-DESC
ICKeyboardDismissTextField:
diff --git a/ICInputAccessory/Info.plist b/ICInputAccessory/Info.plist
index 9f4a4aa..8bce5c7 100644
--- a/ICInputAccessory/Info.plist
+++ b/ICInputAccessory/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
FMWK
CFBundleShortVersionString
- 1.3.0
+ 1.4.0
CFBundleSignature
????
CFBundleVersion
diff --git a/ICInputAccessoryUITests/Info.plist b/ICInputAccessoryUITests/Info.plist
index 3fee538..c48e13f 100644
--- a/ICInputAccessoryUITests/Info.plist
+++ b/ICInputAccessoryUITests/Info.plist
@@ -15,7 +15,7 @@
CFBundlePackageType
BNDL
CFBundleShortVersionString
- 1.3.0
+ 1.4.0
CFBundleSignature
????
CFBundleVersion
diff --git a/Makefile b/Makefile
index 8b63836..bd5efb9 100644
--- a/Makefile
+++ b/Makefile
@@ -1,7 +1,6 @@
install: brew-install bundle-install pod-install
brew-install:
- brew update
brew tap homebrew/bundle
brew bundle
@@ -11,7 +10,10 @@ bundle-install:
pod-install:
bundle exec pod install --no-repo-update
-setup: brew-install
+bootstrap:
+ brew tap homebrew/bundle
+ brew bundle
+ gem install bundler
bundle install
bundle exec pod install --no-repo-update
diff --git a/Podfile.lock b/Podfile.lock
index 4f47d31..12d3a56 100644
--- a/Podfile.lock
+++ b/Podfile.lock
@@ -1,6 +1,6 @@
PODS:
- - ICInputAccessory/KeyboardDismissTextField (1.3.0)
- - ICInputAccessory/TokenField (1.3.0)
+ - ICInputAccessory/KeyboardDismissTextField (1.4.0)
+ - ICInputAccessory/TokenField (1.4.0)
DEPENDENCIES:
- ICInputAccessory/KeyboardDismissTextField (from `./`)
@@ -11,7 +11,7 @@ EXTERNAL SOURCES:
:path: "./"
SPEC CHECKSUMS:
- ICInputAccessory: e9142958152461ddb627e78e3f1f0a8b263b7271
+ ICInputAccessory: dace41bea1ed8b0368bf8ffd439a215efa8effd3
PODFILE CHECKSUM: 6e8fb9f23fc92d92278fbf08ca8ef072ef28a486
diff --git a/README.md b/README.md
index 97b2500..887331f 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ Try .
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg)](https://github.com/Carthage/Carthage)
[![CocoaPods Compatible](https://img.shields.io/cocoapods/v/ICInputAccessory.svg)](https://cocoapods.org/pods/ICInputAccessory)
![Platform](https://img.shields.io/cocoapods/p/ICInputAccessory.svg)
-[![CocoaDocs](https://img.shields.io/cocoapods/metrics/doc-percent/ICInputAccessory.svg)](http://cocoadocs.org/docsets/ICInputAccessory/)
+[![CocoaDocs](https://img.shields.io/cocoapods/metrics/doc-percent/ICInputAccessory.svg)](https://polydice.github.io/ICInputAccessory)
![Swift 3.0](https://img.shields.io/badge/Swift-3.0-orange.svg)
### ICKeyboardDismissTextField
@@ -30,7 +30,7 @@ ICInputAccessory | iOS | Xcode | Swift
`~> 1.0.0` | 8.0+ | 7.2 | ![Swift 2.1.1](https://img.shields.io/badge/Swift-2.1.1-orange.svg)
`~> 1.1.0` | 8.0+ | 7.3 | ![Swift 2.2](https://img.shields.io/badge/Swift-2.2-orange.svg)
`~> 1.2.0` | 8.0+ | 8.0 | ![Swift 2.3](https://img.shields.io/badge/Swift-2.3-orange.svg)
-`~> 1.3.0` | 8.0+ | 8.0 | ![Swift 3.0](https://img.shields.io/badge/Swift-3.0-orange.svg)
+`>= 1.3.0` | 8.0+ | 8.0 | ![Swift 3.0](https://img.shields.io/badge/Swift-3.0-orange.svg)
## Installation
@@ -78,10 +78,10 @@ let tokenField = ICTokenField(frame: rect)
tokenField.delegate = self as? ICTokenFieldDelegate
```
-* The characters that completes a token:
+* The characters that complete a token:
```swift
-/// Characters that completes a new token, defaults are whitespace and commas.
+/// Characters that complete a new token, defaults are whitespace and commas.
public var delimiters: [String]
```
@@ -132,29 +132,39 @@ See `Example/CustomizedTokenField.swift` for more details.
`ICTokenField` currently notifies its delegate the following events:
-* `tokenFieldDidBeginEditing(_:)`
-* `tokenFieldDidEndEditing(_:)`
-* `tokenFieldWillReturn(_:)`
-* `tokenField(_:didEnterText:)`
-* `tokenField(_:didDeleteText:atIndex:)`
+```swift
+@objc optional func tokenFieldDidBeginEditing(_ tokenField: ICTokenField)
+@objc optional func tokenFieldDidEndEditing(_ tokenField: ICTokenField)
+@objc optional func tokenFieldWillReturn(_ tokenField: ICTokenField)
+@objc optional func tokenField(_ tokenField: ICTokenField, didChangeInputText text: String)
+@objc optional func tokenField(_ tokenField: ICTokenField, shouldCompleteText text: String) -> Bool
+@objc optional func tokenField(_ tokenField: ICTokenField, didCompleteText text: String)
+@objc optional func tokenField(_ tokenField: ICTokenField, didDeleteText text: String, atIndex index: Int)
+```
+
+The displayed delimiter string can be customized by:
+
+```swift
+@objc optional func tokenField(_ tokenField: ICTokenField, subsequentDelimiterForCompletedText text: String) -> String
+```
## Development
-* Meke sure [Homebrew](http://brew.sh/) is installed.
+* Make sure [Homebrew](http://brew.sh/) is installed.
* Current `develop` branch requires Ruby `2.3.1`.
* Set up dependencies by running the following command in the project root:
```
-make setup
-```
+ make bootstrap
+ ```
* Open **ICInputAccessory.xcworkspace** and run the demo app with the `Example` scheme.
* See more tasks for building and testing:
```
-rake -T
-```
+ rake -T
+ ```
## Contributing
diff --git a/Source/TokenField/ICToken.swift b/Source/TokenField/ICToken.swift
index 10ff293..818092e 100644
--- a/Source/TokenField/ICToken.swift
+++ b/Source/TokenField/ICToken.swift
@@ -63,10 +63,10 @@ class ICToken: UIView {
// MARK: - Private Properties
private(set) lazy var delimiterLabel: UILabel = {
- let _delimiter = UILabel()
- _delimiter.text = " , "
- _delimiter.textColor = self.normalTextAttributes[NSForegroundColorAttributeName] as? UIColor
- return _delimiter
+ let _label = UILabel()
+ _label.textColor = self.normalTextAttributes[NSForegroundColorAttributeName] as? UIColor
+ _label.textAlignment = .right
+ return _label
}()
private(set) lazy var textLabel: UILabel = {
@@ -90,16 +90,15 @@ class ICToken: UIView {
setUpSubviews()
}
- convenience init(text: String, normalAttributes: [String: NSObject]? = nil, highlightedAttributes: [String: NSObject]? = nil) {
+ convenience init(text: String, delimiter: String = ",", normalAttributes: [String: NSObject]? = nil, highlightedAttributes: [String: NSObject]? = nil) {
self.init()
if let attributes = normalAttributes { normalTextAttributes = attributes }
if let attributes = highlightedAttributes { highlightedTextAttributes = attributes }
- // didSet is not called within the initializer
- setText(text)
- }
-
- private func setText(_ text: String) {
- self.text = text
+ delimiterLabel.text = delimiter
+ ({
+ // Workaround to trigger didSet inside the initializer
+ self.text = text
+ })()
}
// MARK: - Private Methods
@@ -127,7 +126,7 @@ class ICToken: UIView {
"text": textLabel,
"delimiter": delimiterLabel
]
- addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[text][delimiter]|",
+ addConstraints(NSLayoutConstraint.constraints(withVisualFormat: "H:|[text][delimiter]-5-|",
options: [.alignAllCenterY],
metrics: nil,
views: views
diff --git a/Source/TokenField/ICTokenField.swift b/Source/TokenField/ICTokenField.swift
index eeed91c..4108f75 100644
--- a/Source/TokenField/ICTokenField.swift
+++ b/Source/TokenField/ICTokenField.swift
@@ -34,10 +34,16 @@ import UIKit
@objc optional func tokenFieldDidEndEditing(_ tokenField: ICTokenField)
/// Tells the delegate that the token field will process the pressing of the return button.
@objc optional func tokenFieldWillReturn(_ tokenField: ICTokenField)
+ /// Tells the delegate the input text is changed.
+ @objc optional func tokenField(_ tokenField: ICTokenField, didChangeInputText text: String)
+ /// Asks the delegate if the text should become a token in the token field.
+ @objc optional func tokenField(_ tokenField: ICTokenField, shouldCompleteText text: String) -> Bool
/// Tells the delegate that the text becomes a token in the token field.
- @objc optional func tokenField(_ tokenField: ICTokenField, didEnterText text: String)
+ @objc optional func tokenField(_ tokenField: ICTokenField, didCompleteText text: String)
/// Tells the delegate that the token at certain index is removed from the token field.
@objc optional func tokenField(_ tokenField: ICTokenField, didDeleteText text: String, atIndex index: Int)
+ /// Asks the delegate for the subsequent delimiter string for a completed text in the token field.
+ @objc optional func tokenField(_ tokenField: ICTokenField, subsequentDelimiterForCompletedText text: String) -> String
}
@@ -287,23 +293,28 @@ open class ICTokenField: UIView, UITextFieldDelegate, ICBackspaceTextFieldDelega
}
let text = (input as NSString).replacingCharacters(in: range, with: string)
+ delegate?.tokenField?(self, didChangeInputText: text)
for delimiter in delimiters {
- if text.hasSuffix(delimiter) {
- let index = text.index(text.endIndex, offsetBy: -delimiter.characters.count)
- let newToken = text.substring(to: index)
- textField.text = nil
-
- if !newToken.isEmpty && newToken != delimiter {
- tokens.append(ICToken(text: newToken, normalAttributes: normalTokenAttributes, highlightedAttributes: highlightedTokenAttributes))
- layoutTokenTextField()
- delegate?.tokenField?(self, didEnterText: newToken)
- }
- togglePlaceholderIfNeeded()
+ guard text.hasSuffix(delimiter) else {
+ continue
+ }
- return false
+ let index = text.index(text.endIndex, offsetBy: -delimiter.characters.count)
+ let newText = text.substring(to: index)
+
+ if !newText.isEmpty && newText != delimiter && (delegate?.tokenField?(self, shouldCompleteText: newText) ?? true) {
+ tokens.append(customizedToken(with: newText))
+ layoutTokenTextField()
+ delegate?.tokenField?(self, didCompleteText: newText)
}
+
+ textField.text = nil
+ togglePlaceholderIfNeeded()
+
+ return false
}
+
return true
}
@@ -316,7 +327,7 @@ open class ICTokenField: UIView, UITextFieldDelegate, ICBackspaceTextFieldDelega
// MARK: - ICBackspaceTextFieldDelegate
- func textFieldShouldDelete(_ textField: ICBackspaceTextField) -> Bool {
+ @nonobjc func textFieldShouldDelete(_ textField: ICBackspaceTextField) -> Bool {
if tokens.isEmpty {
return true
}
@@ -364,6 +375,14 @@ open class ICTokenField: UIView, UITextFieldDelegate, ICBackspaceTextFieldDelega
// MARK: - Private Methods
+ private func customizedToken(with text: String) -> ICToken {
+ if let string = delegate?.tokenField?(self, subsequentDelimiterForCompletedText: text) {
+ return ICToken(text: text, delimiter: string, normalAttributes: normalTokenAttributes, highlightedAttributes: highlightedTokenAttributes)
+ } else {
+ return ICToken(text: text, normalAttributes: normalTokenAttributes, highlightedAttributes: highlightedTokenAttributes)
+ }
+ }
+
/// Returns true if any highlighted token is found and removed, otherwise false.
private func removeHighlightedToken() -> Bool {
for (index, token) in tokens.enumerated() {
@@ -436,10 +455,16 @@ open class ICTokenField: UIView, UITextFieldDelegate, ICBackspaceTextFieldDelega
guard let text = inputTextField.text, !text.isEmpty else {
return
}
+
+ let shouldCompleteText = delegate?.tokenField?(self, shouldCompleteText: text) ?? true
+ guard shouldCompleteText else {
+ return
+ }
+
inputTextField.text = nil
- tokens.append(ICToken(text: text, normalAttributes: normalTokenAttributes, highlightedAttributes: highlightedTokenAttributes))
+ tokens.append(customizedToken(with: text))
layoutTokenTextField()
- delegate?.tokenField?(self, didEnterText: text)
+ delegate?.tokenField?(self, didCompleteText: text)
}
/// Removes the input text and all displayed tokens.
diff --git a/scripts/update-docs.sh b/scripts/update-docs.sh
index 28a174b..daf0471 100644
--- a/scripts/update-docs.sh
+++ b/scripts/update-docs.sh
@@ -17,7 +17,7 @@ git --no-pager diff --stat
git add .
git commit -m "[CI] Update documentation at $(date +'%Y-%m-%d %H:%M:%S %z')"
-if [ "${TRAVIS_BRANCH}" = "master" ] && [ -n "$DANGER_GITHUB_API_TOKEN" ]; then
+if [ "${TRAVIS_BRANCH}" = "develop" ] && [ -n "$DANGER_GITHUB_API_TOKEN" ]; then
echo "Updating gh-pages..."
git remote add upstream "https://${DANGER_GITHUB_API_TOKEN}@github.com/polydice/ICInputAccessory.git"
git push --quiet upstream HEAD:gh-pages