Rappe Stegarn Rappe Stegarn - 5 months ago 15
Swift Question

Is there a "tag" correspondent?

I'm wondering if there is another thing such as the

tag
?

I'm already using tags on my images but I have to use multiple tags in order to create my code, which I haven't found a way to do... Therefore I'm wondering if there is another thing that works similar to the
tag
? Another way to "mark" an image?

(
image.tag = 1
) ---> example of a tag.

Answer

You can build a Singleton class to keep track of the relation between a UIImage and a tag.

class TaggedImages {
    static let sharedInstance = TaggedImages()
    private var dict = [Int:Set<UIImage>]()
    private init() { }

    func add(tag:Int, to image:UIImage) {
        var set = dict[tag] ?? Set<UIImage>()
        set.insert(image)
        dict[tag] = set
    }

    func remove(tag:Int, to image:UIImage) {
        var set = dict[tag] ?? Set<UIImage>()
        set.remove(image)
        dict[tag] = set
    }

    func images(with tag: Int) -> [UIImage] {
        guard let set = dict[tag] else { return [] }
        return Array(set)
    }

    func tags(by image: UIImage) -> [Int] {
        return dict.filter { $0.1.contains(image) }.map { $0.0 }
    }
}

As you can see this class contains a dictionary where the key is an Int (the tag) and the value is a Set of UIImage(s).

Now we can

  • associate to a given tag a group of images.
  • and each images can be associated to a variable number of tags.

Extending UIImage

Next let's add 4 methods to UIImage

extension UIImage {
    func add(tag:Int) {
        TaggedImages.sharedInstance.add(tag, to: self)
    }

    func remove(tag:Int) {
        TaggedImages.sharedInstance.remove(tag, to: self)
    }

    var tags: [Int] {
        return TaggedImages.sharedInstance.tags(by: self)
    }

    func has(tag tag:Int) -> Bool {
        return self.tags.contains(tag)
    }
}

All methods defined in the previous extension use the TaggedImages shared instance to:

  1. save a relation between the current image and a tag
  2. remove a relation image-tag
  3. retrieve all the tags associated to the current image

How to use it

let sky = UIImage()
sky.add(tag: 1)
sky.add(tag: 2)
sky.add(tag: 3)
sky.tags // [2, 3, 1]

sky.has(tag: 1) // true
sky.has(tag: 2) // true
sky.has(tag: 100) // false

sky.remove(tag:1)
sky.has(tag: 1)  // false

sky.remove(tag:1)
sky.has(tag: 1) // false
sky.tags // [2,3]