ClassyKit / Classy

Expressive, flexible, and powerful stylesheets for UIView and friends.
http://classykit.github.io/Classy/
MIT License
740 stars 76 forks source link

Swift compatibility #81

Closed wimhaanstra closed 7 years ago

wimhaanstra commented 10 years ago

I am using Classy in a Swift project, and with default controls (like UICollectionViewCell) it seems to be working fine. But now I added a subclass of a UICollectionViewCell called SensorCell. I added an entry to my styling file:

SensorCell {
    background-color: #f1f1f1;

    UILabel {
        font: $light-font 20;
    }
}

Then I get this error:

2014-09-17 08:43:02.214 HCP[31903:619635] [Classy] -[CASStyler setFilePath:] Error: Error Domain=CASParseErrorDomain Code=2 "Invalid class nameSensorCell" UserInfo=0x79247260 {CASParseFailingStringErrorKey=" background-color: #f1f1 ...", NSLocalizedFailureReason=Every selector must have a objectClass, NSLocalizedDescription=Invalid class nameSensorCell, CASParseFailingLineNumberErrorKey=38}

TheCoordinator commented 9 years ago

Any progress on this?

dukeflyheli commented 9 years ago

I know what is happening. With swift class names have generated prefixes for the module support. I am using a temp solution and will post that shortly.

wimhaanstra commented 9 years ago

That would be great!

TheCoordinator commented 9 years ago

Check this out guys, seems to be working:

https://github.com/Snupps/Classy/commit/b4c6f2c7403706f1f01b73b5d6e0491c06b2651a

dukeflyheli commented 9 years ago

Apologies for the delay.

Here is my workaround for swift: https://github.com/dukeflyheli/Classy/commit/19311c21b85ec769ec63cfd73e07f9b3827e1f3a

Essentially swift prepends everything with its module or framework identifier. We are working with multiple internal frameworks and some external. What that commit shows you is how to add a bit of code to check multiple modules for the class instead of just the one. I was unable to figure out how to dynamically check all included frameworks/modules so I just have a class that overrides +()load to initialize the styler with all the framework/module names.

Below is an example of the +()load override. As an aside I use this object to pass constants from the cas file to code so I can reference variables from the cas file without duplication.

public class MyLib: UIView{

    var smallMargin = CGFloat(0)

    public class var sharedInstance: MyLib {
        struct Singleton {
            static let instance:MyLib = {
                let lib = MyLib()
                CASStyler.defaultStyler().styleItem(lib)
                return lib
            }()
        }
        return Singleton.instance
    }

    public override class func load(){
        CASStyler.defaultStyler().classModulesToCheck = NSSet(array:
            [
                "MyCoolFramework1",
                "MyCoolFramework2",
                "MyMainTarget",
            ])
    }
}
andreyvit commented 9 years ago

A real workaround is to use @objc to expose a Classy-friendly name. A proper fix would probably be to allow (a list of?) module names in the .cas file itself.

atsepkov commented 9 years ago

Thanks for the tip, I prefer @objc workaround as well.

dnedrow commented 7 years ago

@depl0y , can you close this issue if one of the answers (in particular @objc) is acceptable?

wimhaanstra commented 7 years ago

Sure, the @objc workaround is acceptable