0

我想在教程中创建一个滚动视图,如 Paging with UIScrollView。唯一不同的是在我的应用程序中,我将 .xib 文件添加到 UIscrollView 而不是 UIImageView,并且我从后端部分获取数据而不是静态设置它们。

我发现这条线需要时间(它实际上将图像加载到另一个滚动视图):

[self.offerView loadVisiblePages];

这正是那里发生的事情:

@implementation OfferUIView

- (void)initialization {
    NSInteger pageCount = self.pageImages.count;

    // Set up the array to hold the views for each page
    self.pageViews = [[NSMutableArray alloc] init];
    for (NSInteger i = 0; i < pageCount; ++i) {
        [self.pageViews addObject:[NSNull null]];
    }

    CGSize pagesScrollViewSize = self.scrollView.frame.size;
    self.scrollView.contentSize = CGSizeMake(pagesScrollViewSize.width * 3, pagesScrollViewSize.height);
}

- (void)loadVisiblePages {
    [self initialization];

    // First, determine which page is currently visible
    CGFloat pageWidth = self.scrollView.frame.size.width;
    NSInteger page = (NSInteger)floor((self.scrollView.contentOffset.x * 2.0f + pageWidth) / (pageWidth * 2.0f));

    // Work out which pages we want to load
    NSInteger firstPage = page - 1;
    NSInteger lastPage = page + 1;

    // Purge anything before the first page
    for (NSInteger i=0; i<firstPage; i++) {
        [self purgePage:i];
    }
    for (NSInteger i=firstPage; i<=lastPage; i++) {
        [self loadPage:i];
    }
    for (NSInteger i=lastPage+1; i<self.pageImages.count; i++) {
        [self purgePage:i];
    }
}

我的问题是当我第一次运行应用程序时,加载图像太慢了。你能帮助我吗?

这是 .h 文件:

@interface ViewController2 : UIViewController {
@private
    UIScrollView *scrollView;
}

@property (nonatomic, strong) IBOutlet UIScrollView *scrollView;
@property (nonatomic, strong) PFLogInViewController *login;

@end

和 .m 文件:

@interface ViewController2 ()
@property (nonatomic, strong) NSMutableDictionary *pageImages;
@property (nonatomic, strong) NSMutableArray *companies;
@property (nonatomic, strong) NSMutableArray *offers;
@property (nonatomic, strong) NSMutableArray *pageViews;
@property (nonatomic, strong) OfferUIView *offerView;
@property (nonatomic, assign) NSString *address;

- (void)loadVisiblePages;
- (void)loadPage:(NSInteger)page;
- (void)purgePage:(NSInteger)page;

@end

@implementation ViewController2

@synthesize scrollView = _scrollView;
@synthesize offerView = _offerView;

@synthesize pageImages = _pageImages;
@synthesize companies = _companies;
@synthesize offers = _offers;
@synthesize pageViews = _pageViews;
- (void)loadVisiblePages {
    // First, determine which page is currently visible

    CGFloat pageWidth = self.scrollView.frame.size.height;
    NSInteger page = (NSInteger)floor((self.scrollView.contentOffset.y * 2.0f + pageWidth) / (pageWidth * 2.0f));

    // Work out which pages we want to load
    NSInteger firstPage = page - 1;
    NSInteger lastPage = page + 1;

    // Purge anything before the first page
    for (NSInteger i=0; i<firstPage; i++) {
        [self purgePage:i];
    }
    for (NSInteger i=firstPage; i<=lastPage; i++) {
        [self loadPage:i];
    }
    for (NSInteger i=lastPage+1; i<self.pageImages.count; i++) {
        [self purgePage:i];
    }
}

- (void)loadPage:(NSInteger)page {
    if (page < 0 || page >= self.pageImages.count) {
        // If it's outside the range of what we have to display, then do nothing
        return;
    }
    // Load an individual page, first seeing if we've already loaded it
    UIView *pageView = [self.pageViews objectAtIndex:page];
    if ((NSNull*)pageView == [NSNull null]) {

        CGRect frame = self.scrollView.bounds;
        frame.origin.x = 0.0f;
        frame.origin.y = frame.size.height * page;

        NSArray *views = [[NSBundle mainBundle] loadNibNamed:@"OfferView" owner:self options:nil];
        self.offerView = [views objectAtIndex:0];
        self.offerView.contentMode = UIViewContentModeScaleAspectFit;
        self.offerView.frame = frame;
        [self.scrollView addSubview:self.offerView];
        [self.pageViews replaceObjectAtIndex:page withObject:self.offerView];

        self.offerView.pageId = 1;

        Company *company = [self.companies objectAtIndex:page];
        self.offerView.labelCompany.text = company.name;
        self.offerView.companyAddress = company.address;


        Offer *offer = [self.offers objectAtIndex:page];
        NSMutableArray *imageArray = [self.pageImages objectForKey:offer.objectId];
        self.offerView.pageImages = imageArray;
        self.offerView.offerId = offer.objectId;
        [self.offerView loadVisiblePages];

        self.offerView.labelOffer.text = @"Vid köp för minst";
        self.offerView.labelOffer.text =[[self.offerView.labelOffer.text stringByAppendingFormat:@" %i", offer.offer] stringByAppendingString:@"kr."];

        [self.offerView.labelDiscount setText: [[NSString stringWithFormat:@"%i", offer.discount] stringByAppendingString:@":-"]];

        double deadline = [offer.deadline timeIntervalSinceNow];
        double createdAt = [offer.createdAt timeIntervalSinceNow];
        double difference = deadline - createdAt;

        NSNumber *theDouble = [NSNumber numberWithDouble:difference];
        int inputSeconds = [theDouble intValue];
        int hours =  inputSeconds / 3600;
        int minutes = ( inputSeconds - hours * 3600 ) / 60;
        //int seconds = inputSeconds - hours * 3600 - minutes * 60;
        NSString *theTime = [NSString stringWithFormat:@"%dh %dm", hours, minutes];
        [self.offerView.labelDeadline setText:theTime];
    }
}

- (void)purgePage:(NSInteger)page {
    if (page < 0 || page >= self.pageImages.count) {
        // If it's outside the range of what we have to display, then do nothing
        return;
    }

    // Remove a page from the scroll view and reset the container array
    UIView *pageView = [self.pageViews objectAtIndex:page];
    if ((NSNull*)pageView != [NSNull null]) {
        [pageView removeFromSuperview];
        [self.pageViews replaceObjectAtIndex:page withObject:[NSNull null]];
    }
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.

    // Set up the image we want to scroll and add it to the scroll view
    [self loadDataFromParse];

    NSInteger pageCount = self.pageImages.count;

    // Set up the array to hold the views for each page
    self.pageViews = [[NSMutableArray alloc] init];
    for (NSInteger i = 0; i < pageCount; ++i) {
        [self.pageViews addObject:[NSNull null]];
    }
    printf("%s\n", [@"ViewDidLoad" UTF8String]);
}

- (void)loadDataFromParse {
    self.pageImages = [[NSMutableDictionary alloc] init];
    self.companies = [[NSMutableArray alloc] init];
    self.offers = [[NSMutableArray alloc] init];

    PFQuery *companyQuery = [PFQuery queryWithClassName:@"Company"];
    NSArray *companyArray = [companyQuery findObjects];

    NSArray *offerArray;
    PFQuery *offerQuery = [PFQuery queryWithClassName:@"Offer"];

    NSArray *imageArray;
    PFQuery *imageQuery = [PFQuery queryWithClassName:@"Image"];

    for (NSInteger i=0; i<companyArray.count; i++) {
        PFObject *fetchedCompany = [companyArray objectAtIndex:i];
        Company *company = [[Company alloc] init];
        company.name = [fetchedCompany objectForKey:@"name"];
        company.address = [fetchedCompany objectForKey:@"address"];
        [offerQuery whereKey:@"company" equalTo:fetchedCompany];
        offerArray = [offerQuery findObjects];

        for (NSInteger j=0; j<offerArray.count; j++) {
            PFObject *fetchedOffer = [offerArray objectAtIndex:j];
            Offer *offer = [[Offer alloc] init];
            offer.objectId = [fetchedOffer valueForKey:@"objectId"];
            offer.offer = [[fetchedOffer objectForKey:@"offer"]integerValue];
            offer.discount = [[fetchedOffer objectForKey:@"discount"]integerValue];
            offer.deadline = [fetchedOffer objectForKey:@"deadline"];
            offer.createdAt = [fetchedOffer objectForKey:@"createdAt"];

            [imageQuery whereKey:@"offer" equalTo:fetchedOffer];
            imageArray = [imageQuery findObjects];

            NSMutableArray *array = [[NSMutableArray alloc] init];
            for (NSInteger k=0; k<imageArray.count; k++) {
                PFObject *fetchedimage = [imageArray objectAtIndex:k];
                [array addObject:fetchedimage];
            }
            [self.pageImages setObject:array forKey:offer.objectId];
            [self.offers addObject:offer];
            [self.companies addObject:company];
        }
    }
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    // Set up the content size of the scroll view
    CGSize pagesScrollViewSize = self.scrollView.frame.size;

    //self.scrollView.contentSize = CGSizeMake(pagesScrollViewSize.width * self.pageImages.count, pagesScrollViewSize.height);

    self.scrollView.contentSize = CGSizeMake(pagesScrollViewSize.width, pagesScrollViewSize.height * self.pageImages.count);

    // Load the initial set of pages that are on screen
    [self loadVisiblePages];

    printf("%s\n", [@"ViewWillAppear" UTF8String]);
}

- (void)viewDidUnload
{
    [super viewDidUnload];
    // Release any retained subviews of the main view.
    self.offers = nil;
    self.companies = nil;
    self.pageImages = nil;
    self.pageViews = nil;
    self.scrollView = nil;
    self.offerView = nil;
}

- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}

#pragma mark - UIScrollViewDelegate

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    // Load the pages which are now on screen
    [self loadVisiblePages];
}
4

3 回答 3

0

下载SMPageControl示例..,它可能会帮助你..

于 2012-10-16T08:54:05.443 回答
0

在加载某些数据需要太多时间的情况下,您应该将工作卸载到后台线程。你试过使用GCD吗?

例如,您将像这样进行:

dispatch_queue_t preloadQueue = dispatch_queue_create("preload queue", nil);
    dispatch_async(preloadQueue, ^{
        // do the heavy task here
        dispatch_async(dispatch_get_main_queue(), ^{
        // set-up all the ui components that are required to be set on the main thread
        });
    });

也可以InstrumentsTime Profiling Toolto pin point 一起使用,该指令需要一些时间。

于 2012-10-16T09:04:13.167 回答
0

为了提高您的响应能力,我建议:

  • 首先加载缩略图并在后台加载实际图像。
  • 回收图像并在内存中最多保留 3 个。
  • UIImageViews使用以下方法加载UIImages加载以避免iOS缓存图像(在内存中进行手动缓存):

    + (UIImage *)imageWithContentsOfFile:(NSString *)path

  • 如果加载缩略图是不可接受的并且您的图像非常大,我会将它们平铺加载。

您可以查看WWDC 2010中的使用 Scrollviews 设计应用程序(需要登录)以及 Apple 的以下示例:PhotoScrollerScrollViewSuite。还有一个来自 WWDC 2009 的有趣视频,名为Mastering Scrollviews in iPhone,它涵盖了以UITableView细胞回收方式回收图像,但我找不到它。

于 2012-10-16T09:14:31.693 回答