├── .gitignore ├── .travis.yml ├── CHANGES.md ├── Gemfile ├── InterfaCSS Tests ├── ISSSelectorTests.m ├── ISSStyleSheetParserTests.m ├── InterfaCSS Tests-Info.plist ├── InterfaCSS Tests-Prefix.pch ├── InterfaCSSTests.m ├── TestData │ ├── interfaCSSTests-variables.css │ ├── interfaCSSTests.css │ ├── scopedStyles.css │ ├── styleSheetPropertyValues.css │ ├── styleSheetStructure.css │ ├── styleSheetWithBadData.css │ └── viewDefinitionTest.xml └── en.lproj │ └── InfoPlist.strings ├── InterfaCSS.podspec ├── InterfaCSS.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcshareddata │ └── xcschemes │ └── UnitTests.xcscheme ├── InterfaCSS ├── InterfaCSS-Prefix.pch ├── InterfaCSS.h ├── InterfaCSS.m ├── Model │ ├── ISSLayout.h │ ├── ISSLayout.m │ ├── ISSLazyValue.h │ ├── ISSLazyValue.m │ ├── ISSNestedElementSelector.h │ ├── ISSNestedElementSelector.m │ ├── ISSPointValue.h │ ├── ISSPointValue.m │ ├── ISSPropertyDeclaration.h │ ├── ISSPropertyDeclaration.m │ ├── ISSPropertyDeclarations.h │ ├── ISSPropertyDeclarations.m │ ├── ISSPropertyDefinition.h │ ├── ISSPropertyDefinition.m │ ├── ISSPropertyRegistry.h │ ├── ISSPropertyRegistry.m │ ├── ISSPseudoClass.h │ ├── ISSPseudoClass.m │ ├── ISSRectValue.h │ ├── ISSRectValue.m │ ├── ISSRemoteFont.h │ ├── ISSRemoteFont.m │ ├── ISSSelector.h │ ├── ISSSelector.m │ ├── ISSSelectorChain.h │ ├── ISSSelectorChain.m │ ├── ISSStyleSheet.h │ ├── ISSStyleSheet.m │ ├── ISSStylingContext.h │ ├── ISSStylingContext.m │ ├── ISSUIElementDetails.h │ ├── ISSUIElementDetails.m │ ├── ISSUpdatableValue.h │ ├── ISSUpdatableValue.m │ ├── ISSViewPrototype.h │ └── ISSViewPrototype.m ├── Parser │ ├── ISSDefaultStyleSheetParser.h │ ├── ISSDefaultStyleSheetParser.m │ ├── ISSParser+CSS.h │ ├── ISSParser+CSS.m │ ├── ISSParser.h │ ├── ISSParser.m │ ├── ISSStyleSheetParser.h │ ├── ISSViewHierarchyParser.h │ └── ISSViewHierarchyParser.m ├── UI │ ├── ISSLayoutContextView.h │ ├── ISSLayoutContextView.m │ ├── ISSRootView.h │ ├── ISSRootView.m │ ├── ISSViewBuilder.h │ ├── ISSViewBuilder.m │ ├── UICollectionView+InterfaCSS.h │ ├── UICollectionView+InterfaCSS.m │ ├── UITableView+InterfaCSS.h │ ├── UITableView+InterfaCSS.m │ ├── UIView+ISSPrototypeReusableView.h │ ├── UIView+ISSPrototypeReusableView.m │ ├── UIView+InterfaCSS.h │ └── UIView+InterfaCSS.m └── Util │ ├── ISSDateUtils.h │ ├── ISSDateUtils.m │ ├── ISSDownloadableResource.h │ ├── ISSDownloadableResource.m │ ├── ISSRefreshableResource.h │ ├── ISSRefreshableResource.m │ ├── ISSRuntimeIntrospectionUtils.h │ ├── ISSRuntimeIntrospectionUtils.m │ ├── NSArray+ISSAdditions.h │ ├── NSArray+ISSAdditions.m │ ├── NSAttributedString+ISSAdditions.h │ ├── NSAttributedString+ISSAdditions.m │ ├── NSDictionary+ISSDictionaryAdditions.h │ ├── NSDictionary+ISSDictionaryAdditions.m │ ├── NSMutableArray+ISSAdditions.h │ ├── NSMutableArray+ISSAdditions.m │ ├── NSObject+ISSLogSupport.h │ ├── NSObject+ISSLogSupport.m │ ├── NSString+ISSStringAdditions.h │ ├── NSString+ISSStringAdditions.m │ ├── UIColor+ISSColorAdditions.h │ ├── UIColor+ISSColorAdditions.m │ ├── UIDevice+ISSAdditions.h │ └── UIDevice+ISSAdditions.m ├── LICENSE ├── README.markdown ├── Resources └── InterfaCSS-title-logo.png └── Samples ├── HelloISSLayout ├── HelloISSLayout.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata ├── HelloISSLayout.xcworkspace │ └── contents.xcworkspacedata ├── ISSLayout │ ├── AppDelegate.swift │ ├── Base.lproj │ │ └── LaunchScreen.xib │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Info.plist │ ├── ViewController.swift │ ├── layout.css │ ├── layout.xml │ └── styles.css └── Podfile └── SimpleSample ├── Podfile ├── SimpleSample.xcodeproj ├── project.pbxproj └── project.xcworkspace │ └── contents.xcworkspacedata └── SimpleSample ├── AppDelegate.h ├── AppDelegate.m ├── Default-568h@2x.png ├── IBViewController.css ├── IBViewController.h ├── IBViewController.m ├── IBViewController.xib ├── PrototypeExampleViewController.h ├── PrototypeExampleViewController.m ├── SimpleSample-Info.plist ├── SimpleSample-Prefix.pch ├── SimpleSampleViewController.h ├── SimpleSampleViewController.m ├── constants.css ├── en.lproj └── InfoPlist.strings ├── image.png ├── main.css ├── main.m ├── prototypeExample.css └── views.xml /.gitignore: -------------------------------------------------------------------------------- 1 | **/xcuserdata/** 2 | *.xcuserdatad 3 | *.xcuserstate 4 | *.xcbkptlist 5 | *.pbxuser 6 | *.xcbaseline 7 | *.xccheckout 8 | *.hmap 9 | *.ipa 10 | build/ 11 | Pods 12 | Podfile.lock 13 | InterfaCSS.xcworkspace 14 | Samples/*/*.xcworkspace 15 | .idea 16 | notes 17 | .DS_Store 18 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | osx_image: xcode9.2 2 | language: objective-c 3 | 4 | before_install: 5 | - gem install xcpretty --no-rdoc --no-ri --no-document --quiet 6 | - export LANG=en_US.UTF-8 7 | 8 | script: xcodebuild clean test -project InterfaCSS.xcodeproj -scheme UnitTests -destination 'platform=iOS Simulator,name=iPhone 8' | xcpretty -c && exit ${PIPESTATUS[0]} 9 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | #source 'https://rubygems.org' 2 | 3 | #gem 'cocoapods', :git => 'https://github.com/CocoaPods/CocoaPods.git', :branch => 'master' 4 | #gem 'cocoapods-core', :git => 'https://github.com/CocoaPods/Core.git', :branch => 'master' 5 | #gem 'xcodeproj', :git => 'https://github.com/CocoaPods/Xcodeproj.git', :branch => 'master' 6 | 7 | #gem 'cocoapods-keys' 8 | #gem 'cocoapods-deintegrate' 9 | -------------------------------------------------------------------------------- /InterfaCSS Tests/InterfaCSS Tests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /InterfaCSS Tests/InterfaCSS Tests-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #ifdef __OBJC__ 8 | #import 9 | #import 10 | 11 | #import "NSString+ISSStringAdditions.h" 12 | #endif 13 | 14 | #define ISSAssertEqualFloats(x, y, ...) XCTAssertTrue(ISS_EQUAL_FLT(x, y), __VA_ARGS__) 15 | -------------------------------------------------------------------------------- /InterfaCSS Tests/TestData/interfaCSSTests-variables.css: -------------------------------------------------------------------------------- 1 | .reuseTest { 2 | alpha: @globalVariableTest; 3 | } 4 | -------------------------------------------------------------------------------- /InterfaCSS Tests/TestData/interfaCSSTests.css: -------------------------------------------------------------------------------- 1 | @globalVariableTest: 0.33; 2 | @globalVariableTest2: red; 3 | 4 | // Test caching using enabled/disabled pseudo class 5 | .class1 uilabel:enabled { 6 | alpha: 0.25; 7 | } 8 | 9 | .class1 uilabel:disabled { 10 | alpha: 0.75; 11 | } 12 | 13 | .class1 uicontrol:enabled uilabel { 14 | alpha: 0.33; 15 | } 16 | 17 | .class1 uicontrol:disabled uilabel { 18 | alpha: 0.66; 19 | } 20 | 21 | .class2 { 22 | showsTouchWhenHighlighted: YES; 23 | alpha: 0.99; 24 | } 25 | 26 | .class10 { 27 | alpha: 0.1; 28 | } 29 | 30 | .classTop { 31 | .classMiddle { 32 | .class12 { 33 | alpha: 0.3; 34 | } 35 | 36 | .class11 { 37 | alpha: 0.2; 38 | } 39 | 40 | .abc123 { 41 | alpha: 0.31; 42 | } 43 | 44 | .x123abc { 45 | alpha: 0.32; 46 | } 47 | 48 | .zyxvyt { 49 | alpha: 0.33; 50 | } 51 | 52 | .abc123abc { 53 | alpha: 0.34; 54 | } 55 | 56 | .x123abc123 { 57 | alpha: 0.35; 58 | } 59 | } 60 | } 61 | 62 | .class13 { 63 | alpha: 0.4; 64 | } 65 | 66 | .overwriteTest { 67 | alpha: 0.5; 68 | titleLabel.alpha: 0.25; 69 | } 70 | 71 | .attributedTextTest { 72 | alpha: 0.5; 73 | font: HelveticaNeue-Bold 10; 74 | textColor: #998877; 75 | } 76 | 77 | UIView.disabledStylingTest { 78 | alpha: 0.5; 79 | 80 | UILabel { 81 | alpha: 0.5; 82 | } 83 | } 84 | 85 | .cascadingStylePropertyOverrideWithDefault1 { 86 | alpha: 0.666; 87 | } 88 | 89 | .cascadingStylePropertyOverrideWithDefault2 { 90 | alpha: current; 91 | } 92 | 93 | .testDisableProperty { 94 | alpha: 0.5; 95 | } 96 | 97 | .labelAttributedTextTest { 98 | attributedText: "text" (font: HelveticaNeue-Medium 12, color: blue); 99 | } 100 | 101 | .buttonAttributedTitleTest { 102 | attributedTitle: "text" (font: HelveticaNeue-Medium 12, color: blue); 103 | attributedTitle(highlighted): "text" (font: HelveticaNeue-Medium 12, color: red); 104 | } 105 | 106 | .shadowTest1 { 107 | layer.shadowColor: red; 108 | shadowOffset: size(1,2); 109 | shadowOpacity: 0.5; 110 | shadowRadius: 10; 111 | } 112 | 113 | .shadowTest2 { 114 | shadowColor: red; 115 | shadowOffset: size(1,2); 116 | } 117 | 118 | .sizeToFitTest1 { 119 | frame: sizeToFit().top(10).left(20); 120 | } 121 | 122 | .sizeToFitTest2 { 123 | frame: sizeToFit(100%, 100%).bottom(10).right(20); 124 | } 125 | 126 | .sizeToFitTest3 { 127 | frame: sizeToFit(5, 5); 128 | } 129 | 130 | .centeredRectTest1 { 131 | frame: size(auto, auto).insets(auto, auto, auto, auto); // Centering with auto width/height 132 | } 133 | 134 | .centeredRectTest2 { 135 | frame: size(100, 100).insets(auto, auto, auto, auto); // Centering with fixed width/height 136 | } 137 | 138 | .centeredRectTest3 { 139 | frame: size(50%, 50%).left(auto).right(auto).top(auto).bottom(auto); // Centering with relative width/height 140 | } 141 | 142 | .centeredRectTest4 { 143 | frame: size(50%, 50%).left(auto).right(auto).top(42); // Only horizontal centering 144 | } 145 | 146 | .centeredRectTest5 { 147 | frame: size(50%, 50%).top(auto).bottom(auto).left(42); // Only vertical centering 148 | } 149 | 150 | .centeredRectTest6 { 151 | frame: size(auto, auto).left(auto).right(50).top(auto).bottom(50); // Only single auto inset per axix 152 | } 153 | 154 | .centeredRectTest7 { 155 | frame: size(auto, auto).left(50).right(auto).top(50).bottom(auto); // Only single auto inset per axix 156 | } 157 | 158 | .collectionViewTest { 159 | minimumLineSpacing: 42; 160 | } 161 | 162 | 163 | #layoutElement1 { 164 | layout: size(100, 100), left(parent + 10), top(parent + 10); 165 | } 166 | #layoutElement2 { 167 | layout: size(100, 100), left(layoutElement1), top(layoutElement1); 168 | } 169 | #layoutElement3 { 170 | layout: size(100, 100), left(layoutElement4), top(layoutElement1); 171 | } 172 | #layoutElement4 { 173 | layout: size(100, 100), left(layoutElement3), top(layoutElement1); 174 | } 175 | #layoutElement5 { 176 | layout: left(parent.left + 100), right(parent.right - 100), top(parent.top + 50), bottom(parent.bottom - 50); 177 | } 178 | 179 | 180 | UIView > .typeSelectorAndPrefixedPropertyTest { 181 | UILabel { 182 | font: GillSans 1; 183 | titleLabel.alpha: 1; 184 | } 185 | 186 | UIButton { 187 | titleLabel.font: GillSans 2; 188 | } 189 | 190 | .someOtherSelector, UIButton.testNestedProperty, .anotherSelector { 191 | titleLabel.alpha: 0.5; 192 | } 193 | } 194 | 195 | UIBarButtonItem.prefixedPropertyOnNonUIViewClass { 196 | customView.alpha: 0.5; 197 | } 198 | 199 | UITableViewCell.nestedPropertyNotDirectChildView { 200 | textLabel.enabled: NO; 201 | detailTextLabel.alpha: 0.5; 202 | } 203 | 204 | .textInputTraits { 205 | keyboardType: numberPad; 206 | returnKeyType: done; 207 | } 208 | 209 | UIView .testSpecificity2 { 210 | alpha: 0.75; 211 | } 212 | 213 | #someElementId .testSpecificity1 { 214 | alpha: 0.5; 215 | } 216 | 217 | .testSpecificity1 { 218 | alpha: 0.25; 219 | } 220 | 221 | 222 | .overridePropertyDefinitionStyle { 223 | text: "Monday"; 224 | } 225 | 226 | UILabel.scopeTest { 227 | alpha: 1.0; 228 | } 229 | 230 | 231 | UIViewController UIView { 232 | alpha: 0.1; 233 | } 234 | 235 | UIViewController > UIView { 236 | alpha: 0.25; 237 | } 238 | 239 | UIViewController > #rootView { 240 | alpha: 0.5; 241 | } 242 | 243 | CustomViewController > UIView { 244 | alpha: 0.75; 245 | } 246 | 247 | 248 | .parentSwitcher_childElement { 249 | alpha: 0.5; 250 | } 251 | 252 | .parentSwitcher_parentElement { 253 | .parentSwitcher_childElement { 254 | alpha: 0.75; 255 | } 256 | } 257 | 258 | 259 | #elementIdAndClassTest { 260 | alpha: 0.5; 261 | } 262 | 263 | #elementIdAndClassTest.someClass { 264 | alpha: 0.75; 265 | } 266 | 267 | 268 | .styleInheritance_baseClass { 269 | alpha: 0.5; 270 | } 271 | 272 | .styleInheritance_subClass { 273 | @extend .styleInheritance_baseClass; 274 | contentScaleFactor: 10; 275 | } 276 | -------------------------------------------------------------------------------- /InterfaCSS Tests/TestData/scopedStyles.css: -------------------------------------------------------------------------------- 1 | 2 | UILabel.scopeTest { 3 | alpha: 0.5; 4 | } 5 | -------------------------------------------------------------------------------- /InterfaCSS Tests/TestData/styleSheetPropertyValues.css: -------------------------------------------------------------------------------- 1 | 2 | @attrFont1: HelveticaNeue-Medium 14; 3 | @attrColor1 : lighten(#ffffff, 0%); 4 | @attrFont2: HelveticaNeue-Medium 15; 5 | @attrColor2: rgb(0,0,0); 6 | @numericalConstant: 42; 7 | @mathExpressionConstant: 10 ** (3 - 1); 8 | 9 | @fontNameVariable : "GillSans"; 10 | @fontSizeVariable: 42; 11 | @nestedVariable : @fontNameVariable @fontSizeVariable; 12 | 13 | .simple { 14 | alpha : 0.33; 15 | layer.cornerRadius: 5; 16 | autoresizingMask: width height left right top bottom; 17 | clipsToBounds: YES; 18 | contentMode: bottomRight; 19 | text: "Text's:"; 20 | title: Title; 21 | prompt: 'Prompt'; 22 | searchTextPositionAdjustment: offset(1, 2); 23 | contentSize: size(3, 4); 24 | contentInset: insets(10, 20, 30, 40); 25 | center: point(5, 6); 26 | frame: rect(1,2,3,4); 27 | bounds: size(10,20); 28 | color: rgb(128, 128, 128); 29 | tintColor: #ffffff; 30 | titleColor(selectedHighlighted) : blue; 31 | textColor : rgba(64, 64, 64, 0.5); 32 | shadowColor: red; 33 | transform: rotate(10) scale(20,30) translate(40,50); 34 | attributedText: "text" (font: HelveticaNeue-Medium 12, backgroundColor: rgb(0,0,255), color: darken(#000000, 0%), baselineOffset: 10, strokeColor: yellow, strokeWidth: 1.0); 35 | attributedTitle: "title1 " (font: @attrFont1, foregroundColor: @attrColor1), "title2" (font: @attrFont2, foregroundColor: @attrColor2, underlineStyle: single dash); 36 | } 37 | 38 | .hexColorsRGBA { 39 | color: #4080B000; 40 | titleColor: #00FF80FF; 41 | backgroundColor: #00000080; 42 | tintColor: #80000000; 43 | textColor: #800000FF; 44 | shadowColor: #80000080; 45 | } 46 | 47 | .hexColorsCompact { 48 | color: #000; 49 | titleColor: #fff; 50 | backgroundColor: #0008; 51 | tintColor: #888; 52 | textColor: #8888; 53 | shadowColor: #8880; 54 | } 55 | 56 | .localizedStrings { 57 | text: L("Text"); 58 | title: localized('Title'); 59 | attributedText: L("text1") (font: HelveticaNeue-Medium 12) L("-text2") (font: HelveticaNeue-Medium 12); 60 | } 61 | 62 | .stringsWithEscapes { 63 | text: "dr \"evil\" rules"; 64 | attributedText: "dr \"evil\" rules" (font: HelveticaNeue-Medium 12) ", and so does austin \"danger\" powers" (font: HelveticaNeue-Medium 12); 65 | } 66 | 67 | .prefixes { 68 | cornerRadius: 5; 69 | layer.borderWidth: 10; 70 | imageView.alpha: 0.42; 71 | contentView.alpha: 0.42; 72 | backgroundView.alpha: 0.42; 73 | selectedBackgroundView.alpha: 0.42; 74 | multipleSelectionBackgroundView.alpha: 0.42; 75 | titleLabel.alpha: 0.42; 76 | textLabel.alpha: 0.42; 77 | detailTextLabel.alpha: 0.42; 78 | inputView.alpha: 0.42; 79 | inputAccessoryView.alpha: 0.42; 80 | tableHeaderView.alpha: 0.42; 81 | tableFooterView.alpha: 0.42; 82 | } 83 | 84 | .point1 { 85 | center: parent(50, -50); 86 | } 87 | 88 | .point2 { 89 | center: window(50, -50); 90 | } 91 | 92 | 93 | .rect1 { // Parent insets 94 | frame: parent(10, 10); // dx/dy inset 95 | bounds: parent(10, 20, 30, 40); // top, left, bottom, right inset 96 | } 97 | 98 | .rect2 { // Window insets 99 | frame: window(10, 10); // dx/dy inset 100 | bounds: window(10, 20, 30, 40); // top, left, bottom, right inset 101 | } 102 | 103 | .rect3 { // Parent relative size 104 | frame: size(10%, 20%).left(10).top(20); 105 | bounds: size(30%, 40%).right(30).bottom(40); 106 | } 107 | 108 | .rect4 { // Automatic sizes with parent relative insets/positioning 109 | frame: size(auto, auto).left(10%).top(20%); 110 | bounds: left(50%).right(5).top(0); 111 | } 112 | 113 | .rect5 { // Automatic sizes with parent relative insets/positioning 114 | frame: size(auto, auto).insets(10%, 20%, 30%, 40%); 115 | bounds: size(auto, auto).top(10%).left(20%).bottom(30%).right(40%); 116 | } 117 | 118 | 119 | @font1: HelveticaNeue-Medium 14; 120 | .font1 { 121 | font: @font1; 122 | } 123 | .font2 { 124 | font: bigger(@font1, 1); 125 | } 126 | .font3 { 127 | font: smaller(@font1, 1); 128 | } 129 | .font4 { 130 | font: fontWithSize(@font1, 10); 131 | } 132 | .font5 { 133 | font: HelveticaNeue-Medium 5; 134 | } 135 | .font6 { 136 | font: "Times New Roman" 5; 137 | } 138 | .font7 { 139 | font: 'Times New Roman' 5; 140 | } 141 | .font8 { 142 | font: 42; 143 | } 144 | .font9 { 145 | font: system 42; 146 | } 147 | .font10 { 148 | font: systemItalic 42; 149 | } 150 | .font11 { 151 | font: systemBold 42; 152 | } 153 | 154 | .image1 { 155 | image: image.png; 156 | backgroundImage: "image.png"; 157 | shadowImage: 'image.png'; 158 | progressImage: image(image.png); 159 | trackImage: image("image.png"); 160 | highlightedImage: image('image.png'); 161 | onImage: image(image.png, 1, 2); 162 | offImage: image(image.png, 1, 2, 3, 4); 163 | } 164 | 165 | .colorFunctions { 166 | color: lighten(rgb(17, 34, 51), 50%); 167 | titleColor: darken(#112233, 50%); 168 | textColor: saturate(rgb(17, 34, 51), 50%); 169 | tintColor: desaturate(#112233, 50%); 170 | shadowColor: fadein(rgb(17, 34, 51), 50%); 171 | sectionIndexColor: fadeout(#112233, 50%); 172 | separatorColor: saturate(fadeout(rgb(17, 34, 51), 50%), 50%); 173 | } 174 | 175 | .imageColorFunctions { 176 | image: lighten(#112233, 50%); 177 | backgroundImage: saturate(fadeout(#112233, 50%), 50%); 178 | } 179 | 180 | .fullEnumNames { 181 | autoresizingMask: UIViewAutoresizingFlexibleWidth; 182 | lineBreakMode: NSLineBreakByWordWrapping; 183 | titleColor(UIControlStateSelected): red; 184 | } 185 | 186 | 187 | .numericExpressions { 188 | hidden: 2 > 1; 189 | alpha: 2 * 3 - (2*2.5 + 0.5); 190 | cornerRadius: @numericalConstant + @mathExpressionConstant; 191 | contentSize: size(@numericalConstant, @mathExpressionConstant); 192 | } 193 | 194 | 195 | .layoutParentRelative1 { 196 | layout: size(100, 100), center(parent, parent.centerY - 100); // Using implicit centerX attribute... 197 | } 198 | .layoutParentRelative2 { 199 | layout: size(2 * parent.width, parent.height + 100), left(100), top(100); 200 | } 201 | 202 | .layoutElementRelative1 { 203 | layout: size(100, 100), right(elementFoo), bottom(elementFoo.top - 100); // Using implicit left attribute... 204 | } 205 | .layoutElementRelative2 { 206 | layout: size(elementFoo.width, 2 * elementFoo.height + 100), left(elementFoo.right), top(elementFoo.bottom - 100); 207 | } 208 | 209 | .layoutParentSizeToFit1 { 210 | layout: sizeToFit(100, 100), left(parent.right), top(parent.bottom + 100); 211 | } 212 | .layoutParentSizeToFit2 { 213 | layout: sizeToFit(parent.width * 2, 2 * parent.height + 100), right(3 * parent.left), bottom(guide.bottom); 214 | } 215 | 216 | .layoutImplicitAttributes1 { 217 | layout: size(elementFoo, 2 * elementFoo + 100), center(elementFoo, elementFoo - 100); 218 | } 219 | .layoutImplicitAttributes2 { 220 | layout: size(elementFoo, elementFoo * 2 + 100), topLeft(elementFoo, elementFoo); 221 | } 222 | .layoutImplicitAttributes3 { 223 | layout: size(elementFoo, 2 * elementFoo + 100), topRight(elementFoo, elementFoo); 224 | } 225 | .layoutImplicitAttributes4 { 226 | layout: size(elementFoo, elementFoo * 2 + 100), bottomLeft(elementFoo, elementFoo); 227 | } 228 | .layoutImplicitAttributes5 { 229 | layout: size(elementFoo, 2 * elementFoo + 100), bottomRight(elementFoo, elementFoo); 230 | } 231 | 232 | 233 | .nestedVariableClass { 234 | font: @nestedVariable; 235 | } 236 | -------------------------------------------------------------------------------- /InterfaCSS Tests/TestData/styleSheetStructure.css: -------------------------------------------------------------------------------- 1 | /* Variables: */ 2 | @variable: 0.666; 3 | 4 | // Type selector 5 | uilabel { 6 | alpha: @variable; 7 | } 8 | 9 | // Type+class selector 10 | uilabel.class1 { 11 | alpha: 0.666; 12 | } 13 | 14 | // Type+elementId+class selector 15 | uilabel#identity.class1 { 16 | alpha: 0.666; 17 | } 18 | 19 | uilabel#identity.class1.class2 { 20 | alpha: 0.666; 21 | } 22 | 23 | // elementId+class selector 24 | #identity.class1 { 25 | alpha: 0.666; 26 | } 27 | 28 | // Class selector 29 | .class1 { 30 | alpha: 0.666; 31 | } 32 | 33 | // Multi-class selector 34 | .class1.class2 { 35 | alpha: 0.666; 36 | } 37 | 38 | // Descendant selector chain 39 | uiview .class1 .class2 { 40 | alpha: 0.666; 41 | } 42 | 43 | uiview .class1.class2 { 44 | alpha: 0.666; 45 | } 46 | 47 | // Child/sibling selector chain 48 | uiview > .class1 + .class2 ~ .class3 { 49 | alpha: 0.666; 50 | } 51 | 52 | // Multiple selector (chains) 53 | uilabel, uilabel.class1, .class1, uiview .class1 .class2 { 54 | alpha: 0.666; 55 | } 56 | 57 | uilabel, uilabel.class1.class2, .class1, uiview .class1.class2 .class3 { 58 | alpha: 0.666; 59 | } 60 | 61 | // Nested declarations 62 | uiview { 63 | alpha: 0.666; 64 | .classN1 { 65 | alpha: 0.666; 66 | .classN2 { 67 | alpha: 0.666; 68 | } 69 | } 70 | } 71 | 72 | // Pseudo classes 73 | uiview:onlychild { 74 | alpha: 0.666; 75 | } 76 | 77 | uiview:minOSVersion(8.4) { 78 | alpha: 0.666; 79 | } 80 | 81 | uiview#identifier.class1:onlychild { 82 | alpha: 0.666; 83 | } 84 | 85 | uiview:nthchild(2n+1) { 86 | alpha: 0.666; 87 | } 88 | 89 | uiview uilabel:first-of-type { 90 | alpha: 0.666; 91 | } 92 | 93 | uiview.classx { 94 | alpha: 0.666; 95 | 96 | uilabel:last-of-type { 97 | alpha: 0.666; 98 | } 99 | } 100 | 101 | uiview:pad:landscape { 102 | alpha: 0.666; 103 | } 104 | 105 | uiview:portrait:phone { 106 | alpha: 0.666; 107 | } 108 | 109 | // Wildcard selectors 110 | * uiview { 111 | alpha: 0.666; 112 | } 113 | 114 | * uiview * { 115 | alpha: 0.666; 116 | } 117 | 118 | uiview * { 119 | alpha: 0.666; 120 | } 121 | 122 | uiview * uiview { 123 | alpha: 0.666; 124 | } 125 | -------------------------------------------------------------------------------- /InterfaCSS Tests/TestData/styleSheetWithBadData.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | bad bad bad 4 | 5 | 6 | // Style 1: 7 | .style1 { 8 | alpha: 1; 9 | bad bad bad 10 | } 11 | 12 | 13 | bad bad bad 14 | 15 | 16 | // Style 2: 17 | .style2 { 18 | clipsToBounds: YES; 19 | bad bad bad 20 | } 21 | -------------------------------------------------------------------------------- /InterfaCSS Tests/TestData/viewDefinitionTest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Samples/SimpleSample/SimpleSample/PrototypeExampleViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // PrototypeExampleViewController.h 3 | // Part of InterfaCSS - http://www.github.com/tolo/InterfaCSS 4 | // 5 | // Created by Tobias Löfstrand on 2014-02-09. 6 | // Copyright (c) 2014 Leafnode AB. 7 | // License: MIT (http://www.github.com/tolo/InterfaCSS/LICENSE) 8 | // 9 | 10 | @interface PrototypeExampleViewController : UIViewController 11 | 12 | @property (nonatomic, strong) UITableView* tableView; 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Samples/SimpleSample/SimpleSample/PrototypeExampleViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // PrototypeExampleViewController.m 3 | // Part of InterfaCSS - http://www.github.com/tolo/InterfaCSS 4 | // 5 | // Created by Tobias Löfstrand on 2014-02-09. 6 | // Copyright (c) 2014 Leafnode AB. 7 | // License: MIT (http://www.github.com/tolo/InterfaCSS/LICENSE) 8 | // 9 | 10 | #import "PrototypeExampleViewController.h" 11 | 12 | #import 13 | #import 14 | #import 15 | #import 16 | 17 | 18 | @interface PrototypeExampleCell : UITableViewCell 19 | @property (nonatomic, strong) UILabel* label1; 20 | @property (nonatomic, strong) UILabel* label3; 21 | @end 22 | 23 | @implementation PrototypeExampleCell 24 | @end 25 | 26 | 27 | 28 | @interface PrototypeExampleViewController () 29 | 30 | @property (nonatomic, strong) UILabel* mainTitleLabel; 31 | @property (nonatomic, strong) UIButton* mainTitleBtn; 32 | 33 | @end 34 | 35 | 36 | @implementation PrototypeExampleViewController { 37 | NSArray* items; 38 | } 39 | 40 | - (id)init { 41 | self = [super init]; 42 | if (self) { 43 | self.title = @"Prototype"; 44 | 45 | items = @[ 46 | @[@"ágætis byrjun", @"ágætis byrjun", @"1999"], 47 | @[@"flugufrelsarinn", @"ágætis byrjun", @"1999"], 48 | @[@"olsen olsen", @"ágætis byrjun", @"1999"], 49 | @[@"starálfur", @"ágætis byrjun", @"1999"], 50 | @[@"svefn-g-englar", @"ágætis byrjun", @"1999"], 51 | @[@"popplagið", @"()", @"2002"], 52 | @[@"samskeyti", @"()", @"2002"], 53 | @[@"vaka", @"()", @"2002"], 54 | @[@"glósóli", @"takk", @"2005"], 55 | @[@"hoppípolla", @"takk", @"2005"], 56 | @[@"ára bátur", @"með suð í eyrum við spilum endalaust", @"2008"], 57 | @[@"fljótavík", @"með suð í eyrum við spilum endalaust", @"2008"], 58 | @[@"ekki múkk", @"Valtari", @"2012"], 59 | @[@"varúð", @"Valtari", @"2012"], 60 | @[@"hrafntinna", @"Kveikur", @"2013"], 61 | @[@"ísjaki", @"Kveikur", @"2013"], 62 | ]; 63 | } 64 | return self; 65 | } 66 | 67 | - (void) loadView { 68 | // To prevent a lot of up front loading when application starts, loading of a stylesheet can be postponed until it's actually needed. 69 | // Additionally, a scope can be attached to the stylesheet, to limit styles to only be processed while in a particular view controller for instance 70 | ISSStyleSheetScope* scope = [ISSStyleSheetScope scopeWithViewControllerClass:self.class]; 71 | [[InterfaCSS interfaCSS] loadStyleSheetFromMainBundleFile:@"prototypeExample.css" withScope:scope]; 72 | 73 | // Load the complete view hierarchy for this view controller from the view definition file 'views.xml' 74 | self.view = [ISSViewBuilder loadViewHierarchyFromMainBundleFile:@"views.xml" fileOwner:self]; 75 | 76 | [self.mainTitleBtn setTitle:@"Sample button" forState:UIControlStateNormal]; 77 | } 78 | 79 | - (NSUInteger) supportedInterfaceOrientations { 80 | return UIInterfaceOrientationMaskAll; 81 | } 82 | 83 | 84 | #pragma mark - Table View 85 | 86 | 87 | - (NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { 88 | return items.count; 89 | } 90 | 91 | - (UITableViewCell*) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 92 | PrototypeExampleCell* cell = [tableView dequeueReusablePrototypeCellWithIdentifierISS:@"prototypeExampleCell" forIndexPath:indexPath]; 93 | 94 | NSArray* item = items[indexPath.row]; 95 | 96 | cell.label1.text = item[0]; 97 | 98 | // Testing the use of an element Id for this label 99 | UILabel* label2 = [cell subviewWithElementId:@"label2"]; 100 | label2.text = item[1]; 101 | 102 | cell.label3.text = item[2]; 103 | 104 | return cell; 105 | } 106 | 107 | - (void) tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath { 108 | [cell applyStylingISS]; 109 | } 110 | 111 | - (void) tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { 112 | UITableViewCell* cell = [tableView cellForRowAtIndexPath:indexPath]; 113 | [cell.selectedBackgroundView applyStylingWithAnimationISS]; 114 | } 115 | 116 | @end 117 | -------------------------------------------------------------------------------- /Samples/SimpleSample/SimpleSample/SimpleSample-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | com.leafnode.se.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | UIInterfaceOrientationPortraitUpsideDown 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /Samples/SimpleSample/SimpleSample/SimpleSample-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_3_0 10 | #warning "This project uses features only available in iOS SDK 3.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #endif 17 | 18 | #import 19 | -------------------------------------------------------------------------------- /Samples/SimpleSample/SimpleSample/SimpleSampleViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleSampleViewController.h 3 | // Part of InterfaCSS - http://www.github.com/tolo/InterfaCSS 4 | // 5 | // Created by Tobias Löfstrand on 2012-02-24. 6 | // Copyright (c) 2012 Leafnode AB. 7 | // License: MIT (http://www.github.com/tolo/InterfaCSS/LICENSE) 8 | // 9 | 10 | @interface SimpleSampleViewController : UIViewController 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /Samples/SimpleSample/SimpleSample/SimpleSampleViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // SimpleSampleViewController.m 3 | // Part of InterfaCSS - http://www.github.com/tolo/InterfaCSS 4 | // 5 | // Created by Tobias Löfstrand on 2012-02-24. 6 | // Copyright (c) 2012 Leafnode AB. 7 | // License: MIT (http://www.github.com/tolo/InterfaCSS/LICENSE) 8 | // 9 | 10 | #import "SimpleSampleViewController.h" 11 | 12 | // Define this to enable using ISSViewBuilder shorthand macros: 13 | //#define ISS_VIEW_BUILDER_SHORTHAND_ENABLED 14 | 15 | #import 16 | #import 17 | 18 | 19 | @interface SimpleSampleViewController () 20 | 21 | @property (nonatomic, strong) UILabel* mainTitleLabel; 22 | @property (nonatomic, strong) UIButton* mainTitleButton; 23 | 24 | @property (nonatomic, strong) UILabel* contentTitleLabel; 25 | @property (nonatomic, strong) UILabel* contentSubtitleLabel; 26 | 27 | @property (nonatomic, strong) UIView* simpleSampleContentView; 28 | @property (nonatomic, strong) UIButton* mainButtonTop; 29 | @property (nonatomic, strong) UIButton* mainButton; 30 | 31 | @end 32 | 33 | 34 | 35 | @implementation SimpleSampleViewController 36 | 37 | 38 | #pragma mark - Lifecycle 39 | 40 | - (id)init { 41 | self = [super init]; 42 | if (self) { 43 | self.title = @"Simple"; 44 | } 45 | return self; 46 | } 47 | 48 | - (void) loadView { 49 | // Construct the view hierachy for this view controller using ISSViewBuilder 50 | self.view = [ISSViewBuilder rootViewWithStyle:@"simpleSampleMainView" andSubViews:^{ 51 | return @[ 52 | self.mainTitleLabel = [ISSViewBuilder labelWithStyle:@"mainTitleLabel"], 53 | self.mainTitleButton = [ISSViewBuilder buttonWithStyle:@"mainTitleButton"], 54 | self.simpleSampleContentView = [ISSViewBuilder viewWithStyle:@"simpleSampleContentView" andSubViews:^{ return @[ 55 | self.contentTitleLabel = [ISSViewBuilder labelWithStyle:@"simpleSampleContentTitleLabel"], 56 | self.contentSubtitleLabel = [ISSViewBuilder labelWithStyle:@"simpleSampleContentSubtitleLabel"], 57 | // You can also add and setup an already existing view object using the view builder: 58 | [ISSViewBuilder setupView:[[UIView alloc] init] withStyleClass:@"simpleSampleButtonContainer" andSubViews:^{ 59 | return @[ 60 | self.mainButtonTop = [ISSViewBuilder buttonWithStyle:@"simpleSampleMainButton1"], 61 | self.mainButton = [ISSViewBuilder buttonWithStyle:@"simpleSampleMainButton2"], 62 | [ISSViewBuilder buttonWithStyle:@"simpleSampleMainButton3"]]; 63 | }] ]; 64 | }] ]; 65 | }]; 66 | 67 | [self.mainButton addTarget:self action:@selector(touchedButton:event:) forControlEvents:UIControlEventAllTouchEvents]; 68 | 69 | // NOTE: Uncomment below to disable styling of cornerRadius (just to test what disabling a property feels like) 70 | //[self.mainButton disableStylingForPropertyISS:@"cornerRadius"]; 71 | 72 | [self.mainTitleButton setTitle:@"Sample button" forState:UIControlStateNormal]; 73 | 74 | self.contentTitleLabel.text = @"Content Main"; 75 | self.contentSubtitleLabel.text = @"Content Sub"; 76 | 77 | // Setup notification blocks to get notified when styles are applied to mainButton 78 | self.mainButton.willApplyStylingBlockISS = ^(NSArray* styles) { 79 | // Use this block to for instance override which style properties are allowed to be set at the moment. 80 | //NSLog(@"Will apply styles to mainButton - %lu properties", (unsigned long)styles.count); 81 | return styles; 82 | }; 83 | self.mainButton.didApplyStylingBlockISS = ^(NSArray* styles) { 84 | // In this block it's possible to for instance update any derived styling properties, or override values set during styling. 85 | //NSLog(@"Did apply styles to mainButton - %lu properties", (unsigned long)styles.count); 86 | }; 87 | 88 | // Apply styling only once as startup to mainButtonTop, then disable automatic re-styling, to make it possible do adjust styling manually in code. 89 | [self.mainButtonTop applyStylingOnceISS]; 90 | 91 | // Add custom style to tab bar item 92 | [[InterfaCSS sharedInstance] addStyleClass:@"tab1" forUIElement:self.tabBarItem]; 93 | } 94 | 95 | - (NSUInteger) supportedInterfaceOrientations { 96 | return UIInterfaceOrientationMaskAll; 97 | } 98 | 99 | - (void) viewDidAppear:(BOOL)animated { 100 | [super viewDidAppear:animated]; 101 | 102 | // Debug log matching styles for self.mainTitleLabel: 103 | #if DEBUG == 1 104 | [[InterfaCSS interfaCSS] logMatchingStyleDeclarationsForUIElement:self.mainTitleLabel]; 105 | #endif 106 | 107 | [self performSelector:@selector(animateSimpleSampleContentView) withObject:nil afterDelay:.0f]; 108 | } 109 | 110 | - (void) viewWillDisappear:(BOOL)animated { 111 | [super viewWillDisappear:animated]; 112 | 113 | [self.simpleSampleContentView removeStyleClassISS:@"simpleSampleContentViewAtRest" scheduleStyling:NO]; 114 | } 115 | 116 | - (void) animateSimpleSampleContentView { 117 | [UIView animateWithDuration:1.0f delay:.0f usingSpringWithDamping:0.25 initialSpringVelocity:0 options:UIViewAnimationOptionBeginFromCurrentState animations:^{ 118 | [self.simpleSampleContentView addStyleClassISS:@"simpleSampleContentViewAtRest" scheduleStyling:NO]; 119 | [self.simpleSampleContentView applyStylingISS]; 120 | } completion:nil]; 121 | } 122 | 123 | 124 | #if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 125 | 126 | - (void) didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { 127 | [super didRotateFromInterfaceOrientation:fromInterfaceOrientation]; 128 | 129 | // Debug log matching styles for self.mainTitleLabel: 130 | [[InterfaCSS interfaCSS] logMatchingStyleDeclarationsForUIElement:self.mainTitleLabel]; 131 | } 132 | 133 | #else 134 | 135 | - (void) viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator { 136 | [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; 137 | 138 | // Debug log matching styles for self.mainTitleLabel: 139 | [self iss_logDebug:@"Matching declarations before rotation:"]; 140 | [[InterfaCSS interfaCSS] logMatchingStyleDeclarationsForUIElement:self.mainTitleLabel]; 141 | [coordinator animateAlongsideTransition:nil completion:^(id context) { 142 | [self iss_logDebug:@"Matching declarations after rotation:"]; 143 | [[InterfaCSS interfaCSS] logMatchingStyleDeclarationsForUIElement:self.mainTitleLabel]; 144 | }]; 145 | } 146 | 147 | #endif 148 | 149 | 150 | #pragma mark - Actions 151 | 152 | - (void) touchedButton:(id)btn event:(UIEvent*)event { 153 | UITouch* touch = [event.allTouches anyObject]; 154 | if( touch.phase == UITouchPhaseBegan ) { 155 | NSString* title; 156 | if( [self.mainButtonTop.currentTitle hasPrefix:@"T"] ) title = [self.mainButtonTop.currentTitle lowercaseString]; 157 | else title = [self.mainButtonTop.currentTitle uppercaseString]; 158 | [self.mainButtonTop setTitle:title forState:UIControlStateNormal]; 159 | 160 | [self.mainButton addStyleClassISS:@"touched" animated:YES]; 161 | } else if( touch.phase == UITouchPhaseEnded || touch.phase == UITouchPhaseCancelled ) { 162 | [self.mainButton removeStyleClassISS:@"touched" animated:YES]; 163 | } 164 | } 165 | 166 | 167 | @end 168 | -------------------------------------------------------------------------------- /Samples/SimpleSample/SimpleSample/constants.css: -------------------------------------------------------------------------------- 1 | 2 | /* Constants: */ 3 | 4 | @stdHeadingLabel: AvenirNextCondensed-DemiBold 20; 5 | @stdTitleLabel: Avenir-Black 15; 6 | @stdTitleColor: #5f5f5f; 7 | @stdSubTitleLabel: Avenir-Light 14; 8 | @stdButtonFont: HelveticaNeue-Light 14; 9 | 10 | @stdColor1: rgb(16, 109, 255); 11 | -------------------------------------------------------------------------------- /Samples/SimpleSample/SimpleSample/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /Samples/SimpleSample/SimpleSample/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tolo/InterfaCSS/1b6b18a15239d7b9382d895252ebd9f4cda1aa5a/Samples/SimpleSample/SimpleSample/image.png -------------------------------------------------------------------------------- /Samples/SimpleSample/SimpleSample/main.css: -------------------------------------------------------------------------------- 1 | 2 | 3 | /* "Reset" default styles */ 4 | 5 | UIButton { 6 | backgroundImage: #e0e0e0; // Color as background image 7 | backgroundImage(highlighted): #7f7f7f; 8 | borderColor: #7f7f7f; 9 | borderWidth: 0.5; 10 | cornerRadius: 6; 11 | clipsToBounds: YES; 12 | titleColor: #303030; 13 | titleColor(highlighted): white; 14 | font: @stdButtonFont; 15 | } 16 | 17 | 18 | 19 | /* Common stuff */ 20 | 21 | .tabBarStyle1 UITabBarItem { 22 | font: Avenir-Light 20; 23 | textColor: lightGray; 24 | textColor(selected): #b300fd; 25 | titlePositionAdjustment: offset(0, -10); 26 | } 27 | 28 | UITabBarItem.tab1 { 29 | font: Avenir-Heavy 20; 30 | } 31 | 32 | #mainTitleLabel, .mainTitleLabel { 33 | frame: sizeToFit(160, 50).left(15).top(30); 34 | textColor: rgb(255, 255, 255); 35 | font: @stdHeadingLabel; 36 | alpha: 1; 37 | backgroundColor: fadeout(lightGray, 75%); 38 | cornerRadius: 5; 39 | clipsToBounds: YES; 40 | attributedText: "Simple" (foregroundColor: #e1881e), " Sample " (foregroundColor: #3f3f3f), "Main" (foregroundColor: #ab45ec); 41 | } 42 | 43 | #mainTitleLabel:landscape, .mainTitleLabel:landscape { // Landscape orientation 44 | alpha: 0.5; 45 | textAlignment: center; 46 | } 47 | 48 | 49 | 50 | /* SimpleSampleViewController */ 51 | 52 | 53 | .simpleSampleMainView { // Root view of SimpleSampleViewController 54 | autoresizingMask: width height; 55 | backgroundColor: gradient(darken(magenta, 50%), #e4e1e6); 56 | } 57 | 58 | .simpleSampleMainView .mainTitleLabel { 59 | shadowColor: fadeout(black, 50%); 60 | shadowOffset: size(1,1); 61 | } 62 | 63 | .mainTitleButton { 64 | frame: rect(15, 60, 120, 30); 65 | } 66 | 67 | 68 | // Content view and labels: 69 | 70 | .simpleSampleContentView { 71 | bounds: size(200, 230); 72 | center: parent(0, 0); 73 | backgroundColor: desaturate(fadeout(@stdColor1, 50%), 30%); 74 | layer.cornerRadius: 10; 75 | clipsToBounds: YES; 76 | anchorPoint: point(0, 0); 77 | transform: rotate(-25); 78 | } 79 | 80 | .simpleSampleContentViewAtRest { 81 | transform: identity; 82 | } 83 | 84 | .simpleSampleContentTitleLabel { 85 | frame: sizeToFit(140, 30).left(auto).right(auto).top(10); // Size to fit and center horizontally 86 | textColor: rgb(255, 255, 255); 87 | font: smaller(@stdTitleLabel, 2); 88 | } 89 | 90 | .simpleSampleContentSubtitleLabel { 91 | frame: rect(20, 40, 160, 20); 92 | textColor: rgb(228, 228, 228); 93 | font: smaller(@stdSubTitleLabel, 3); 94 | } 95 | 96 | 97 | // Content buttons: 98 | 99 | .simpleSampleButtonContainer { 100 | frame: rect(10, 80, 180, 140); 101 | backgroundColor: #88cc44; 102 | } 103 | 104 | .simpleSampleButtonContainer UIButton { 105 | backgroundImage: fadeout(white, 33%); 106 | } 107 | 108 | .simpleSampleMainButton1 { 109 | frame: size(160, 30).top(10).left(10); 110 | title: Top Button; 111 | font: AvenirNextCondensed-UltraLight 22; 112 | } 113 | 114 | .simpleSampleMainButton2 { 115 | bounds: size(160, 30); 116 | center: parent(0, 0); 117 | titleColor(highlighted): #b300fd; 118 | backgroundImage(highlighted): #d0d0d0; 119 | title: MainButton; 120 | transform: identity; 121 | } 122 | 123 | .simpleSampleMainButton3 { 124 | frame: size(160, 30).top(100).left(10); 125 | title: Bottom Button; 126 | font: HelveticaNeue-CondensedBold 14; 127 | } 128 | 129 | uibutton.touched { 130 | transform: rotate(180); 131 | } 132 | -------------------------------------------------------------------------------- /Samples/SimpleSample/SimpleSample/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // Part of InterfaCSS - http://www.github.com/tolo/InterfaCSS 4 | // 5 | // Created by Tobias Löfstrand on 2012-02-24. 6 | // Copyright (c) 2012 Leafnode AB. 7 | // License: MIT (http://www.github.com/tolo/InterfaCSS/LICENSE) 8 | // 9 | 10 | #import 11 | 12 | #import "AppDelegate.h" 13 | 14 | int main(int argc, char * argv[]) 15 | { 16 | @autoreleasepool { 17 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Samples/SimpleSample/SimpleSample/prototypeExample.css: -------------------------------------------------------------------------------- 1 | 2 | /* PrototypeExampleViewController */ 3 | 4 | .prototypeExampleMainView { 5 | autoresizingMask: width height; 6 | backgroundColor: #f0f0f0; 7 | 8 | #mainTitleLabel { 9 | textColor: #b300fd; 10 | } 11 | 12 | .mainTitleButton { 13 | frame: rect(15, 60, 120, 30); 14 | backgroundImage(highlighted): #f0f0f0; 15 | titleColor(highlighted): #b300fd; 16 | } 17 | 18 | .mainTitleButton:landscape { 19 | frame: rect(200, 30, 120, 30); 20 | } 21 | 22 | .prototypeExampleTable { 23 | frame: parent(100, 10, 10, 10); 24 | clipsToBounds: YES; 25 | cornerRadius: 6; 26 | borderColor: darkGray; 27 | borderWidth: 1; 28 | 29 | .cellBackgroundView { 30 | frame: parent; 31 | backgroundColor: #fcfcfc; 32 | } 33 | 34 | .cellBackgroundViewSelected { 35 | frame: parent; 36 | backgroundColor: fadeout(desaturate(#b300fd, 80%), 50%); 37 | } 38 | 39 | .prototypeExampleCellLabel1, .prototypeExampleCellLabel2, .prototypeExampleCellLabel3 { 40 | textColor: #4f4f4f; 41 | } 42 | 43 | .prototypeExampleCellLabel1 { 44 | frame: rect(5, 2, 120, 21); 45 | font: @stdTitleLabel; 46 | textColor: @stdTitleColor; 47 | } 48 | 49 | .prototypeExampleCellLabel2 { 50 | frame: rect(5, 21, 120, 21); 51 | font: @stdSubTitleLabel; 52 | } 53 | 54 | .prototypeExampleCellLabel3 { 55 | frame: size(auto, auto).left(50%).right(3%); 56 | font: HelveticaNeue-UltraLight 36; 57 | adjustsFontSizeToFitWidth: YES; 58 | minimumScaleFactor: 0.5; 59 | textAlignment: right; 60 | } 61 | 62 | 63 | /* Examples on how to use pseudo classes to apply conditional styling based on row numer in UITableView: */ 64 | 65 | .prototypeExampleCell:nthOfType(even) .prototypeExampleCellLabel3 { 66 | textColor: darken(green, 25%); 67 | } 68 | 69 | .prototypeExampleCell:nthOfType(odd) .prototypeExampleCellLabel3 { 70 | textColor: darken(blue, 25%); 71 | } 72 | 73 | .prototypeExampleCell:firstOfType UILabel { 74 | textColor: darken(red, 15%); 75 | } 76 | 77 | .prototypeExampleCell:lastOfType UILabel { 78 | textColor: orange; 79 | } 80 | } 81 | } 82 | 83 | // Landscape orientation adjustment for tableview: 84 | .prototypeExampleTable:landscape { 85 | frame: parent(80, 10, 10, 10); 86 | } 87 | -------------------------------------------------------------------------------- /Samples/SimpleSample/SimpleSample/views.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |