TestsTested | ✗ |
LangLanguage | SwiftSwift |
License | MIT |
ReleasedLast Release | Jan 2017 |
SwiftSwift Version | 3.0 |
SPMSupports SPM | ✗ |
Maintained by Wonder Bear.
TagList, flexible tag list view, easy to use & extend. I love it.
If you prefer not to use either of the aforementioned dependency managers, you can integrate TagList into your project manually.
Open the demo project, build and run.
public protocol TagListDelegate: NSObjectProtocol {
func tagActionTriggered(tagList: TagList, action: TagAction, content: TagPresentable, index: Int)
func tagListUpdated(tagList: TagList)
}
public protocol TagPresentable {
var tag: String { get }
var isSelected: Bool { get set }
func createTagContent() -> TagContent
}
public protocol TagActionable {
var actionDelegate: TagActionDelegate? { get set }
}
public protocol TagActionDelegate: NSObjectProtocol {
func tagActionTriggered(action: TagAction)
}
public protocol TagStatable {
var stateDelegate: TagStateDelegate? { get set }
}
public protocol TagStateDelegate: NSObjectProtocol {
func tagSelected(_ isSelected: Bool)
}
protocol TagWrapperDelegate: TagActionable, TagActionDelegate, TagStatable, TagStateDelegate {
func wrap(target: TagContent) -> TagWrapper
func wrap(wrapper: TagWrapper) -> TagWrapper
}
import SwiftTagList
extension ViewController: TagListDelegate {
// Called when tagList's content changed
func tagListUpdated(tagList: TagList) {
...
}
// Tag interaction
func tagActionTriggered(tagList: TagList, action: TagAction, content: TagPresentable, index: Int) {
...
}
}
let view = TagList()
view.delegate = self
view.backgroundColor = UIColor.yellow
view.tagMargin = UIEdgeInsets(top: 3, left: 5, bottom: 3, right: 5)
view.separator.image = #imageLiteral(resourceName: "icon_arrow_right")
view.separator.size = CGSize(width: 16, height: 16)
view.separator.margin = UIEdgeInsets(top: 0, left: 5, bottom: 0, right: 5)
...
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
tagList.frame = CGRect(origin: CGPoint.zero, size: CGSize(width: areaList.frame.width, height: 0))
}
TagPresentableText, TagPresentableIcon & TagPresentableIconText are already implemented, you can use it straightforwardly, or you can choose to implement TagPresentable and subclass TagContent to create your own tag.
var delegate: TagListDelegate?
var tags: [Tag] = []
var horizontalAlignment: TagHorizontalAlignment = .left | .right | .center
var verticalAlignment: TagVerticalAlignment = .left | .right | .center
var tagMargin = UIEdgeInsets(top: 3, left: 3, bottom: 3, right: 3)
var separator: SeparatorInfo = SeparatorInfo()
var isSeparatorEnabled = false
var isAutowrap = true
var selectionMode: TagSelectionMode = .none | .single | .multiple
func tagPresentables() -> [TagPresentable]
func selectedTagPresentables() -> [TagPresentable]
let tag = Tag(content: TagPresentableText("...") {
$0.label.font = UIFont.systemFont(ofSize: 16)
}, onInit: {
$0.padding = UIEdgeInsets(top: 8, left: 10, bottom: 8, right: 10)
$0.layer.borderColor = UIColor.cyan.cgColor
$0.layer.borderWidth = 2
$0.layer.cornerRadius = 5
}, onSelect: {
$0.backgroundColor = $0.isSelected ? UIColor.orange : UIColor.white
})
tag.wrappers = [TagWrapperRemover(onInit: {
$0.deleteButton.setImage(UIImage(named: "icon_delete")).withRenderingMode(.alwaysTemplate), for: .normal)
$0.space = 8
}) {
$0.deleteButton.tintColor = $1 ? UIColor.white : UIColor.black
}]
tagList.tags.append(tag)
init(content: TagPresentable, onInit: ((Tag) -> Void)? = nil, onSelect: ((Tag) -> Void)? = nil)
var content: TagPresentable { get }
var wrappers: [TagWrapper] = []
var padding: UIEdgeInsets = UIEdgeInsets(top: 3, left: 3, bottom: 3, right: 3)
var isSelected: Bool
init(_ tag: String, onContentInit: ((TagContentText) -> Void)? = nil)
init(_ tag: String, icon: String, onContentInit: ((TagContentIcon) -> Void)? = nil)
init(_ tag: String, icon: String, onContentInit: ((TagContentIconText) -> Void)? = nil)
init(onInit: ((TagWrapperRemover) -> Void)? = nil, onSelect: ((TagWrapperRemover, Bool) -> Void)? = nil)
xiongxiong, [email protected]
TagList is available under the MIT license. See the LICENSE file for more info.