我尝试使用自定义形状创建自定义UINavigationBar(忽略透明度)
正如您所看到的,这个UINavigationBar有一个自定义形状,我试图复制它。
环顾四周,我发现了this response,它解释了我遵循的第一步。
1)我创建了一个名为CustomNavigationBar的UINavigationBar的子类。 2)我像这样覆盖sizeThatFits方法:
- (CGSize) sizeThatFits:(CGSize)size
{
return CGSizeMake(320.0, 70.0);
}
3)这就是我失去的地方......
在前面的回答中说UIBezierPath可用于创建自定义形状(即使是曲线),然后应用为蒙版。我试过这个覆盖drawRect,但我得到的是一个很大的黑色导航条(我的条形颜色设置为红色)。
编辑:我的抽签错了,这是正确的
- (void)drawRect:(CGRect)rect
{
UIBezierPath *path = [[UIBezierPath alloc] init];
[path moveToPoint:CGPointZero];
[path addLineToPoint:CGPointMake(320.0, 0.0)];
[path addLineToPoint:CGPointMake(320.0, 50.0)];
[path addQuadCurveToPoint:CGPointMake(0.0, 50.0) controlPoint:CGPointMake(160.0, 90.0)];
[path closePath];
[[UIColor redColor] setFill];
[path fill];
}
编辑:如下所述,我的代码有一些错误,现在它吸引了一些东西。
如您所见,UIBezierPath正确定义了形状,但是存在一些新问题:
1)状态栏是完全黑色的,没有任何东西在那里呈现,即使我将颜色改为光,它也不会显示任何内容。我错过了什么?
2)由于sizeThatFits方法,还剩下一些黑色部分。有没有办法让这部分透明?
感谢所有人!
编辑2 :好吧,我完全改变了对这个问题的看法,我认为我已经接近解决方案了。现在我尝试使用透明的png文件作为背景,但仍然需要增加它的高度,所以现在这是我的代码。
- (CGSize) sizeThatFits:(CGSize)size
{
return [[UIImage imageNamed:@"Layer3"] size];
}
- (void)drawRect:(CGRect)rect
{
[self setClipsToBounds:NO];
UIImage *image = [UIImage imageNamed:@"Layer3"];
[image drawInRect:rect];
}
更简单,对吧?显然" Layer3"是我的透明png图像的名称。但现在,这就是我所得到的。
如您所见,状态栏未包含在png图像中。
我现在缺少什么?
谢谢!
答案 0 :(得分:5)
嗯,我很傻xD
最后我得到了一个解决这个问题的方法,它比我想象的要简单得多。
以下是步骤:
1)子类UINavigationBar,我创建了一个CustomNavigationBar对象。
2)在它的init中,写下这行
UIImage *image = [UIImage imageNamed:@"barBackgroundImageName"];
[self setBackgroundImage:image forBarPosition:UIBarPositionTopAttached barMetrics:UIBarMetricsDefault];
[self setShadowImage:[UIImage new]];
这很重要,也是我无法完成所有这些工作的原因,图片的高度必须为64px 。我在online Apple Documentation上找到了它,它描述了UINavigationBar和状态栏之间的行为。
3)就是这样。这是我的结果(我知道背景不对称,只是一个测试)。
感谢您的所有时间和帮助!!!
答案 1 :(得分:0)
如果是我,我会拿起gimp并制作一个具有所需形状的矩形背景,使用alpha通道来实现透明度。它可能更容易:)
编辑:也许你不应该放弃你的想法;)检查这个https://developer.apple.com/library/ios/documentation/2ddrawing/conceptual/drawingprintingios/BezierPaths/BezierPaths.html,你会发现你的代码可能仍然不完整。还有一些小事:
您将曲线绘制到180,100点。请注意,这不是酒吧的中心,如果您不希望它不规则,您应该放160,100。此外,你应该从这里开始照顾那些" 320"如果它在iPad上运行怎么办?如果它的景观怎么样?如果iOS 8出现并且尺寸不再是320怎么办? ;)
从高处开始注意这些" 90"据我所知,导航栏通常高44像素(64个状态栏计数)。很可能高度以某种方式被修剪到64而且你没有看到曲线,所以我会考虑使用一个小数字,直到你有效。
编辑2:关于你的最后一个问题......这是一个疯狂的猜测,但你是否尝试在建立bezier路径之前调用[super drawRect:rect]
方法?超类可能已经为状态栏/透明度实现了绘制机制,您只需要调用它。从来没有在过去做过,所以我不知道它是否会起作用,但它值得一试;)
编辑3:关于状态栏问题,您是否尝试过实施此协议? https://developer.apple.com/library/ios/documentation/uikit/reference/UIBarPositioning_Protocol/Reference/Reference.html#//apple_ref/c/econst/UIBarPositionTop这是另一个疯狂的猜测,因为我以前没有做过,但看起来UINavigationBar实现了UIBarPositioning协议,你可以在其中实现barPosition
方法,强制它返回{{ 1}}值,这样导航栏将显示在状态栏下方。如果是这样,那么可能唯一剩下的步骤是使其高出20个像素,并为所有视图添加20px垂直偏移。值得一试,我想! ;)