Skip to content

Commit c4c1ed0

Browse files
committed
Added support for background-image with UIImageView
1 parent d5538e2 commit c4c1ed0

7 files changed

Lines changed: 111 additions & 0 deletions

File tree

Classes/ViewStyling/GAViewStyling.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,20 @@
5252

5353
#pragma mark -
5454

55+
@interface UIImage (GAViewStyling)
56+
57+
/**
58+
* Create an image from the main resource bundle or a data URL. For example:
59+
* url(<bundle_resource.jpg>)
60+
* url(data:image/jpg;base64,<BASE_64_DATA>)
61+
*
62+
*/
63+
+ (UIImage *)imageWithCSSURL:(NSString *)cssUrl;
64+
65+
@end
66+
67+
#pragma mark -
68+
5569
/**
5670
* Returns a size from a CSS declaration that contains two lengths (i.e. "320px 240px").
5771
* The first length is width (x), the second is height (y). If the string does not have at least two lengths,

Classes/ViewStyling/GAViewStyling.m

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,42 @@ + (UIFont *)fontWithCSSDeclaration:(id)cssDeclaration
149149

150150
@end
151151

152+
#pragma mark -
153+
154+
@implementation UIImage (GAViewStyling)
155+
156+
+ (UIImage *)imageWithCSSURL:(NSString *)cssUrl
157+
{
158+
// Make a NSURL by using everything inside the "url(...)" string
159+
//
160+
NSRange urlRange = NSMakeRange(4, [cssUrl length] - 5);
161+
NSURL* theUrl = [NSURL URLWithString:[cssUrl substringWithRange:urlRange]];
162+
163+
if ([[theUrl scheme] isEqualToString:NSURLFileScheme])
164+
{
165+
GADebugStr(@"Loading image named '%@'", [theUrl lastPathComponent]);
166+
167+
return [UIImage imageNamed:[theUrl lastPathComponent]];
168+
}
169+
else if ([[theUrl scheme] isEqualToString:@"data"])
170+
{
171+
NSError* myErr = nil;
172+
NSData* imgData = [NSData dataWithContentsOfURL:theUrl options:0 error:&myErr];
173+
174+
if (myErr != nil)
175+
{
176+
NSLog(@"Could not make NSData from data URL: %@", myErr);
177+
return nil;
178+
}
179+
180+
return [UIImage imageWithData:imgData];
181+
}
182+
183+
NSAssert(YES, @"Unsupported URL scheme for UIImage (GAViewStyling): %@", [theUrl scheme]);
184+
return nil;
185+
}
186+
187+
@end
152188
/**
153189
* The input string will be something like "NNNpx NNNpx [other chars]"
154190
*/

Classes/ViewStyling/UIView+GAViewStyling.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,14 @@
6363

6464
@end
6565

66+
#pragma mark - Image styling
67+
68+
@interface UIImageView (GAViewStyling)
69+
70+
- (void)applyComputedStyles:(id)cssDeclaration;
71+
72+
@end
73+
6674
#pragma mark - Text styling
6775

6876
@interface UILabel (GAViewStyling)

Classes/ViewStyling/UIView+GAViewStyling.m

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,37 @@ - (void)applyComputedStyles:(id)cssDeclaration
161161

162162
#pragma mark -
163163

164+
@implementation UIImageView (GAViewStyling)
165+
166+
- (void)applyComputedStyles:(id)cssDeclaration
167+
{
168+
[super applyComputedStyles:cssDeclaration];
169+
170+
NSString* backgroundImage = [cssDeclaration valueForKey:@"background-image"];
171+
172+
if ([backgroundImage isEqualToString:@"none"] || ![backgroundImage hasPrefix:@"url("])
173+
return;
174+
175+
self.image = [UIImage imageWithCSSURL:backgroundImage];
176+
177+
// Default for background images is to put them in the top left (background-position: 0% 0%)
178+
//
179+
NSString* backgroundPos = [cssDeclaration valueForKey:@"background-position"];
180+
181+
if ([backgroundPos isEqualToString:@"0% 0%"])
182+
self.contentMode = UIViewContentModeTopLeft;
183+
else if ([backgroundPos isEqualToString:@"50% 50%"])
184+
self.contentMode = UIViewContentModeCenter;
185+
else if ([backgroundPos isEqualToString:@"50% 100%"])
186+
self.contentMode = UIViewContentModeBottom;
187+
188+
// Note that we ignore background-repeat in this UIImageView category since it doesn't support that.
189+
}
190+
191+
@end
192+
193+
#pragma mark -
194+
164195
@implementation UILabel (GAViewStyling)
165196

166197
- (NSString *)styleSelector

GAJavaScript.xcodeproj/project.pbxproj

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
2DC139A613B3AC5E0026D4D5 /* GHUnitIOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2DC139A513B3AC5D0026D4D5 /* GHUnitIOS.framework */; };
3030
2DC139F013B3CF4A0026D4D5 /* UIView+GAViewStyling.h in Headers */ = {isa = PBXBuildFile; fileRef = 2DC139EE13B3CF4A0026D4D5 /* UIView+GAViewStyling.h */; settings = {ATTRIBUTES = (Public, ); }; };
3131
2DC139F113B3CF4A0026D4D5 /* UIView+GAViewStyling.m in Sources */ = {isa = PBXBuildFile; fileRef = 2DC139EF13B3CF4A0026D4D5 /* UIView+GAViewStyling.m */; };
32+
2DF837B414351B6C00281875 /* logo.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 2DF837B314351B6B00281875 /* logo.jpg */; };
3233
493383BB12B433F000FBE23C /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 493383BA12B433F000FBE23C /* main.m */; };
3334
4933848612B4373600FBE23C /* TScriptObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 4933848512B4373600FBE23C /* TScriptObject.m */; };
3435
4933848C12B437CD00FBE23C /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4933848B12B437CD00FBE23C /* CoreGraphics.framework */; };
@@ -99,6 +100,7 @@
99100
2DC139A513B3AC5D0026D4D5 /* GHUnitIOS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GHUnitIOS.framework; path = ../../ThirdParty/GHUnitIOS.framework; sourceTree = "<group>"; };
100101
2DC139EE13B3CF4A0026D4D5 /* UIView+GAViewStyling.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIView+GAViewStyling.h"; path = "Classes/ViewStyling/UIView+GAViewStyling.h"; sourceTree = "<group>"; };
101102
2DC139EF13B3CF4A0026D4D5 /* UIView+GAViewStyling.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIView+GAViewStyling.m"; path = "Classes/ViewStyling/UIView+GAViewStyling.m"; sourceTree = "<group>"; };
103+
2DF837B314351B6B00281875 /* logo.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = logo.jpg; path = Tests/logo.jpg; sourceTree = "<group>"; };
102104
4933839E12B4338200FBE23C /* GAJavaScriptTests.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = GAJavaScriptTests.app; sourceTree = BUILT_PRODUCTS_DIR; };
103105
493383A012B4338200FBE23C /* GAJavaScriptTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "GAJavaScriptTests-Info.plist"; sourceTree = "<group>"; };
104106
493383BA12B433F000FBE23C /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = Tests/main.m; sourceTree = "<group>"; };
@@ -213,6 +215,7 @@
213215
children = (
214216
2DBE365D13BDFCA700E9AA11 /* TViewStyling.h */,
215217
2DBE365E13BDFCA700E9AA11 /* TViewStyling.m */,
218+
2DF837B314351B6B00281875 /* logo.jpg */,
216219
);
217220
name = ViewStyling;
218221
sourceTree = "<group>";
@@ -353,6 +356,7 @@
353356
files = (
354357
49F51D8412B6C64700F91142 /* ga-js-runtime.js in Resources */,
355358
2D8500B213816B2100758EA2 /* TestWebViewContent.html in Resources */,
359+
2DF837B414351B6C00281875 /* logo.jpg in Resources */,
356360
);
357361
runOnlyForDeploymentPostprocessing = 0;
358362
};

Tests/TViewStyling.m

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,24 @@ - (void)testGradientToFromSyntax
188188
GHAssertTrue(pColors[0] == 0.f && pColors[1] == 0.5f, @"Bad colors");
189189
}
190190

191+
- (void)testImageFromCSSURL
192+
{
193+
NSString* testUrl = @"url(file://blah/blah/logo.jpg)";
194+
UIImage* testImage = [UIImage imageWithCSSURL:testUrl];
195+
196+
GHAssertNotNil(testImage, @"Could not load image from bundle");
197+
198+
testUrl = @"urrl(foo)";
199+
testImage = [UIImage imageWithCSSURL:testUrl];
200+
201+
GHAssertNil(testImage, @"Should not have an image now.");
202+
203+
testUrl = @"url(data:image/gif;base64,R0lGODlhEAAOALMAAOazToeHh0tLS/7LZv/0jvb29t/f3//Ub//ge8WSLf/rhf/3kdbW1mxsbP//mf///yH5BAAAAAAALAAAAAAQAA4AAARe8L1Ekyky67QZ1hLnjM5UUde0ECwLJoExKcppV0aCcGCmTIHEIUEqjgaORCMxIC6e0CcguWw6aFjsVMkkIr7g77ZKPJjPZqIyd7sJAgVGoEGv2xsBxqNgYPj/gAwXEQA7)";
204+
testImage = [UIImage imageWithCSSURL:testUrl];
205+
206+
GHAssertNotNil(testImage, @"Could not load image from data URL");
207+
}
208+
191209
@end
192210

193211
#pragma mark -

Tests/logo.jpg

15.5 KB
Loading

0 commit comments

Comments
 (0)