Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TIMOB-11876] Support for custom shadow image of nav bar #4750

Merged
merged 7 commits into from
Oct 7, 2013
21 changes: 21 additions & 0 deletions apidoc/Titanium/UI/Window.yml
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,10 @@ properties:

- name: barImage
summary: Background image for the nav bar, specified as a URL to a local image.
description: |
The behavior of this API on iOS has changed from version 3.2.0. Previous versions
of the SDK created a custom image view and inserted it as a child of the navigation bar.
The titanium sdk now uses the native call to set the background image of the navigation bar.
platforms: [iphone, ipad, mobileweb, tizen]
type: String

Expand Down Expand Up @@ -336,6 +340,15 @@ properties:
type: Boolean
default: false

- name: hideShadow
summary: Set this to true to hide the shadow image of the navigation bar.
description: |
This property is only honored if a valid value is specified for the [barImage](Titanium.UI.Window.barImage) property.
platforms: [iphone, ipad]
type: Boolean
default: false
since: 3.2.0

- name: left
summary: Window's left position, in platform-specific units.
description: |
Expand Down Expand Up @@ -553,6 +566,14 @@ properties:
platforms: [iphone, ipad, mobileweb, tizen]
type: Titanium.UI.View

- name: shadowImage
summary: Shadow image for the navigation bar, specified as a URL to a local image..
description: |
This property is only honored if a valid value is specified for the [barImage](Titanium.UI.Window.barImage) property.
platforms: [iphone, ipad]
type: String
since: 3.2.0

- name: statusBarStyle
summary: The status bar style associated with this window.
description: |
Expand Down
2 changes: 1 addition & 1 deletion apidoc/Titanium/UI/iOS/NavigationWindow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ excludes:
properties: [navBarHidden, tabBarHidden, navTintColor, translucent, toolbar,
barColor, barImage, leftNavButton, rightNavButton, title, titleControl,
titlePrompt, titleImage, titleid, titlepromptid, url, backButtonTitle,
backButtonTitleImage]
backButtonTitleImage, shadowImage, hideShadow]

properties:
- name: window
Expand Down
94 changes: 51 additions & 43 deletions iphone/Classes/TiUIWindowProxy.m
Original file line number Diff line number Diff line change
Expand Up @@ -272,14 +272,6 @@ -(BOOL)_handleClose:(id)args
-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
[super willAnimateRotationToInterfaceOrientation:toInterfaceOrientation duration:duration];
//Update the barImage here as well. Might have the wrong bounds but that will be corrected
//in the call from frameSizeChanged in TiUIWindow. Avoids the visual glitch
if ( (shouldUpdateNavBar) && (controller != nil) && ([controller navigationController] != nil) ) {
id barImageValue = [self valueForKey:@"barImage"];
if ((barImageValue != nil) && (barImageValue != [NSNull null])) {
[self updateBarImage];
}
}
[self willChangeSize];
}

Expand Down Expand Up @@ -379,39 +371,65 @@ -(void)setBarColor:(id)colorString
}
}



-(void)updateBarImage
{
UINavigationBar * ourNB = [[controller navigationController] navigationBar];
CGRect barFrame = [ourNB bounds];
UIImage * newImage = [TiUtils toImage:[self valueForUndefinedKey:@"barImage"]
proxy:self size:barFrame.size];

if (newImage == nil) {
[barImageView removeFromSuperview];
RELEASE_TO_NIL(barImageView);
if (controller == nil || [controller navigationController] == nil || !shouldUpdateNavBar) {
return;
}
if (barImageView == nil) {
barImageView = [[UIImageView alloc]initWithImage:newImage];

id barImageValue = [self valueForUndefinedKey:@"barImage"];

UINavigationBar* ourNB = [[controller navigationController] navigationBar];
UIImage* theImage = [TiUtils toImage:barImageValue proxy:self];

if (theImage == nil) {
[ourNB setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault];
} else {
[barImageView setImage:newImage];
}
[barImageView setFrame:barFrame];
int barImageViewIndex = 0;
if ([ourNB respondsToSelector:@selector(setBackgroundImage:forBarMetrics:)]) {
//We should ideally be using the setBackgroundImage:forBarMetrics:
//method. Revisit after 1.8.1 release
barImageViewIndex = 1;
}
if ([[ourNB subviews] indexOfObject:barImageView] != barImageViewIndex) {
[ourNB insertSubview:barImageView atIndex:barImageViewIndex];
UIImage* resizableImage = [theImage resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0) resizingMode:UIImageResizingModeStretch];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resizableImageWithCapInsets:resizingMode: is available only as from iOS6
Should fall back to resizableImageWithCapInsets:for iOS5

[ourNB setBackgroundImage:resizableImage forBarMetrics:UIBarMetricsDefault];
//You can only set up the shadow image with a custom background image.
id shadowImageValue = [self valueForUndefinedKey:@"shadowImage"];
theImage = [TiUtils toImage:shadowImageValue proxy:self];

if (theImage != nil) {
UIImage* resizableImage = [theImage resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0) resizingMode:UIImageResizingModeStretch];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

resizableImageWithCapInsets:resizingMode: is available only as from iOS6, as is
setShadowImage:. So this should be skipped for iOS5.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@philet as of 3.1.3 Titanium SDK only supports iOS SDK 6.0 and above, so these changes are fine.

ourNB.shadowImage = resizableImage;
} else {
BOOL clipValue = [TiUtils boolValue:[self valueForUndefinedKey:@"hideShadow"] def:NO];
if (clipValue) {
//Set an empty Image.
ourNB.shadowImage = [[[UIImage alloc] init] autorelease];
} else {
ourNB.shadowImage = nil;
}
}
}

}

-(void)setBarImage:(id)value
{
[self replaceValue:[self sanitizeURL:value] forKey:@"barImage" notification:NO];
[self replaceValue:value forKey:@"barImage" notification:NO];
if (controller!=nil)
{
TiThreadPerformOnMainThread(^{[self updateBarImage];}, NO);
}
}

-(void)setShadowImage:(id)value
{
[self replaceValue:value forKey:@"shadowImage" notification:NO];
if (controller!=nil)
{
TiThreadPerformOnMainThread(^{[self updateBarImage];}, NO);
}
}

-(void)setHideShadow:(id)value
{
[self replaceValue:value forKey:@"hideShadow" notification:NO];
if (controller!=nil)
{
TiThreadPerformOnMainThread(^{[self updateBarImage];}, NO);
Expand Down Expand Up @@ -458,8 +476,7 @@ -(void)setRightNavButton:(id)proxy withObject:(id)properties
// add the new one
BOOL animated = [TiUtils boolValue:@"animated" properties:properties def:NO];
[controller.navigationItem setRightBarButtonItem:[proxy barButtonItem] animated:animated];
[self updateBarImage];
}
}
else
{
controller.navigationItem.rightBarButtonItem = nil;
Expand Down Expand Up @@ -506,8 +523,7 @@ -(void)setLeftNavButton:(id)proxy withObject:(id)properties
// add the new one
BOOL animated = [TiUtils boolValue:@"animated" properties:properties def:NO];
[controller.navigationItem setLeftBarButtonItem:[proxy barButtonItem] animated:animated];
[self updateBarImage];
}
}
else
{
controller.navigationItem.leftBarButtonItem = nil;
Expand Down Expand Up @@ -583,7 +599,6 @@ -(void)refreshBackButton
}
[[prevController navigationItem] setBackBarButtonItem:backButton];
[backButton release];
[self updateBarImage];
}

-(void)setBackButtonTitle:(id)proxy
Expand Down Expand Up @@ -619,10 +634,6 @@ -(void)updateNavBar
if ([[self valueForKey:@"titleControl"] isKindOfClass:[TiViewProxy class]]) {
[self updateTitleView];
}
id barImageValue = [self valueForKey:@"barImage"];
if ((barImageValue != nil) && (barImageValue != [NSNull null])) {
[self updateBarImage];
}
}, NO);
}

Expand Down Expand Up @@ -664,8 +675,6 @@ -(void)updateTitleView
//layout the titleControl children
[titleControl layoutChildren:NO];

[self updateBarImage];

return;
}
[oldProxy removeBarButtonView];
Expand All @@ -689,7 +698,6 @@ -(void)updateTitleView
if (oldView != newTitleView) {
[ourNavItem setTitleView:newTitleView];
}
[self updateBarImage];
}


Expand Down Expand Up @@ -862,7 +870,7 @@ -(void)setupWindowDecorations
SETPROPOBJ(@"leftNavButton",setLeftNavButton);
SETPROPOBJ(@"rightNavButton",setRightNavButton);
SETPROPOBJ(@"toolbar",setToolbar);
SETPROP(@"barImage",setBarImage);
[self updateBarImage];
[self refreshBackButton];

id navBarHidden = [self valueForKey:@"navBarHidden"];
Expand Down