Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make extension for multiple classes Swift

I have an extension:

extension UILabel {
    func animateHidden(flag: Bool) {
        self.hidden = flag
    }
}

I need to make the same one for UIImageView but I don't want to copy that whole code. Is it possible to make an extension for multiple classes?

Thanks.

like image 847
Danny Avatar asked Jul 19 '16 16:07

Danny


People also ask

Can we extend structure in Swift?

It is not possible to subclass a struct in Swift, only classes can be subclassed. An extension is not a subclass, it's just adding additional functionality on to the existing struct , this is comparable to a category in Objective-C.

Can we create extension of final class in Swift?

An extension may not contain stored properties but you can add methods inside. Show activity on this post. Show activity on this post. Show activity on this post.

What is difference between extension and inheritance Swift?

Only the instances of the subclass can use the new methods. Another diff : In extension, there is no any specific name of extension in swift, but while subclassing there is another name of subclass. In extension, we can not add variables (fields), in subclass it is possible to declare variables.


2 Answers

You could make a protocol and extend it.

Something like:

protocol Animations {
    func animateHidden(flag: Bool)
}

extension Animations {
    func animateHidden(flag: Bool) {
        // some code
    }
}

extension UILabel: Animations {}

extension UIImageView: Animations {}

Your method will be available for the extended classes:

let l = UILabel()
l.animateHidden(false)

let i = UIImageView()
i.animateHidden(false)

In a comment, you've asked: "in this case how to call self for UILabel and UIImageView in animateHidden function?". You do that by constraining the extension.

Example with a where clause:

extension Animations where Self: UIView {
    func animateHidden(flag: Bool) {
        self.hidden = flag
    }
}

Thanks to @Knight0fDragon for his excellent comment about the where clause.

like image 82
Eric Aya Avatar answered Oct 21 '22 18:10

Eric Aya


Best Method to Extend UILabel & UIImageView Together

Swift 4.1 / Xcode 9.4

A much better way to do this in your case would be to just extend UIView. This works because both UILabel and UIImageView both inherit from UIView.


Extension

extension UIView {
    func animateHidden(flag: Bool) {
        self.hidden = flag
    }
}

Usage of animateHidden(flag: Bool) Extension

Declaration of label and imageView:

label = UILabel()
imageView = UIImageView()

Actual usage of extension

label.animateHidden(flag: true)
imageView.animateHidden(flag: false)

Bonus - Other Classes that many UI Components Conform to

If you would like to have your extension be able to conform with many different types of UI components, there are 4 types that a very large amount of UI components conform to:

  1. CVarArg
  2. Equatable
  3. Hashable
  4. NSCoding

Some of the many UI components include:

  • UILabel: CVarArg, Equatable, Hashable, NSCoding

  • UITextField: CVarArg, Equatable, Hashable, NSCoding

  • UITableViewCell: CVarArg, Equatable, Hashable, NSCoding

  • UITextView: CVarArg, Equatable, Hashable, NSCoding

  • UITableView: CVarArg, Equatable, Hashable, NSCoding

  • UIImage: CVarArg, Equatable, Hashable, NSCoding

  • UIPickerView: CVarArg, Equatable, Hashable, NSCoding

  • UIView: CVarArg, Equatable, Hashable, NSCoding

  • UIImageView: CVarArg, Equatable, Hashable, NSCoding

  • UINavigationBar: CVarArg, Equatable, Hashable, NSCoding

  • UIButton: CVarArg, Equatable, Hashable, NSCoding

  • UIBarButtonItem: CVarArg, Equatable, Hashable, NSCoding

  • UIStackView: CVarArg, Equatable, Hashable, NSCoding

  • UIToolbar: CVarArg, Equatable, Hashable, NSCoding

  • UITabBar: CVarArg, Equatable, Hashable, NSCoding

  • UITabBarItem: CVarArg, Equatable, Hashable, NSCoding

  • UIScrollView: CVarArg, Equatable, Hashable, NSCoding

  • UISplitViewController: CVarArg, Equatable, Hashable, NSCoding

  • UIViewController: CVarArg, Equatable, Hashable, NSCoding

  • UIScreen: CVarArg

  • UISwitch: CVarArg, Equatable, Hashable, NSCoding

  • UISlider: CVarArg, Equatable, Hashable, NSCoding

  • UIAlertAction: CVarArg

  • UIAlertController: CVarArg, Equatable, Hashable, NSCoding

  • UIImageAsset: CVarArg, Equatable, Hashable, NSCoding

  • UIDatePicker: CVarArg, Equatable, Hashable, NSCoding

  • UINib: CVarArg

  • UIResponder: CVarArg

  • UIWindow: CVarArg, Equatable, Hashable, NSCoding

  • UIRegion: CVarArg, Equatable, Hashable, NSCoding

  • UIControl: CVarArg, Equatable, Hashable, NSCoding

  • UIBezierPath: CVarArg, Equatable, Hashable, NSCoding

  • UIVisualEffect: CVarArg, Equatable, Hashable, NSCoding

  • UISearchBar: CVarArg, Equatable, Hashable, NSCoding

  • UIMenuItem: CVarArg

  • UIMenuController: CVarArg

  • UIStoryboard: CVarArg

  • And many more...


This means that by extending either CVarArg, Equatable, Hashable, or NSCoding, you can extend most (if every not every) UI component.



Well anyways, I hope this all helps you resolve your issue and if you have absolutely any questions, suggestions, etc., feel free to ask!



like image 43
Noah Wilder Avatar answered Oct 21 '22 19:10

Noah Wilder