1

所以伙计们,我正在使用这个功能来拍摄UIWebView加载电子书的照片并在用户渲染页面时显示它

-(UIImage*)captureScreen:(UIView*) viewToCapture
{

    UIGraphicsBeginImageContextWithOptions(viewToCapture.bounds.size, viewToCapture.opaque, 0.0);
    [viewToCapture.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return viewImage;
}

但问题是获取图像发生延迟(0.5 秒).. 当我在时间分析器中测试时,仪器指向这条线 [viewToCapture.layer renderInContext:UIGraphicsGetCurrentContext()];作为导致延迟的线.. 所以任何建议,建议我怎么能过来这个延迟。

先谢谢了。

注意事项: 1.Im 使用 UIPageController 实现书籍效果。

2.要检查我尝试过的内容,请检查此链接

4

2 回答 2

1

解决这个问题的最好方法是使用委托。这意味着如果您告诉委托方法制作图像,它可以在后台执行并告诉您的视图“嘿,现在我为您获取了 XXX 的图像”(取决于您如何实现它。这样您就可以加载您的查看其中的电子书,并在书的中间显示一个带有默认背景的加载器。图像完成后,您使用正确的图像更新书的视图并删除加载器。就像苹果的iBooks 和任何其他好的应用程序都可以。

我自己的一个项目的示例(根据您的需要进行了调整,但在 UITableViewController 中使用):
BookDelegate.h

#import <Foundation/Foundation.h>

@class Book;

@protocol BookDelegate <NSObject>

@optional
- (void)didRecieveImageForBook:(NSString*)imagePath indexPath:(NSIndexPath*)indexPath;

@end

书.h

#import <Foundation/Foundation.h>
#import "BookDelegate.h"

@interface Book : NSOperation <NSObject>
{   
    id <BookDelegate> delegate;
    SEL didRecieveImageForBookSelector;
}

@property (strong, nonatomic) id delegate;
@property (assign) SEL didRecieveImageForBookSelector;

- (NSString*)getBookImageForBookId:(int)BookId externalRefference:(NSString*)url indexPath:(NSIndexPath*)indexPath;
- (id)delegate;

// Delegate methods
- (void)didRecieveImageForBook:(NSString*)imagePath indexPath:(NSIndexPath*)indexPath;

@end

书.m

#import "Book.h"
#import <objc/runtime.h>

@implementation Book

static char kAssociationKey;

@synthesize didRecieveImageForBookSelector;
@synthesize delegate;

- (id)init
{
    if (self = [super init])
    {
        [self setDidRecieveImageForBookSelector:@selector(didRecieveImageForBook:indexPath:)];
    }
    return self;
}

#pragma mark -
#pragma mark The default delegate functions

- (void)didRecieveImageForBook:(NSString*)imagePath indexPath:(NSIndexPath*)indexPath
{
    NSLog(@"********************************************************");
    NSLog(@"*** PLEASE IMPLEMENT THE FOLLOWING DELEGATE FUNCTION ***");
    NSLog(@"***       didRecieveImageForBook:indexPath:       ***");
    NSLog(@"********************************************************");
}

#pragma mark -
#pragma mark Function for fechting images

// This method is not adapted to what YOU need, but left my code here in case it might help you out.
- (NSString*)getBookImageForBookId:(int)bookId externalRefference:(NSString*)url indexPath:(NSIndexPath*)indexPath
{    
    NSString *ext = [[url lastPathComponent] pathExtension];

    NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];

    NSString *imagePath = [documentsPath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@%d.%@", APP_BookIMAGEPEFIX, BookId, ext]];
    BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:imagePath];

    if (fileExists)
    {
        return imagePath;
    }
    else {
        NSURL *theUrl = [NSURL URLWithString:url];

        ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:theUrl];
        [request setDidFinishSelector:@selector(BookImageFetched:)];
        [request setDidFailSelector:@selector(processFailed:)];
        [request setTimeOutSeconds:60];
        [request setDownloadDestinationPath:imagePath];
        [request setDelegate:self];

        [request startAsynchronous];

        objc_setAssociatedObject(request, &kAssociationKey, indexPath, OBJC_ASSOCIATION_RETAIN_NONATOMIC);

        return @"";
    }
}

- (void)BookImageFetched:(ASIHTTPRequest *)request 
{
    NSIndexPath *indexPath = objc_getAssociatedObject(request, &kAssociationKey);
    NSString *imagePath = request.downloadDestinationPath;

    [[self delegate] performSelector:self.didRecieveImageForBookSelector withObject:imagePath withObject:indexPath];
}

#pragma mark -
#pragma mark delegate functions

- (id)delegate
{
        return delegate;
}

- (void)setDelegate:(id)newDelegate
{
        delegate = newDelegate;
}

#pragma mark -

@end
于 2012-05-03T13:23:04.453 回答
1

您可以使用 GCD - 我注意到您提供的链接中的 GCD 缺少一个步骤。这是我用来异步获取图像并在它准备好并且工作正常时通知的方法:

dispatch_queue_t concurrent = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    dispatch_async(concurrent, ^{
        __block UIImage *image = nil;
        dispatch_sync(concurrent, ^{
            //put code to grab image here
        });
        dispatch_sync(dispatch_get_main_queue(), ^{
            //this gets called when the above is finshed
            //you should also check if the image is nil or not
        });
    }); 

希望能帮助到你

记录在案 - 我用它来拍摄 UIView 快照,并且总是尝试将我的目标放在父视图中,即使它是暂时的 - 它似乎加快了速度。

UIGraphicsBeginImageContextWithOptions(self.bounds.size, YES, 0.0);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;

不确定它是否有帮助,或者您是否使用相同的方法。我希望你能尽快解决这个问题:)

于 2012-05-03T13:26:35.830 回答