在NSCache中的UIView被覆盖

时间:2013-05-21 16:46:53

标签: iphone ios objective-c uiview nscache

我有一个UIView,其中包含阴影和角落,我正在加载UIViewController中的四个,我看到屏幕加载时出现性能损失。由于我使用带阴影和角半径的相同白色背景,我想我会将UIView存储在NSCache中。

当我运行应用程序时,第一个UIView应该有一个很大的差距,但是它没有出现。显示的是我的视图列表中的最后一个视图。如果我将最后一个注释掉并再次运行,则会显示第三个。好像我在内存中遇到指针问题但不确定。也许我错误地使用NSCache了?

(注意:显示的第一个视图不使用NSCache)

enter image description here

以下是我使用NSCache的方法:

.h文件

@interface LunchDetailViewController : UIViewController <UIScrollViewDelegate>

@property (nonatomic) IBOutlet UIScrollView *scrollView;
@property (nonatomic, strong) NSCache *entreeViewsCache;

@end

.m文件

@synthesize scrollView;
@synthesize entreeViewsCache;

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.entreeViewsCache = [[NSCache alloc] init];
    UIView *entreeView = [[UIView alloc] init];
    entreeView.backgroundColor = [UIColor whiteColor];
    entreeView.layer.masksToBounds = NO;
    entreeView.layer.cornerRadius = 3.0;
    entreeView.layer.shadowOffset = CGSizeMake(1.1, 2.1);
    entreeView.layer.shadowOpacity = 0.2;

    [self.entreeViewsCache setObject:entreeView forKey:@"EntreeView"];
}

- (void) configureScrollView
{
    // This line of code allows the scroll view to be 'scrollable'.
    self.scrollView.contentSize = CGSizeMake(320, 620);

    UIView *elementaryRoundedCornerView = [self.entreeViewsCache objectForKey:@"EntreeView"];
    elementaryRoundedCornerView.frame = CGRectMake(15,15,290,180);

    UIView *middleRoundedCornerView = [self.entreeViewsCache objectForKey:@"EntreeView"];
    middleRoundedCornerView.frame = CGRectMake(15,210,290,180);

    UIView *highRoundedCornerView = [self.entreeViewsCache objectForKey:@"EntreeView"];
    highRoundedCornerView.frame = CGRectMake(15,404,290,180);

    NSMutableArray *entreeItems = [[NSMutableArray alloc] initWithObjects:@"Pancakes w/ Sausage Patties", @"Corn Dog", @"Grilled Cheese Sandwhich", @"Chicken Tender Wraps", nil];


    UIView *elementaryLunchMenuDetails = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 240, 160)];
    [elementaryLunchMenuDetails addSubview:[self returnNativeCode:entreeItems rectDimensions:CGRectMake(2, 5, 215, 160) schoolType:@"Elementary"]];
    [elementaryRoundedCornerView addSubview:elementaryLunchMenuDetails];

    UIView *middleLunchMenuDetails = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 240, 160)];
    [middleLunchMenuDetails addSubview:[self returnNativeCode:entreeItems rectDimensions:CGRectMake(2, 2, 215, 160) schoolType:@"Middle"]];
    [middleRoundedCornerView addSubview:middleLunchMenuDetails];

    UIView *highLunchMenuDetails = [[UIView alloc] initWithFrame:CGRectMake(10,10, 240, 160)];
    [highLunchMenuDetails addSubview:[self returnNativeCode:entreeItems rectDimensions:CGRectMake(2, 2, 215, 160) schoolType:@"High"]];
    [highRoundedCornerView addSubview:highLunchMenuDetails];

    [self.scrollView addSubview:elementaryRoundedCornerView];
    [self.scrollView addSubview:middleRoundedCornerView];
    [self.scrollView addSubview:highRoundedCornerView];
}

1 个答案:

答案 0 :(得分:0)

哇。这很聪明。但不正确。

您可能希望创建一个UIView子类,以您希望的方式格式化视图,而不是使用NSCache复制视图。然后在滚动视图中抛出一堆这些视图。

<强> ABCView.m

@implementation ABCDayView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor = [UIColor whiteColor];
        self.layer.masksToBounds = NO;
        self.layer.cornerRadius = 3.0;
        self.layer.shadowOffset = CGSizeMake(1.1f, 2.1f);
        self.layer.shadowOpacity = 0.2f;
    }
    return self;
}

- (void)setItems:(NSArray *)items
{
    if ([_items isEqualToArray:items] == NO) {
        _items = items;
        [self createItemViews];
        [self setNeedsLayout];
    }
}

// You'll also need to add -createItemViews and -setNeedsLayout methods.

.m文件

- (void)configureScrollView
{
    NSMutableArray *entreeItems = @[@"Pancakes w/Sausage Patties",
                                    @"Corn Dog",
                                    @"Grilled Cheese Sandwhich",
                                    @"Chicken Tender Wraps"];

    CGRect frame = CGRectMake(15,15,290,180);
    ABCDayView *elementaryView = [[ABCDayView alloc] initWithFrame:frame];
    elementaryView.items = entreeItems;

    CGFloat y = CGRectGetMaxY(elementaryView.frame) + 10.0f;
    frame = CGRectMake(15, y, 290, 180);
    ABCDayView *middleView = [[ABCDayView alloc] initWithFrame:frame];
    middleView.items = entreeItems;

    ...

    CGFloat length = // Use CGRectGetMaxY on the last frame to get the length.
    self.scrollView.contentSize = CGSizeMake(320, length);
}

这绝不是完美的代码。但希望它能让你了解实现这一目标的更好方法。