Making UIToolbar and UINavigationBar’s background totally transparent
来源:互联网 发布:刘亦菲票房毒药知乎 编辑:程序博客网 时间:2024/05/16 23:42
源自:http://atastypixel.com/blog/making-uitoolbar-and-uinavigationbars-background-totally-transparent/
I have an upcoming iPhone application, Cartographer, that is highly stylised and requires high customisation of the interface to achieve a convincing, beautiful vintage look. To make it work, I needed transparent toolbars and navigation bars for my UIViewController-based views.
The solution I came up with for this was to implement a category on UINavigationBar and UIToolbar, and overriding drawRect:
with a method that does absolutely nothing. Then I can place my own textures behind the bar, and they’ll be seen, instead of the default bar background.
@interface UINavigationBar (TransparentAdditions)
@end
@implementation UINavigationBar (TransparentAdditions)
- (void)drawRect:(CGRect)rect {
// Do nothing!
}
@end
For UIToolBar, if you’re using it within a UINavigationController, you’ll want to also overridedrawLayer:inContext:
, as this appears to be used instead of drawRect:
when used within a navigation controller, for some weird reason.
Note that this method will affect all bars in your app. If you only want some bars to be transparent, you’ll need to do a little objc-hocus-pocus. Thanks to Mike Ash for this solution on method replacement (read that article for the whys and hows). This technique replaces the default methods as before, but keeps track of the defaults. If you now set the tintColor
of the bar to [UIColor clearColor]
, the bar will have a transparent background. Otherwise, it’ll just look the same as usual.
For UIToolbar (same principle for UINavigationBar):
#import <objc/runtime.h> // Keep track of default implementation
static void (*_origDrawRect)(id, SEL, CGRect);
static void (*_origDrawLayerInContext)(id, SEL, CALayer*, CGContextRef);
// Override for drawRect:
static void OverrideDrawRect(UIToolbar *self, SEL _cmd, CGRect r) {
if ( [[self tintColor] isEqual:[UIColor clearColor]] ) {
// Do nothing
} else {
// Call default method
_origDrawRect(self, _cmd, r);
}
}
// Override for drawLayer:inContext:
static void OverrideDrawLayerInContext(UIToolbar *self, SEL _cmd, CALayer *layer, CGContextRef context) {
if ( [[self tintColor] isEqual:[UIColor clearColor]] ) {
// Do nothing
} else {
// Call default method
_origDrawLayerInContext(self, _cmd, layer, context);
}
}
@implementation UIToolbar (TransparentAdditions)
+ (void)load {
// Replace methods, keeping originals
Method origMethod = class_getInstanceMethod(self, @selector(drawRect:));
_origDrawRect = (void *)method_getImplementation(origMethod);
if(!class_addMethod(self, @selector(drawRect:), (IMP)OverrideDrawRect, method_getTypeEncoding(origMethod)))
method_setImplementation(origMethod, (IMP)OverrideDrawRect);
origMethod = class_getInstanceMethod(self, @selector(drawLayer:inContext:));
_origDrawLayerInContext = (void *)method_getImplementation(origMethod);
if(!class_addMethod(self, @selector(drawLayer:inContext:), (IMP)OverrideDrawLayerInContext, method_getTypeEncoding(origMethod))
method_setImplementation(origMethod, (IMP)OverrideDrawLayerInContext);
}
@end
You can now add background texture to the bars in a number of ways. These are two I’ve used:
- By adding a CALayer to
[bar layer]
— but note that UINavigationBar will try to add elements at index 0, underneath your background. To make this work, I provided a subclassed CALayer (and overrode UINavigationBar’s+layer
method) which only letsyou insert layers at index 0, via a custom method, and overrideinsertLayer:atIndex:
method, setting index to 1 if it’s 0. UIToolbar doesn’t require this. - Or, by adding a CALayer to your view layer. Note that the view’s bounds do not cover the UINavigationBar; I had to offset the layer by the height of the bar in question (
navigationBarLayer.frame = CGRectMake(0, -self.navigationController.navigationBar.frame.size.height, [barImage size].width, [barImage size].height);
, for example), and setself.view.clipsToBounds = NO
to allow the layer to be seen.
Of course, you can also draw the texture in drawRect:
, instead. It’s entirely up to you. The advantage in using a CALayer
is that it can overlap the view boundary, for effects like drop shadows.
- Making UIToolbar and UINavigationBar’s background totally transparent
- Transparent UIToolBar
- Transparent UIToolBar
- Set terminal text color and transparent background
- background:transparent
- How can you decide to use UINavigationBar, UIToolbar and UITabbar
- UIToolbar UINavigationController UINavigationBar UIBarButtonItem
- UIToolbar UINavigationController UINavigationBar UIBarButtonItem
- UIToolbar与UINavigationBar笔记
- UIToolbar UINavigationController UINavigationBar UIBarButtonItem
- Do it before making it totally clear
- set transparent button image and background color to button
- UIToolBar,UINavigationBar 修改背景色
- UIToolBar,UINavigationBar 修改背景色
- UINavigationController--导航控制器(UINavigationBar、UIToolBar)
- background-color:transparent
- css 属性 background:transparent;
- background-color:transparent
- 金融工程程序搜索
- FreePascal拉杂勒死与WINCE5 动态数组
- 2011-06-25 编译记录
- magento 关于paypal支付后台设定以及错误的处理
- Visual Basic 速学系统 V6.2.425
- Making UIToolbar and UINavigationBar’s background totally transparent
- Delegate类简介
- SQL Server 2008 下 18456错误的解决办法
- VMware Server启动后没见localhost选项的解决方法
- PHP插件功能实现思路漫谈
- GPU Bayer Conversion
- Linux 常见特殊符号
- libcurl
- Java-IO输入与输出 知识点