是否可以在加载视图的同时在 UICollectionView 中加载自定义单元格?
Is it possible to load custom cells in a UICollectionView at the same time the view loads?
我是 iOS 的新手,我似乎陷入了 UICollectionView 问题。
我正在尝试制作一个选项卡栏应用,其第一个选项卡是包含集合视图的导航控制器。海关单元格的内容(图像、文本)来自网络服务。由于通过网络服务下载内容需要时间,我希望应用程序启动后立即显示单元格,而不必等待数据加载(这意味着在数据加载之前).因此,屏幕上会有 只有空单元格 (& 标签栏和导航栏)的时间很短。
但是,当我的应用程序运行时,单元格是在从 Web 服务加载所有数据的同时创建的。有时当网速很慢时,屏幕上会等待很长时间才能加载有数据的单元格。 不知道是否有人可以告诉我我做错了什么。提前致谢!
这是我的 viewDidLoad: 集合视图控制器实现文件中方法的代码:
- (void)viewDidLoad
{
[super viewDidLoad];
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame
collectionViewLayout:layout];
[self.collectionView setDataSource:self];
[self.collectionView setDelegate:self];
[self.collectionView setBackgroundColor:[UIColor whiteColor];
layout.sectionInset = UIEdgeInsetsMake(0, 5, 10, 5);
layout.minimumLineSpacing = 5;
UINib *nib = [UINib nibWithNibName:@"TDEFeedCollectionViewCell" bundle:nil];
[self.collectionView registerNib:nib forCellWithReuseIdentifier:@"feedCell"];
}
我是否应该在 loadView:
方法中执行上述实现并将配置的 UICollectionView
对象分配给集合视图控制器的 view
属性 以便单元格加载为一旦 loadView:
方法被调用?
非常感谢!
--- 编辑 ---
下面是控制器初始化器的实现:
- (instancetype)initWithCollectionViewLayout:(UICollectionViewLayout *)layout
{
self = [super initWithCollectionViewLayout:layout];
if (self) {
self.navigationItem.title = @"News Feeds";
_session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]
delegate:nil
delegateQueue:nil];
[self fetchFeed];
}
return self;
}
下面是初始化器中使用的 -(void)fetchFeed
方法的实现:
- (void)fetchFeed
{
NSString *requestString = @"http://exampleapi.exampleweb.com/feeds.json";
NSURL *url = [NSURL URLWithString:requestString];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:req
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:data
options:0
error:nil];
self.feeds = jsonObject[@"feeds"];
dispatch_async(dispatch_get_main_queue(), ^{
[self.collectionView reloadData];
});
}];
[dataTask resume];
}
在数据源方法中,我只是使用 JSON 在 -(void)fetchFeed
方法中解析的数据并将它们分配给适当的单元格视图。
Apple 有一个照片网格视图示例项目,可以使用智能缓存即时加载资产。
Example app using Photos framework
如果我是你,我会考虑从那个开始,然后用你自己的网络服务调用替换照片库调用应该是微不足道的。
这个项目免费为您提供了很多东西 - 相信我,在我看到这个页面之前,我几乎从头开始写了一些类似的东西。
对不起,ArenLi,我完全误解了这个问题。
你想要的解决方案(我认为)是在下载完成之前用一些空白数据预填充 self.feeds
,当它完成时,你更新数组并重新加载 self.collectionView
.
尝试添加这个
self.feeds = [NSArray arrayWithCapacity:10]; // or any other number you want
[self.collectionView reloadData];
之后
UINib *nib = [UINib nibWithNibName:@"TDEFeedCollectionViewCell" bundle:nil];
[self.collectionView registerNib:nib forCellWithReuseIdentifier:@"feedCell"];
在- viewDidLoad
方法中,看看是否有帮助。
问题当然在于您不知道在下载完成之前要显示的单元格数量,因此您必须猜测或者只是用某个任意数字来解决。
注意: 请小心使用此方法,因为它可能会崩溃,因为单元格可能希望在 self.feeds
中找到一些数据。您需要确保单元格已准备好获取空白数据。
我是 iOS 的新手,我似乎陷入了 UICollectionView 问题。
我正在尝试制作一个选项卡栏应用,其第一个选项卡是包含集合视图的导航控制器。海关单元格的内容(图像、文本)来自网络服务。由于通过网络服务下载内容需要时间,我希望应用程序启动后立即显示单元格,而不必等待数据加载(这意味着在数据加载之前).因此,屏幕上会有 只有空单元格 (& 标签栏和导航栏)的时间很短。
但是,当我的应用程序运行时,单元格是在从 Web 服务加载所有数据的同时创建的。有时当网速很慢时,屏幕上会等待很长时间才能加载有数据的单元格。 不知道是否有人可以告诉我我做错了什么。提前致谢!
这是我的 viewDidLoad: 集合视图控制器实现文件中方法的代码:
- (void)viewDidLoad
{
[super viewDidLoad];
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
self.collectionView = [[UICollectionView alloc] initWithFrame:self.view.frame
collectionViewLayout:layout];
[self.collectionView setDataSource:self];
[self.collectionView setDelegate:self];
[self.collectionView setBackgroundColor:[UIColor whiteColor];
layout.sectionInset = UIEdgeInsetsMake(0, 5, 10, 5);
layout.minimumLineSpacing = 5;
UINib *nib = [UINib nibWithNibName:@"TDEFeedCollectionViewCell" bundle:nil];
[self.collectionView registerNib:nib forCellWithReuseIdentifier:@"feedCell"];
}
我是否应该在 loadView:
方法中执行上述实现并将配置的 UICollectionView
对象分配给集合视图控制器的 view
属性 以便单元格加载为一旦 loadView:
方法被调用?
非常感谢!
--- 编辑 --- 下面是控制器初始化器的实现:
- (instancetype)initWithCollectionViewLayout:(UICollectionViewLayout *)layout
{
self = [super initWithCollectionViewLayout:layout];
if (self) {
self.navigationItem.title = @"News Feeds";
_session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]
delegate:nil
delegateQueue:nil];
[self fetchFeed];
}
return self;
}
下面是初始化器中使用的 -(void)fetchFeed
方法的实现:
- (void)fetchFeed
{
NSString *requestString = @"http://exampleapi.exampleweb.com/feeds.json";
NSURL *url = [NSURL URLWithString:requestString];
NSURLRequest *req = [NSURLRequest requestWithURL:url];
NSURLSessionDataTask *dataTask = [self.session dataTaskWithRequest:req
completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error) {
NSDictionary *jsonObject = [NSJSONSerialization JSONObjectWithData:data
options:0
error:nil];
self.feeds = jsonObject[@"feeds"];
dispatch_async(dispatch_get_main_queue(), ^{
[self.collectionView reloadData];
});
}];
[dataTask resume];
}
在数据源方法中,我只是使用 JSON 在 -(void)fetchFeed
方法中解析的数据并将它们分配给适当的单元格视图。
Apple 有一个照片网格视图示例项目,可以使用智能缓存即时加载资产。
Example app using Photos framework
如果我是你,我会考虑从那个开始,然后用你自己的网络服务调用替换照片库调用应该是微不足道的。
这个项目免费为您提供了很多东西 - 相信我,在我看到这个页面之前,我几乎从头开始写了一些类似的东西。
对不起,ArenLi,我完全误解了这个问题。
你想要的解决方案(我认为)是在下载完成之前用一些空白数据预填充 self.feeds
,当它完成时,你更新数组并重新加载 self.collectionView
.
尝试添加这个
self.feeds = [NSArray arrayWithCapacity:10]; // or any other number you want
[self.collectionView reloadData];
之后
UINib *nib = [UINib nibWithNibName:@"TDEFeedCollectionViewCell" bundle:nil];
[self.collectionView registerNib:nib forCellWithReuseIdentifier:@"feedCell"];
在- viewDidLoad
方法中,看看是否有帮助。
问题当然在于您不知道在下载完成之前要显示的单元格数量,因此您必须猜测或者只是用某个任意数字来解决。
注意: 请小心使用此方法,因为它可能会崩溃,因为单元格可能希望在 self.feeds
中找到一些数据。您需要确保单元格已准备好获取空白数据。