KTTagsView
KTTagsView offers a Swift UIView and protocols to help you to display your own custom views as "tags". This library is very useful when you need to display your tags in a UIScrollView, as it is handled by a UIView.
💡 You can display tags using aUICollectionViewand itsUICollectionLayout, but its not very suitable to deal with a scrollable element being inside another scrollable element, making it not scrollable etc...
Features
It also includes a few styling properties:
- horizontal alignment: the horizontal alignment of the tags (
left,centerorright) - vertical alignment: the vertical alignment of the tags (
top,centerorbottom). - intertag spacing: the minimum spacing between tags.
📱 Example
💡 To run the example project, clone the repo, pod install, and run the iOS application.
Installation
CocoaPods
The preferred installation method is with CocoaPods. Add the following to your Podfile:
pod 'KTTagsView', '~> 1.0.1'Carthage
For Carthage, add the following to your Cartfile:
github "iKiKi/KTTagsView"
Usage
1) Implement your own views you need to display as tags (as usual).
They just need them to conform to the `TagSizable` protocol.
public protocol TagSizable: class {
associatedtype Tag
static func preferredSize(with contentSize: CGSize, tag: Tag, at index: Int) -> CGSize
}
💡 This protocol allows you to manipulate your own type representing a tag, through theassociatedtype.
Example with just a String as tag:
import KTTagsView
final class MyTagView: UIView {
// Implement it as usual
}
// MARK: - TagSizable
extension MyTagView: TagSizable {
static func preferredSize(with contentSize: CGSize, tag: String, at index: Int) -> CGSize {
//TODO: return the size of your view from the tag
}
}
⚠️ Make sure the returned size width do not exceed the contentSize width.
2) Implement a TagsProvider objet. This aims to hold your tags data and the graphics context to display them using KTTagsView.
This protocol is very simple.
public protocol TagsProvider: TagSizable {
var tags: [Tag] { get }
var horizontalAlignment: TagsView.HorizontalAlignment { get }
var verticalAlignment: TagsView.VerticalAlignment { get }
var minimumIntertagSpacing: CGFloat { get }
}- tags: the property holding tags data.
- horizontalAlignment: the horizontal alignment of the tags (left, center or right). This is
.leftby default. - verticalAlignment: the vertical alignment of the tags (top, center or bottom). This is
.topby default. - minimumIntertagSpacing: the spacing between tags.
💡 Note thatTagsProvideris himselfTagSizable. In fact, it is expected the object to return the size provided by your views direclty.
Please find an example below with an object called TagsViewModel (always with tags data as String):
import KTTagsView
final class TagsViewModel: TagsProvider {
var tags: [String] {
//TODO: return your
}
var horizontalAlignment: TagsView.HorizontalAlignment = .left
var verticalAlignment: TagsView.VerticalAlignment = .top
var minimumIntertagSpacing: CGFloat = 8
// MARK: - TagSizable
static func preferredSize(with contentSize: CGSize, tag: String, at index: Int) -> CGSize {
return MyTagView.preferredSize(with: contentSize, tag: tag, at: index)
}
}3) Make an object compliant to the TagsViewDataSource protocol. A convenient approach is to use the same TagsProvider objet.
It can be expected the `TagsProvider` to act as data source..
public protocol TagsViewDataSource: class {
func tagsView(_ tagsView: TagsView, sizeForTagAt index: Int) -> CGSize
func tagsView(_ tagsView: TagsView, viewForTagAt index: Int) -> UIView
}Please find an example below with the previous TagsViewModel and MyTagView object:
import KTTagsView
// MARK: - TagsViewDataSource
extension TagsViewModel: TagsViewDataSource {
func tagsView(_ tagsView: TagsView, sizeForTagAt index: Int) -> CGSize {
let tag = self.tags[index]
return MyTagView.preferredSize(with: tagsView.bounds.size, tag: tag, at: index)
}
func tagsView(_ tagsView: TagsView, viewForTagAt index: Int) -> UIView {
let tagView = MyTagView./*init()*/
let tag = self.tags[index]
//tagView.update(with: tag)
return tagView
}
}4) Finally add the TagsView to your UICollectionViewCell, UITableViewCell or any other parent UIView and call the reloadData passing your TagsProvider and TagsViewDataSource compliant objects.
import KTTagsView
final class TagsCollectionViewCell: UICollectionViewCell {
// MARK: Outlets
@IBOutlet weak var ibTagsView: TagsView!
// MARK: - Internal methods
func update(with viewModel: TagsViewModel) {
self.ibTagsView.reloadData(with: viewModel, dataSource: viewModel)
}
}License
KTTagsView is released under the MIT license. See LICENSE for details.



