我正在使用SDWebImage在UICollectionView中显示图像。我将productImageUrl和productId作为服务器响应。能够在Custom-cell中显示图像,现在我想要的是:
1)在另一个名为ProductDetailViewController的UIViewController上以大视图显示图像。(图像显示在ProductDetailViewController上,但我从ProductCollectionViewController传递图像url的方式不对,请查看代码,并建议更好的方法。)
2) On button click将调用服务器,并使用之前作为服务器响应获得的productId (如何将dictId传递给ProductDetailViewController,以便对服务器进行调用)。
3)获取only two key-value of an Object as response,所以可以在多个字典中解析多个值。但是如果响应包含多个值,那么什么将是the optimized way to parse the response。
这是我试过的密码。(很抱歉,长时间未优化的代码仍处于学习阶段)
ProductCollectionViewController.m
#import "ProductCollectionViewController.h"
#import "ProductCell.h"
#import "UIImageView+WebCache.h"
#import "ProductDetailViewController.h"
@interface ProductCollectionViewController ()
@property(strong, nonatomic) NSMutableArray *productList;
@end
@implementation ProductCollectionViewController
-(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
}
return self;
}
static NSString * const reuseIdentifier = @"Cell";
-(void)viewDidLoad
{
[super viewDidLoad];
[self getProductList];
}
-(void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
}
-(void)getProductList
{
NSURL * url = [NSURL URLWithString:@"xxxx.yyyy.zzzz"];
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:url];
NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject];
NSURLSessionDataTask * dataTask = [defaultSession dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
if (!error)
{
NSDictionary *responseJson = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
NSArray *rsBody = responseJson[@"rsBody"];
_productList = [NSMutableArray new];
for(NSDictionary *dict in rsBody)
{
NSMutableDictionary *dictUrl=[[NSMutableDictionary alloc]init];
NSMutableDictionary *dictProductId =[[NSMutableDictionary alloc]init];
[dictUrl setValue:[dict valueForKey:@"productImageUrl"] forKey:@"url"];
[dictId setValue:[dict valueForKey:@"productId"] forKey:@"id"];
[_productList addObject:dictUrl];
[_productList addObject:dictId];
}
NSLog(@"urls for image: %@",_productList );
[self.collectionView reloadData];
}}];
[dataTask resume];
}
#pragma mark <UICollectionViewDataSource>
-(NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
return 1;
}
-(NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
{
return _productList.count;
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
ProductCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"Cell" forIndexPath:indexPath];
NSURL *imageUrl = [[_productList objectAtIndex:indexPath.row]valueForKey:@"url"];
[cell.productImageView sd_setImageWithURL:imageUrl placeholderImage:[UIImage imageNamed:@"placeholder.jpg"]];
NSString *id =[[_productList objectAtIndex:indexPath.row] valueForKey:@"id"];
cell.productPrice.text= id;
return cell;
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"showProduct"]) {
NSArray *indexPaths = [self.collectionView indexPathsForSelectedItems];
ProductDetailViewController *destViewController = segue.destinationViewController;
NSIndexPath *indexPath = [indexPaths objectAtIndex:0]
destViewController.productName =[[_productList objectAtIndex:indexPath.row]valueForKey:@"url"];
[self.collectionView deselectItemAtIndexPath:indexPath animated:NO];
}
}
@endProductDetailViewController.h
`#import <UIKit/UIKit.h>
@interface ProductDetailViewController : UIViewController
- (IBAction)buyButton:(id)sender;
- (IBAction)closeButton:(id)sender;
@property (weak, nonatomic) IBOutlet UIImageView *productImage;
@property (weak, nonatomic) NSString *productName;
@end`ProductDetailViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
self.productImage.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:self.productName]]];
//code to get productId
}
- (IBAction)buyButton:(id)sender {
//code to make server call with productId.
}JSON的服务器响应格式
{"rsBody":
[{"productId":11,
"productImageUrl":"http:xxxx"},
{"productId":9,
"productImageUrl":"http:"xxxx"}]}发布于 2015-11-06 13:50:22
对于你的第一个问题,这句话
self.productImage.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:self.productName]]];阻塞了主线程。这意味着应用程序将在更新屏幕或允许交互之前下载整个图像,这是不好的。
NSURL *url = [[NSURL alloc]initWithString:self.productName];
dispatch_queue_t imageFetchQ = dispatch_queue_create("image fetcher", NULL);
dispatch_async(imageFetchQ, ^{
NSData *imageData = [[NSData alloc] initWithContentsOfURL:url];
UIImage *image = [[UIImage alloc]initWithData:imageData];
dispatch_async(dispatch_get_main_queue(), ^{
self.productImage.image=image;
}
});
}); 试一试上面的块。它将在另一个线程上获取产品映像。
问题二:视图控制器之间的两个传输数据执行在prepareForSegue中所做的操作,设置目标视图控制器的公共属性。
问题三:最佳的方法是创建一个NSObject类,通过某种名为setupFromDictionary的方法将数据从字典中读取到该类的属性中。
这里有一个名为product的对象,它具有productID属性和productImageURL属性。这样,您就不会经常在某些字典中调用valueForKey或objectForKey。
https://stackoverflow.com/questions/33566955
复制相似问题