内存警告删除 UINavigationBar 按钮
我已经覆盖了类别中 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
为什么不重写 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.