UIBarButtonItem上没有阴影/浮雕

Chr*_*ris 6 cocoa-touch uiimage uibarbuttonitem ios

我有一个自定义UIBarButtonItem的问题.当我通过创建自定义UIBarButtonItem时

 [[UIBarButtonItem alloc]initWithImage:[UIImage imageNamed:@"FilterIcon.png"] style:UIBarButtonItemStyleBordered target:self action:@selector(filterTouched:)];
Run Code Online (Sandbox Code Playgroud)

生成的按钮没有"浮雕"外观,系统项目通过在其图标后面放置一个半透明的黑色阴影来实现.

左:系统项,右:自定义项

在左侧,您可以看到"组织"系统栏按钮项,右键是上面代码的结果.

在资源中创建阴影是徒劳的,因为iOS/Cocoa只使用图像的掩码并丢弃任何颜色信息.

有趣的是,如果我在Interface-Builder中创建条形按钮项,它看起来很好.但是,在我的问题的上下文中,我需要在代码中创建按钮项.

Ale*_*lex 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;
}
Run Code Online (Sandbox Code Playgroud)


Jam*_*rey 7

我认为这种情况发生的原因是由另一个问题的答案所涵盖的:

/sf/answers/243349711/

/sf/answers/457002241/

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;
}
Run Code Online (Sandbox Code Playgroud)

所以,UIBarButtonItem过去看起来像这样:

之前

使用上面的函数创建,如下所示:

UIBarButtonItem barButtonItem = new UIBarButtonItem(ApplyToolbarButtonStyling(UIImage.FromFile("MusicIcon.png")), UIBarButtonItemStyle.Plain, delegate {});
Run Code Online (Sandbox Code Playgroud)

现在看起来像这样:

后

希望这可以帮助将来的某个人.