我遇到了自定义UIBarButtonItem的问题。当我通过
创建自定义UIBarButtonItem时 [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"FilterIcon.png"] style:UIBarButtonItemStyleBordered target:self action:@selector(filterTouched:)];
生成的按钮没有“浮雕”外观,系统项目通过在其图标后面放置一个半透明的黑色阴影来实现。
在左侧,您会看到“整理”系统栏按钮项,右侧是上面代码的结果。
在资源中创建阴影是徒劳的,因为iOS / Cocoa只使用图像的掩码并丢弃任何颜色信息。
有趣的是,如果我在Interface-Builder中创建了条形按钮项,它看起来很好。但是,在我的问题的上下文中,我需要在代码中创建按钮项。
答案 0 :(得分:10)
James Furey的剧本有Objective-C版本。
- (UIImage *)applyToolbarButtonStyling:(UIImage *)oldImage {
float shadowOffset = 1;
float shadowOpacity = .54;
CGRect imageRect = CGRectMake(0, 0, oldImage.size.width, oldImage.size.height);
CGRect shadowRect = CGRectMake(0, shadowOffset, oldImage.size.width, oldImage.size.height);
CGRect newRect = CGRectUnion(imageRect, shadowRect);
UIGraphicsBeginImageContextWithOptions(newRect.size, NO, oldImage.scale);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextScaleCTM(ctx, 1, -1);
CGContextTranslateCTM(ctx, 0, -(newRect.size.height));
CGContextSaveGState(ctx);
CGContextClipToMask(ctx, shadowRect, oldImage.CGImage);
CGContextSetFillColorWithColor(ctx, [UIColor colorWithWhite:0 alpha:shadowOpacity].CGColor);
CGContextFillRect(ctx, shadowRect);
CGContextRestoreGState(ctx);
CGContextClipToMask(ctx, imageRect, oldImage.CGImage);
CGContextSetFillColorWithColor(ctx, [UIColor colorWithWhite:1 alpha:1].CGColor);
CGContextFillRect(ctx, imageRect);
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}
答案 1 :(得分:7)
我认为原因发生这种情况会被另一个问题的答案所覆盖:
https://stackoverflow.com/a/3476424/1210490
https://stackoverflow.com/a/6528603/1210490
UIBarButtonItems的行为有所不同,具体取决于您以编程方式附加它们的位置。如果将它们附加到工具栏,它们将变为白色“浮雕”图标。如果将它们附加到导航栏,它们就不会。
我花了最后几个小时编写一个函数来将工具栏UIBarButtonItem样式应用于UIImages。 它是用C#编写的MonoTouch ,但我相信你能够把它调到Obj-C没问题......
UIImage ApplyToolbarButtonStyling(UIImage oldImage)
{
float shadowOffset = 1f;
float shadowOpacity = .54f;
RectangleF imageRect = new RectangleF(PointF.Empty, oldImage.Size);
RectangleF shadowRect = new RectangleF(new PointF(0, shadowOffset), oldImage.Size);
RectangleF newRect = RectangleF.Union(imageRect, shadowRect);
UIGraphics.BeginImageContextWithOptions(newRect.Size, false, oldImage.CurrentScale);
CGContext ctxt = UIGraphics.GetCurrentContext();
ctxt.ScaleCTM(1f, -1f);
ctxt.TranslateCTM(0, -newRect.Size.Height);
ctxt.SaveState();
ctxt.ClipToMask(shadowRect, oldImage.CGImage);
ctxt.SetFillColor(UIColor.FromWhiteAlpha(0f, shadowOpacity).CGColor);
ctxt.FillRect(shadowRect);
ctxt.RestoreState();
ctxt.ClipToMask(imageRect, oldImage.CGImage);
ctxt.SetFillColor(UIColor.FromWhiteAlpha(1f, 1f).CGColor);
ctxt.FillRect(imageRect);
UIImage newImage = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return newImage;
}
所以,UIBarButtonItem过去看起来像这样:
使用上面的函数创建,如下所示:
UIBarButtonItem barButtonItem = new UIBarButtonItem(ApplyToolbarButtonStyling(UIImage.FromFile("MusicIcon.png")), UIBarButtonItemStyle.Plain, delegate {});
现在看起来像这样:
希望这有助于将来。
答案 2 :(得分:0)
记下James Furey剧本中的阴影偏移。 我已经取得了以下经验:
float shadowOffset = 1.0f // for a UIBarButtonItem in UINavigationItem
float shadowOffset = 0.0f // for a UIBarButtonItem in UIToolBar
在iOS 6.1 SDK中观察到这一点。
(现在在iOS 7下已经过时)