classykit / classy Goto Github PK
View Code? Open in Web Editor NEWExpressive, flexible, and powerful stylesheets for UIView and friends.
Home Page: http://classykit.github.io/Classy/
License: MIT License
Expressive, flexible, and powerful stylesheets for UIView and friends.
Home Page: http://classykit.github.io/Classy/
License: MIT License
Hi there,
When I add properties to UIView via a category, and then target those properties through a style sheet, nothing happens. It seems like Classy's reflection doesn't find properties added through extensions? Is there a workaround - or am I misdiagnosing this issue?
Thanks.
In my application, when the application is launched, it sets a default stylesheet.
But then it starts communicating with our webserver, which tells the application which stylesheet should be loaded and it switches to a different stylesheet.
This works fine, but the UICollectionViews do seem to have a problem with the background color set in the stylesheet (and maybe other properties).
UICollectionViews also had the problem that they didn't appear correctly without using a cas_styleClass. Since I added that to the UICollectionView, the background is correctly set, but now while switching theme it appears to happen again.
Ability to query device name and iOS version e.g.
UIView.widget
/* default background color */
background-color red
/* background color on iPads running iOS7 and above */
@media ipad and (version:>=7)
background-color blue
One neat feature that the-other-styling-framework (:smile:) has is support for CSS's :nth-child
pseudo-class. It comes in particularly handy for e.g. when giving alternating background colours to UITableViewCell
.
What I am currently doing is something like
- (void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath;
{
Subclass *c = (Subclass *)cell;
[cell setBackgroundColor:[indexPath row] % 2 ? [c firstColor] : [c secondColor]];
}
And the stylesheet has:
Subclass {
first-color: #fff;
second-color: #ddd;
}
It'd be great if there was a better way to do this!
Hey, I'm in the midst of porting a rather large app over to using Classy styles and was wondering if you had any thoughts on this use case. In this app, all labels should be OpenSans font, but we use xibs and I'd like to let the font size set in the xib remain the font size after changing the font face. In theory, perhaps something like this:
UILabel {
font: OpenSans inherit; // inherit here means inherit the existing font size of the UILabel
}
This seems fairly non-trivial to implement and perhaps even is against the approach Classy takes (with how it constructs invocations up front) making it not really possible. But, do you see this as a valid use case at all or have any thoughts on how to accomplish this differently?
Thanks!
Say I have this stylesheet:
UIButton.green-button {
background-color: green;
}
UIButton.green-button {
background-color: red;
}
My .green-button
should actually be red, assuming we are playing by CSS rules in this case, but it is still green. I've traced it down to this line https://github.com/cloudkite/Classy/blob/master/Classy/Parser/CASStyler.m#L61 which seems to apply styles from bottom to top. If I flip that to be top to bottom it works the way I want it to. Is there a reason for using reverseObjectEnumerator
there that I'm not getting?
Anyway, I can't tell you how much I love this project, so thanks!
I'm running into an issue in which a global style set on a UILabel appears to override more specific styles attached to the attributedText attribute of a particular label––in my case, an icon font and color. Here's roughly what my .cas file looks like:
UILabel {
font: HelveticaNeue-Thin 17.0;
text-color: #333;
}
And then, in code:
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
FAKIcon *icon = [FAKFontAwesome trophyIconWithSize:20];
[icon addAttribute:NSForegroundColorAttributeName value:[UIColor yellowColor]];
self.trophyLabel.attributedText = [icon attributedString];
}
My expectation is that the attributedText font properties should always take precedence––indeed, the idea that a global UILabel setting could override this everywhere seems rather alarming. Is this an iOS limitation? Am I nuts?
UIViewController supports CASStyleableItem yet does not get updated. UIView cas_updateStyling doesn't branch out to its ViewController.
Why not? Bug or by design?
I'd like to be able to update properties on my ViewController which control its views.
if a new view, ex: viewcontroller pushed on the navigationcontroller, but is offscreen. the styling doesn't take place.
Great library, looks very promising. One feature that would make this library more useful in larger projects would be the ability to @import
.cas files into stylesheet.cas
. Large projects may have hundreds of views and keeping all of it in one file would become unwieldy fairly quickly.
Thoughts?
We need to get certain styled properties before the hierarchy is complete. To do that I manually call cas_updateStyling on view when I know that the hierarchy is deep enough for the proper styles to get applied. This no longer works because cas_updateStyling in UIView+CASAddtions checks for self.window, which is nil at that point. Why does it do the check?
I cannot set UIButton's clipsToBounds property. This is the code I use:
UIButton {
clipsToBounds: YES;
}
Console returns:
[Classy] -[CASObjectClassDescriptor propertyDescriptorForKey:] Property 'clipsToBounds' not found. Class 'UIView'
Tested on iOS 6.1 and iOS 7.0.2.
I noticed that Classy has a memory leak when running my app through Instruments. Views that have styles applied never get deallocated. The issue seems to be a combination of [invocation retainArguments]
and [self.invocation invokeWithTarget:resolvedTarget]
.
The issue seems to be the target
being retained. I noticed that nilling out the target after invoking didn't seem to help. Any ideas?
When i have a custom button class "CustomButton" that extends from UIButton with class name "cc"
this won't work
^UIButton.cc {
background-color: red;
}
I apologize if I missed this in the documentation, but how would I set the font family or size of the UIFont property titleLabel
on a UIButton?
For our current project we need to develop an app with two different themes, i.e. mainly different fonts and colors. To achieve this we have created a target for each theme, and a Theme Manager class with a bunch of class method that return correct colors depending on the currently built target. So, for example, I can call UIColor *color = [ThemeManager mainBackgroundColor];
anywhere to get the main background color for the currently built theme.
However, we would like to integrate Classy into our project, and we are trying to find a workaround for the above without having two separate stylesheets for the color variables of each theme. In Classy you have made it possible to specify a bunch of colors using their names, e.g. "orangered", and I was wondering how you are making that possible, since I would like to try to extend these colors to include, for example, mainBackgroundColor.
Any help would be very much appreciated!
It would be great to see some wrappers around cell customization - specifically things like selectedbackgroundcolor.
Additional examples/docs around creating custom implementations would be good too.
CASObjectClassDescriptor *objectClassDescriptor = [[CASStyler defaultStyler] objectClassDescriptorForClass:[UITableViewCell class]];
CASArgumentDescriptor *colorArg = [CASArgumentDescriptor argWithClass:UIColor.class];
[objectClassDescriptor setArgumentDescriptors:@[colorArg] setter:@selector(setSelectedBackgroundColor:) forPropertyKey:@"selectedBackgroundColor"];
Hi
We are using Classy on a project that has a UIPageViewController where each page has a UICollectionView.
When paging through the pages in the UIPageViewController we notice a small delay and with an attached profiler we notice that some of the time is spent in Classy.
Any advice on a workaround to remove the delay would be great.
{
, }
, ;
, :
are all optional)styleClass
to any view/*hello comment*/
and //hello comment
&
concat nested selectorsHere's a weird but frustrating one:
I'm trying to set a UIImageView subclass's contentMode property to aspect fit (UIViewContentModeScaleAspectFit) using a stylesheet.
All of the below fail and result in the enum value of UIViewContentModeScaleToFill (0) being applied instead:
content-mode: scale-aspect-fit
content-mode: scaleAspectFit
content-mode: scaleaspectfit
content-mode: UIViewContentModeScaleAspectFit
content-mode: 1
However, enum constants with less camel-cased words work just fine, e.g.:
content-mode: top-left
So I'm guessing this is something that happens when more than two camel-cased words are appended to the enum name when naming the constant? For example:
typedef NS_ENUM(NSInteger, MyEnumType) {
MyEnumTypeOne, // works
MyEnumTypeOneTwo, // works
MyEnumTypeOneTwoThree, // will not work?
};
Or maybe it's just based on the total length of the constant name? Any suggestions / workarounds since even using the integer value doesn't seem to work?
Hi CloudKite
Thanks for the excellent library.
What would be really nice, if I could set the TintColor for UIImageViews.
One simple way of doing this would be to add the line 335 to CASStyler.m:
[objectClassDescriptor setArgumentDescriptors:@[colorArg] forPropertyKey:@cas_propertykey(UIView, tintColor)];
Kind Regards
Graham
Hi cloudkite,
I love classy, thank you for this awesome framework.
Changing a style class at runtime is very known from web applications. Like expand collapse cases for example.
Question:
Example use case.
I want to add some class on a button after it was clicked.
So in my View I do something like that:
[self.myButton cas_addStyleClass:@"expanded"];
Then I remove the style class if its clicked again.
[self.myButton cas_removeStyleClass:@"expanded"];
Is that a feasible way to use classy?
Do I need to call something else to update the view hierarchy?
While that in general works, it is not supporting any animations inside the animation block.
[UIView animateWithDuration:defaultAnimationDuration
animations:^{
So I dont know what exactly I need to do to perform this style class change as an animation.
I've previously used the Pixate framework, but got very excited by Classy's development due to its open-source nature. In my mind, Classy's primary competitive advantage is (was) the fact that it was open source: if there was a bug, I could fix it myself and not be dependent on upstream (not that it's been a problem yet!)
It seems that a couple of weeks ago Pixate went open source and is now available on Github: https://github.com/pixate/pixate-freestyle-ios
Users will now be comparing Pixate and Classy directly. Perhaps a list of pros and cons for Classy vs Pixate in the README would be useful? What are your thoughts?
EDIT: Perhaps a comparison to NUI would be useful too?: https://github.com/tombenner/nui
Is it normal that the styling of the elements of my uitableviewcell's takes place after layoutSubview is called. because I need different layout depending on the styling of the items.
Nice tool. 😄
What about pseudo classes?
^UIButton:highlighted {
textColor: orange;
}
Would it be possible to change the styling of a UIView by changing the styleClass to a different string?
I have created a feature request for classy.as (.cas file) support in AppCode. Please vote it here if you also need this: http://youtrack.jetbrains.com/issue/OC-8889
I have a global UILabel style that looks something like this:
UILabel {
font: HelveticaNeue-Thin 17.0;
text-color: #333;
}
Followed by a nested rule that's specific to tables:
^UITableViewCell {
UILabel {
text-color: blue;
}
}
My expectation is that the latter rule should take precedence over the former––it appears to have a higher level of specificity. However, the table label remains stubbornly gray until I comment out the global rule, at which point it recolors as expected. Am I doing something wrong?
Hi! Really like what you're doing with Classy, and I'm exploring its suitability for a large project I'm working on. One requirement this project has is the ability to load icons and images for styled elements from a URL, as opposed to only using resources in the app's bundle.
In Pixate / CSS, doing this works something like:
.myClass {
background-image: url("http://somewhere.com/images/icon.png");
}
Is there a similar functionality implemented or planned for Classy?
For unrecognised properties, classes, arguments etc
At the moment some things are silently ignored.
current example app is empty
After a pleasant conversation at the water cooler, @cloudkite pointed out that I was getting my jimmies rustled about the whitespace delimited style code for no reason: I can use braces and semicolons like a decent human being as well!
There's no need to behave like an animal and pretend whitespace is a good way to format and structure code!
I have a UILabel
and do the following:
label.cas_styleClass = @"label";
label.text = @"someString";
[label sizeToFit];
And in Classy I simply change the font:
UILabel.label {
font: ArialMT 10;
}
What happens is that the label is resized according to the size of the text using the default system font, and it is then styled in Classy, so the end result is that the frame of the label does not fit neatly around the text of the label.
It would be really cool to target properties specifically for the iPhone 5/5s. I use classy for specifying size and margin constants used by AutoLayout (check out http://codeblog.shape.dk/blog/2013/12/16/live-editing-layout-constants-using-classy/ and https://github.com/olegam/ClassyLiveLayout).
Often the height constant or the top/bottom margin for a view is different for the 3.5 inch screen than for the 4 inch. It would be nice to specify both values in the stylesheet and have Classy automatically pick the right one according to the screen size. Somewhat similar to CSS media queries. This could also be useful for font sizes, insets and other kinds of properties.
The syntax could maybe look something like this:
UIButton.signup-button {
margin-top<h568>: 40;
margin-top: 20;
size: 100 20;
}
The screen size specifier will override any normal properties matching all other screen sizes. What do you think? Is there already a way to accomplish something like this?
Classy looks to be a fantastic library - I've evaluated many different solutions, but so far what you've started fits in quite well with what I've envisioned.
I've spent the last hour or so digging through the code, and wanted to hear your thoughts on keypath support such as:
- MyViewController.view
- MyViewController.myCustomView.firstButton
This may break the paradigm that you've laid the foundation for, but was the natural way I started to write styles. I'd be happy to expand on this in my own fork, but wanted to first gauge your thoughts.
Properties-Basic.cas file shows that a size property can be set for UIButton. But when trying this out it reports "Property 'size' not found".
filename: Properties-Basic.cas
UISlider, UINavigationBar UIButton font-name helvetica size 40 50 text-color: #444
If you apply a style to sectionHeaders of UITableView, then while scrolling the styles don't reapply until you finish scrolling.
I'd like to request support for array values in styles. Specifically, this is to enable setting array of colors and locations on a CAGradientLayer within a custom view class. I imagine there might be other uses as well in other custom subclass scenarios.
This might look something like:
MyCustomView {
gradientLayer: @ {
colors: [red, rgb(160, 180, 220), green]
locations: [0.0, 0.2, 1.0]
}
}
When I try to set title-color for specific control states they don't seem to take the state into account. So in the following example the color will be the same for all states and the last property overrides the first one.
UIButton.login-submit-button {
title-color[controlState: normal]: white;
title-color[controlState: disabled]: #ffffff66;
}
Any idea of what's wrong here? Is the title-color property not supported?
rgb or rgba expression e.g.
background-color: rgb(255,0,0)
First of all, I want to thank you for your hard work on this awesome project. I recently discovered that classy supports media queries, but following snippet of cas will throw exception when run on iPad (this also happens when using @media iphone and (version:<7.0)
and removing @device iphone
:
@device iphone {
UILabel.label2 {
@media (version: < 7.0) {
text-color: #0f0;
}
@media (version: >= 7.0) {
text-color: #00f;
}
font: HelveticaNeue 120;
}
}
Stacktrace (line throwing exception is 106 in CASStyler.m, using 0.2.0 from cocapods):
2013-12-18 11:25:46.977 n42[15934:80b] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM removeObjectAtIndex:]: index 3 beyond bounds [0 .. 2]'
*** First throw call stack:
(
0 CoreFoundation 0x020f25e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x01e758b6 objc_exception_throw + 44
2 CoreFoundation 0x020936aa -[__NSArrayM removeObjectAtIndex:] + 442
3 n42 0x0006fac3 __31-[CASStyler setFilePath:error:]_block_invoke + 515
4 CoreFoundation 0x0216f05d __53-[__NSArrayI enumerateObjectsWithOptions:usingBlock:]_block_invoke + 61
5 CoreFoundation 0x0216ef92 -[__NSArrayI enumerateObjectsWithOptions:usingBlock:] + 258
6 CoreFoundation 0x020ec0a5 -[NSArray enumerateObjectsUsingBlock:] + 53
7 n42 0x0006f215 -[CASStyler setFilePath:error:] + 1525
8 n42 0x0006eba0 -[CASStyler setFilePath:] + 112
9 n42 0x00077ce1 -[CASStyler setWatchFilePath:] + 129
That would help a lot in writing the specs / cas files!
Example: https://github.com/ricobeck/KFCocoaPodsPlugin
Great tool. Thanks.
Example
MYHomeViewController > UIButton.main {
background-color black
}
First of all, congrats for your great work!
I'm using Classy in iOS 7 and setting a different UINavigationBar+StatusBar color on a CAS file. However, the text color on Status Bar is not good with the new color and should be change to white, for example.
Is there a way to change the Status Bar style through Classy?
Hey Guys,
first of all , thanks for you work, I love classy.
I worked from the latest git branch directly and was able to set several classes on one styleClassId like:
self.userName = [[MYTextField alloc] initWithStyleClassId:@"primaryTextfield userName"
Where the firstclass is rather global style and userName a chance to set things specifically to this element.
With a new update today it seems like this feature is gone again.
Can you give me a hint what to do?
If this is not possible anymore can you at least give the revision number from which I could fork and work for now with this feature still working?
Thanks in advance?
Firstly, this project is freakin awesome.
Just wondering if there is support for setting something like text color for a UISegmentedControl which is done via setTitleTextAttributes:forState and takes a dictionary for the style settings?
Thanks.
Enable color utilities such as lighten, darken, desaturate, saturate
Hi
Our current project uses [CASStyler defaultStyler].variables to define brand specific stylesheets that are @import'ed in the main stylesheet.
We are seeing errors from the CASStyler like this:
[Classy] -[CASStyler setFilePath:] Error: Error Domain=CASParseErrorDomain Code=2 "Could not parse file" UserInfo=0x155357e0 {NSLocalizedFailureReason=File does not exist or is empty, NSLocalizedDescription=Could not parse
As an attempt to get rid os the errors we have tried renaming our main stylesheet to 'stylesheet.cas', but that breaks the @import of stylesheets defined by variables as these are set after the stylesheet has been parsed.
Any ideas on how to get rid of the errors?
I am using DTCoreText in my application and I would like to style the NSAttributedString ,that DTCoreText generates, using my stylesheet.
Currently I am using DTAttributedTextCell but all styling of text using DTCoreText is done by supplying a NSDictionary with a couple of parameters.
For example:
NSDictionary* options = @ {
@"DTDefaultFontSize": @13,
@"DTDefaultFontFamily": @"Helvetica Neue",
@"DTDefaultTextColor" : [UIColor redColor]
};
[textCell setHTMLString:htmlText options:options];
My stylesheet:
DTAttributedTextCell.description {
background-color: white;
font: "HelveticaNeue-Medium" 13;
text-color: black;
}
It would be a solution to query the Stylesheet in someway, that we get back a NSDictionary or something with the right values.
After that, the user should do the conversion themselves (Convert the UIFont to a Font Family text)
We use Classy for a project and would like to use the @import feature for branding the app in two versions (different fonts, colors and graphics).
So we have a main style ‘Resources/styles.cas’ and a variable part ‘Resources/brandxvariables.cas’ that is @import'ed from the main file.
This works well if the @import is not variable, but what we would really like to do is this (contents of ‘Resources/styles.cas’):
@import "$brandvariables"
UIView.view1 {
background-color: $view1color;
}
UIView.view2 {
background-color: $view2color;
}
The $brandvariables variable is set in the AppDelegate like this:
[CASStyler defaultStyler].variables = @{@"$brandvariables": @“brand1variables.cas" };
Contents of ‘Resources/brand1variables.cas’:
$view1color = #ff0000;
$view2color = #00ff00;
This causes Classy to throw an Exception:
0 CoreFoundation 0x019b65e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x017398b6 objc_exception_throw + 44
2 CoreFoundation 0x01968bcc -[__NSArrayM insertObject:atIndex:] + 844
3 CoreFoundation 0x01968870 -[__NSArrayM addObject:] + 64
4 ClassyBrandTest - Brand1 0x00009832 -[CASLexer lookaheadByCount:] + 482
5 ClassyBrandTest - Brand1 0x0000953e -[CASLexer peekToken] + 62
6 ClassyBrandTest - Brand1 0x000101dc __48+[CASParser parserFromFilePath:variables:error:]_block_invoke + 620
7 CoreFoundation 0x01a3f40c __65-[__NSDictionaryI enumerateKeysAndObjectsWithOptions:usingBlock:]_block_invoke + 76
8 CoreFoundation 0x01a3f32e -[__NSDictionaryI enumerateKeysAndObjectsWithOptions:usingBlock:] + 238
9 CoreFoundation 0x019a4525 -[NSDictionary enumerateKeysAndObjectsUsingBlock:] + 53
10 ClassyBrandTest - Brand1 0x0000fb80 +[CASParser parserFromFilePath:variables:error:] + 1088
11 ClassyBrandTest - Brand1 0x0001e57a -[CASStyler setFilePath:error:] + 298
12 ClassyBrandTest - Brand1 0x0001e3d0 -[CASStyler setFilePath:] + 112
13 ClassyBrandTest - Brand1 0x00028181 -[CASStyler setWatchFilePath:] + 129
I think the lexer has a problem with the dot in ‘brand1variables.cas’.
Any suggestions?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.