在 iOS 7 下运行我的 iOS 6 应用程序时,为啥我的视图上没有正确显示阴影?
Posted
技术标签:
【中文标题】在 iOS 7 下运行我的 iOS 6 应用程序时,为啥我的视图上没有正确显示阴影?【英文标题】:Why are shadows not appearing correctly on my views when running my iOS 6 app under iOS 7?在 iOS 7 下运行我的 iOS 6 应用程序时,为什么我的视图上没有正确显示阴影? 【发布时间】:2013-10-22 15:18:52 【问题描述】:我有一个尚未更新到 ios 7 的 iOS 6 应用程序。我的阴影出现了一些奇怪的颜色问题,这些问题只出现在 iOS 7 上。有时它们看起来正常,有时它们是彩色的。
正常(50% 的时间阴影在 iOS 7 上正常显示):
彩色(50% 的时间它们以这种方式出现。它们应该像上面一样是黑色的。似乎在移入和移出视图时发生):
有人有什么想法吗?这是我已经使用了两年多的代码。有一个更好的方法吗?这里是否有更新的 API 调用不正确?
ShadowedTableView.h
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
@interface ShadowedTableView : UITableView
CAGradientLayer *originShadow;
CAGradientLayer *topShadow;
CAGradientLayer *bottomShadow;
@end
ShadowedTableView.m
#import "ShadowedTableView.h"
#define SHADOW_HEIGHT 20.0
#define SHADOW_INVERSE_HEIGHT 10.0
#define SHADOW_RATIO (SHADOW_INVERSE_HEIGHT / SHADOW_HEIGHT)
@implementation ShadowedTableView
//
// shadowAsInverse:
//
// Create a shadow layer
//
// Parameters:
// inverse - if YES then shadow fades upwards, otherwise shadow fades downwards
//
// returns the constructed shadow layer
//
- (CAGradientLayer *)shadowAsInverse:(BOOL)inverse
CAGradientLayer *newShadow = [[CAGradientLayer alloc] init];
CGRect newShadowFrame =
CGRectMake(0, 0, self.frame.size.width,
inverse ? SHADOW_INVERSE_HEIGHT : SHADOW_HEIGHT);
newShadow.frame = newShadowFrame;
newShadow.colors =
@[(__bridge id)(inverse ?
([self.backgroundColor colorWithAlphaComponent:0.0].CGColor) :
([UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:inverse ? (SHADOW_INVERSE_HEIGHT / SHADOW_HEIGHT) * 0.5 : 0.5].CGColor)),
(__bridge id)(inverse ?
([UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:inverse ? (SHADOW_INVERSE_HEIGHT / SHADOW_HEIGHT) * 0.5 : 0.5].CGColor) :
([self.backgroundColor colorWithAlphaComponent:0.0].CGColor))];
return newShadow;
//
// layoutSubviews
//
// Override to layout the shadows when cells are laid out.
//
- (void)layoutSubviews
[super layoutSubviews];
//
// Construct the origin shadow if needed
//
if (!originShadow)
originShadow = [self shadowAsInverse:NO];
[self.layer insertSublayer:originShadow atIndex:0];
else if (![(self.layer.sublayers)[0] isEqual:originShadow])
[self.layer insertSublayer:originShadow atIndex:0];
[CATransaction begin];
[CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions];
//
// Stretch and place the origin shadow
//
CGRect originShadowFrame = originShadow.frame;
originShadowFrame.size.width = self.frame.size.width;
originShadowFrame.origin.y = self.contentOffset.y;
originShadow.frame = originShadowFrame;
[CATransaction commit];
if (self.style == UITableViewStylePlain)
NSArray *indexPathsForVisibleRows = [self indexPathsForVisibleRows];
if ([indexPathsForVisibleRows count] == 0)
[topShadow removeFromSuperlayer];
topShadow = nil;
[bottomShadow removeFromSuperlayer];
bottomShadow = nil;
return;
NSIndexPath *firstRow = indexPathsForVisibleRows[0];
if ([firstRow section] == 0 && [firstRow row] == 0)
UIView *cell = [self cellForRowAtIndexPath:firstRow];
if (!topShadow)
topShadow = [self shadowAsInverse:YES];
[cell.layer insertSublayer:topShadow atIndex:0];
else if ([cell.layer.sublayers indexOfObjectIdenticalTo:topShadow] != 0)
[cell.layer insertSublayer:topShadow atIndex:0];
CGRect shadowFrame = topShadow.frame;
shadowFrame.size.width = cell.frame.size.width;
shadowFrame.origin.y = -SHADOW_INVERSE_HEIGHT;
topShadow.frame = shadowFrame;
else
[topShadow removeFromSuperlayer];
topShadow = nil;
NSIndexPath *lastRow = [indexPathsForVisibleRows lastObject];
if ([lastRow section] == [self numberOfSections] - 1 &&
[lastRow row] == [self numberOfRowsInSection:[lastRow section]] - 1)
UIView *cell =
[self cellForRowAtIndexPath:lastRow];
if (!bottomShadow)
bottomShadow = [self shadowAsInverse:NO];
[cell.layer insertSublayer:bottomShadow atIndex:0];
else if ([cell.layer.sublayers indexOfObjectIdenticalTo:bottomShadow] != 0)
[cell.layer insertSublayer:bottomShadow atIndex:0];
CGRect shadowFrame = bottomShadow.frame;
shadowFrame.size.width = cell.frame.size.width;
shadowFrame.origin.y = cell.frame.size.height;
bottomShadow.frame = shadowFrame;
else
[bottomShadow removeFromSuperlayer];
bottomShadow = nil;
//
// dealloc
//
// Releases instance memory.
//
@end
【问题讨论】:
不记得细节,但他们确实更新了导航栏上阴影的显示方式。 【参考方案1】:似乎 CAGradientLayer 需要 0,0,0,0 的 RGBA 来制作完全透明的颜色,这意味着它的混合模式在 iOS 7 中发生了变化。我已经为此提交了一份雷达 (#15336983)。
无论如何,解决方法是替换:
([self.backgroundColor colorWithAlphaComponent:0.0].CGColor) :
与:
([UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.0].CGColor) :
【讨论】:
以上是关于在 iOS 7 下运行我的 iOS 6 应用程序时,为啥我的视图上没有正确显示阴影?的主要内容,如果未能解决你的问题,请参考以下文章
UIButton 在 iOS 7 的兼容模式下没有获得 iOS 6 样式
indexPathForCell 在 IOS 7 下返回 NULL,在 IOS 6 下工作正常