【问题标题】:iOS7 UINavigationBar subclass > try to draw under UIStatusBariOS7 UINavigationBar 子类 > 尝试在 UIStatusBar 下绘制
【发布时间】:2013-09-24 20:19:34
【问题描述】:

我尝试在 iOS7 上通过 drawRect 绘制自定义 UINavigationBar。随着导航栏和状态栏的变化,我的抽奖开始于 y-origin 20.0,而不是状态栏后面的 0.0。我检查了 wwdc 视频,但我只找到了没有自定义绘图的图像示例。有任何想法吗?我需要在我的子类中设置一些参数吗?

  1. 基于“Master-Detail Application”新建项目
  2. 为 UINavigationBar 创建一个子类
  3. 将 Main.storyboard 中的 UINavigationBar 更改为自定义类
  4. 关闭半透明[self setTranslucent:NO];
  5. 在 UINavigationBar 的 sublass 中添加一个真正简单的 drawRect

我做了一个简单的测试:

CGColorSpaceRef colorSpace  = CGColorSpaceCreateDeviceRGB();
UIBezierPath* maskPath = [UIBezierPath bezierPathWithRect: CGRectMake(0, 0, 320, 64)];

[maskPath closePath];
[[UIColor greenColor] setFill];
[maskPath fill];

CGColorSpaceRelease(colorSpace); 

绿色的NavigationBar从Statusbar下方开始,如何从Statusbar后面开始绘制?

当前解决方案:

@Redwarp 发布了一个方法,我也做了一个简单的版本来测试:

CustomBGView *testView = [[CustomBGView alloc] initWithFrame:CGRectMake(0, 0, 320, 64)];

RetinaAwareUIGraphicsBeginImageContext(testView.frame.size);

CGContextRef context = UIGraphicsGetCurrentContext();
[testView.layer renderInContext:context];

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

[self setBackgroundImage:image forBarPosition:UIBarPositionTop barMetrics:UIBarMetricsDefault];

在自定义 UIView 中,您可以随心所欲地进行绘制,并且您的自定义视图也会出现在 StatusBar 的后面。

【问题讨论】:

  • 您找到解决方案了吗?我不明白为什么你的问题被否决了。我也有同样的问题。
  • 我也对否决票感到困惑......无论如何,我现在还没有找到解决方案@Redwarp。我希望/希望/打赌您可以设置一个属性,并且您将能够在状态栏后面使用 drawRect 绘制自定义导航栏样式。但也许我错过了另一种方式?

标签: uinavigationbar ios7 drawrect uistatusbar


【解决方案1】:

我找到了一个解决方案,这有点奇怪:我将 UINavigationBar 子类化,并在 onLayoutSubviews 中创建我想要创建的背景,并将其设置为背景图像。所以我做了等效的drawRect,但是在我设置为背景的UIImage中。 然后,在 xib 或故事板中,我选择我的子类作为导航栏的类型。

这里是:

@implementation MyNavigationBar

- (void)layoutSubviews {
    [super layoutSubviews];

    CGPoint origin = [self.superview convertPoint:self.frame.origin toView:nil];
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(self.bounds.size.width, self.bounds.size.height + origin.y), NO, 0.0);
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextClipToRect(context, CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height + origin.y));
    [self.baseImage drawInRect:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)];
    UIImage *backgroundImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    [self setBackgroundImage:backgroundImage forBarMetrics:UIBarMetricsDefault];
    // If you don't want the bar shadow, set the shadow image as null
    [self setShadowImage:[UIImage new]];
}

而且当你不想改变图片时,你调用[navigationBar needsLayout],它会再次调用layoutSubviews

编辑:诀窍是获取导航栏的来源。如果有状态栏,则原点为 y 20。如果没有状态栏,则原点为 0。因此,将 origin.y 添加到绘图中的图像的高度,您将获得一个不错的结果。

【讨论】:

  • 我希望我能投票支持你的帖子。我会等到下周才会接受你的解决方案。也许有人有第二种方法!?
  • 好的!我的意思是“我对 UINavigation 栏进行子类化”,而不是“我对子视图进行子类化”
猜你喜欢
  • 1970-01-01
  • 2013-09-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多