No Shadow/Emboss on UIBarButtonItem

Mam problem z niestandardowym UIBarButtonItem. Kiedy tworzę Niestandardowy UIBarButtonItem poprzez

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

Otrzymany przycisk nie ma" wytłoczonego " wyglądu, który elementy systemu uzyskują poprzez umieszczenie półprzezroczystego czarnego cienia za ikonami.

Po lewej: element systemowy, po prawej: element niestandardowy

Po lewej stronie znajduje się przycisk" organizuj " Pasek systemowy, po prawej wynik kodu z góry.

Tworzenie cienia w zasobie jest daremne, ponieważ iOS / Cocoa używał tylko maski obraz i odrzuca wszelkie informacje o kolorze.

Co ciekawe, jeśli stworzę element przycisku paska w Interface-Builderze, wygląda to dobrze. Jednak w kontekście mojego problemu, muszę utworzyć element przycisku w kodzie.

Author: Chris, 2012-06-18

3 answers

Istnieje Objective-C wersja skryptu Jamesa Furey ' a.

- (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;
}
 10
Author: Alex-alex,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-08-08 13:21:51

Myślę, że powód to się dzieje jest objęty tymi odpowiedziami na inne pytanie:

Https://stackoverflow.com/a/3476424/1210490

Https://stackoverflow.com/a/6528603/1210490

Uibarbuttonitemy zachowują się różnie w zależności od tego, gdzie są programowo dołączane. Jeśli dołączysz je do paska narzędzi, staną się białymi "wytłoczonymi" ikonami. Jeśli dołączysz je do paska nawigacyjnego, nie będą.

Spędziłem ostatnie kilka godzin. pisanie funkcji do zastosowania stylizacji paska narzędziowego UIBarButtonItem do UIImages. jest napisany w C# Dla MonoTouch , Ale jestem pewien, że będziesz w stanie dostosować go do Obj-C no problemo...
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;
}

Więc, UIBarButtonItem, który kiedyś wyglądał tak:

Przed

Utworzony za pomocą powyższej funkcji, Tak:

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

Teraz wyglądałoby tak:

Po

Mam nadzieję, że to pomoże komuś w przyszłości.
 7
Author: James Furey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:01:18

Zwróć uwagę na przesunięcie cienia w scenariuszu Jamesa Furey ' a. Zrobiłem następujące doświadczenie:

float shadowOffset = 1.0f // for a UIBarButtonItem in UINavigationItem
float shadowOffset = 0.0f // for a UIBarButtonItem in UIToolBar

Zaobserwowano to w iOS 6.1 SDK.

(obecnie przestarzałe pod iOS 7)

 0
Author: AppsolutEinfach,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-02-18 12:51:22