内存警告删除 UINavigationBar 按钮

发布于 2024-09-16 00:11:35 字数 1616 浏览 6 评论 0原文

我已经覆盖了类别中 UINavigationBar 上的 drawLayer:inContext: ,以便我可以将自定义图像放在那里。我讨厌这样,但我的客户很坚定。

结果,我不得不求助于一些相当丑陋的黑客才能把事情搞定。我必须在该类别中放置一个新方法,以便在导航栏标题上放置一个标题,并且我必须在 -viewDidAppear 中显式调用它。

我可以忍受这一点。真正的问题是,当内存不足时,UINavigationBar 似乎正在卸载其子视图,包括我的后退按钮!我真的不知道如何从中恢复。

这是我的 UINavigationBar 类别。我想,我从这里得到了这段代码;核心显卡大多只是让我头晕。

@implementation UINavigationBar (background)

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
{
    if([self isMemberOfClass: [UINavigationBar class]]){
        UIImage *image = [UIImage imageNamed:@"top_bar.png"];
        //CGContextClip(ctx);
        CGContextTranslateCTM(ctx, 0, image.size.height - 20);
        CGContextScaleCTM(ctx, 1.0, -1.0);
        CGContextDrawImage(ctx, CGRectMake(0, 2, self.frame.size.width, self.frame.size.height), image.CGImage);
    }
}

-(void)customTitle:(NSString *)text
{
    UINavigationItem *top = self.topItem;
    [[top.titleView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];

    UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 40)];
    title.textAlignment = UITextAlignmentCenter;
    title.text = text;
    title.textColor = [UIColor blackColor];
    title.font = [UIFont boldSystemFontOfSize:16];
    title.backgroundColor = [UIColor clearColor];
    top.titleView = title;
    [title release];

}

有没有更简单的方法?如果没有,我怎样才能告诉 UINavigationBar,“用你应该拥有的子视图重新加载自己”?

更新:尝试重写 -drawRect 。代码更简单,但问题仍然存在——在某些情况下后退按钮消失。顺便说一句,我假设这与收到内存不足警告有关。它似乎只发生在通过 UIImagePicker 旅行回来后,所以也许那里发生了一些事情来改变事情。另外,我确实启用了 NSZombies,显然关闭它会显着改变内存肤色。

I've overridden drawLayer:inContext: on UINavigationBar in a category so that I can put a custom image up there. I hate it, but my client was adamant.

As a result, I've had to fall back to some pretty ugly hacks to get things up there. I had to put a new method in that category to put a title on the nav bar header, and I have to call it explicitly in -viewDidAppear.

I can live with that. The real problem is, when memory gets low, it appears that UINavigationBar is unloading its subviews, including my back button! I don't really know how to recover from that.

Here's my UINavigationBar category. I got this code from here on SO, I think; Core Graphics mostly just makes my head spin.

@implementation UINavigationBar (background)

- (void)drawLayer:(CALayer *)layer inContext:(CGContextRef)ctx
{
    if([self isMemberOfClass: [UINavigationBar class]]){
        UIImage *image = [UIImage imageNamed:@"top_bar.png"];
        //CGContextClip(ctx);
        CGContextTranslateCTM(ctx, 0, image.size.height - 20);
        CGContextScaleCTM(ctx, 1.0, -1.0);
        CGContextDrawImage(ctx, CGRectMake(0, 2, self.frame.size.width, self.frame.size.height), image.CGImage);
    }
}

-(void)customTitle:(NSString *)text
{
    UINavigationItem *top = self.topItem;
    [[top.titleView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];

    UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 200, 40)];
    title.textAlignment = UITextAlignmentCenter;
    title.text = text;
    title.textColor = [UIColor blackColor];
    title.font = [UIFont boldSystemFontOfSize:16];
    title.backgroundColor = [UIColor clearColor];
    top.titleView = title;
    [title release];

}

Is there a simpler way? If not, how can I tell UINavigationBar, "Reload yourself with the subviews you're supposed to have"?

UPDATE: Tried overriding -drawRect instead. The code is simpler but the problem remains--in certain cases the back button vanishes. By the way, I'm assuming it's related to having received a low-mem warning. It only seems to happen after coming back from a trip through UIImagePicker, so maybe something happens in there to change things. Also I did have NSZombies enabled, and obviously turning that off changes the memory complexion significantly.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

野侃 2024-09-23 00:11:35

为什么不重写 UINavigationBar 类别中的drawRect,而不是重写drawLayer:inContext:?

据我所知,这是一个非常干净的黑客,并且不需要为您的标题提供自定义 UILabel。

更新:您有关内存警告的信息更有意义。您是否设置了自定义后退按钮?当控制器收到内存警告时,如果它不在屏幕上,它就会放弃它的视图。您的导航控制器很有可能发生这种情况。如果您在 init 方法中设置自定义后退按钮,则在内存警告清除后将无法将其重新添加到导航项中。

Why not override drawRect in your UINavigationBar category, rather than drawLayer:inContext:?

As far as I can remember, it's a pretty clean hack, and there is no need to provide a custom UILabel for your title.

Update: Your information about a memory warning makes more sense. Are you setting a custom back button? When a controller receives a memory warning, it ditches it's view if it's not on screen. There is a very good chance that this it happening with your navigation controller. If you are setting a custom back button in say, an init method, there will be no way for it to be re-added to the navigation item post memory warning purge.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文