即使在主线程上调用重新加载,UITable 也不会刷新
UITable won't refresh even with reload called on main thread
我有一个带有 UITable 和导航控制器的主视图控制器 (SecondViewController
)。按下导航栏按钮时,菜单会从 table 顶部的导航栏下拉。这个菜单是通过添加一个视图控制器作为子视图创建的,如下所示:
//SecondViewController.m
self = sortMenu.secondVC;
[self addChildViewController:sortMenu];
[self.view addSubview:sortMenu.view];
[sortMenu didMoveToParentViewController:self];
sortMenu
包含一个按钮,该按钮通过调用主视图控制器的 class 方法来更改单元格的显示顺序。
//SortMenuViewController.m
- (IBAction)sortButtonPressed:(id)sender {
[_secondVC sortButtonPressed:[sender tag]];
}
在 sortButtonPressed
中,它调用一个方法来发出具有更新的排序过滤器值的提取请求。
//SecondViewController.m
-(void)sortButtonPressed:(NSInteger)sortDescriptor{
_sortDescriptor = sortDescriptor;
currentPredicate = [NSPredicate predicateWithFormat:@"dataset & %d > 0", 4];
[self fetchResultsUsingSegmentedControlIndex];
}
提取请求已执行,returns数据按新顺序排列。
//SecondViewController.m
- (IBAction)fetchResultsUsingSegmentedControlIndex
{
NSString* sectionNameKeyPath = nil;
NSArray* sortDescriptors = nil;
NSSortDescriptor *scientificNameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"scientificName" ascending:YES];
NSSortDescriptor *commonNameFirstDescriptor = [[NSSortDescriptor alloc] initWithKey:@"commonNameFirst" ascending:YES];
NSSortDescriptor *commonNameLastDescriptor = [[NSSortDescriptor alloc]
initWithKey:@"commonNameLast"
ascending:YES
selector:@selector(localizedCaseInsensitiveCompare:)];
if (_sortDescriptor == kSortByCommonNameFirst )
{
sortDescriptors = [[NSArray alloc] initWithObjects:commonNameFirstDescriptor, commonNameLastDescriptor, scientificNameDescriptor, nil];
sectionNameKeyPath = @"commonNameFirst";
}
else if (_sortDescriptor == kSortByCommonNameLast )
{
sortDescriptors = [[NSArray alloc] initWithObjects:commonNameLastDescriptor, commonNameFirstDescriptor, scientificNameDescriptor, nil];
sectionNameKeyPath = @"commonNameLast";
}
else if (_sortDescriptor == kSortByScientificName )
{
sortDescriptors = [[NSArray alloc] initWithObjects:scientificNameDescriptor, commonNameFirstDescriptor, commonNameLastDescriptor, nil];
sectionNameKeyPath = @"scientificName";
}
NSError *error;
NSLog(@"current predicate: %@", currentPredicate);
[[self fetchedResultsControllerWithsectionNameKeyPath:sectionNameKeyPath sortDescriptors:sortDescriptors predicate:currentPredicate] performFetch:&error];
[scientificNameDescriptor release];
[commonNameLastDescriptor release];
[commonNameFirstDescriptor release];
[sortDescriptors release];
NSUInteger sectionsCt = [[speciesFetchedResultsController sections] count];
int sum = 0;
for (int i=1; i < sectionsCt; i++){
id <NSFetchedResultsSectionInfo> sectionInfo = [[speciesFetchedResultsController sections] objectAtIndex:i];
NSUInteger numOfObj = [sectionInfo numberOfObjects];
NSLog(@" in section %d number of objects is %lu ", i, (unsigned long)numOfObj);
sum = sum + numOfObj;
}
[_table performSelectorOnMainThread:@selector(reloadData)
withObject:nil
waitUntilDone:NO];
}
当我从主视图控制器调用 fetchResultsUsingSegmentedControlIndex
时(在下拉排序菜单之前),它工作正常。但是,当从 sortMenu
调用时,不会调用 numberOfRowsInSection
、numberOfSectionsInTableView
和 cellForRowAtIndexPath
。我试图用 performSelectorOnMainThread
在主线程上调用 reloadData
并将其分派到主队列,但都不起作用。
我最初通过在按下导航栏按钮时向主视图控制器添加一个 pickerview 创建了一个排序菜单,并且我的 table 重新加载正确。由于为菜单创建了一个单独的视图控制器(以获得更好的设计控制),它不起作用。
最终使用委托。
// SortMenuViewController.h
#import <UIKit/UIKit.h>
@protocol SortMenuViewControllerDelegate <NSObject>
-(void)sortButtonPressed:(NSInteger)sortDescriptor;
-(void)viewButtonPressed:(NSInteger)viewDescriptor;
@end
@interface SortMenuViewController : UIViewController{
}
//SortMenuViewController.m
- (IBAction)changeSort:(id)sender {
[_delegate sortButtonPressed:[sender tag]];
}
//SecondViewController.h
@interface SecondViewController : UIViewController <NSFetchedResultsControllerDelegate, SortMenuViewControllerDelegate>{
}
-(void)sortButtonPressed:(NSInteger)sortDescriptor{
_sortDescriptor = sortDescriptor;
currentPredicate = [NSPredicate predicateWithFormat:@"dataset & %d > 0", dataset];
[self fetchResultsUsingSegmentedControlIndex];
}
我有一个带有 UITable 和导航控制器的主视图控制器 (SecondViewController
)。按下导航栏按钮时,菜单会从 table 顶部的导航栏下拉。这个菜单是通过添加一个视图控制器作为子视图创建的,如下所示:
//SecondViewController.m
self = sortMenu.secondVC;
[self addChildViewController:sortMenu];
[self.view addSubview:sortMenu.view];
[sortMenu didMoveToParentViewController:self];
sortMenu
包含一个按钮,该按钮通过调用主视图控制器的 class 方法来更改单元格的显示顺序。
//SortMenuViewController.m
- (IBAction)sortButtonPressed:(id)sender {
[_secondVC sortButtonPressed:[sender tag]];
}
在 sortButtonPressed
中,它调用一个方法来发出具有更新的排序过滤器值的提取请求。
//SecondViewController.m
-(void)sortButtonPressed:(NSInteger)sortDescriptor{
_sortDescriptor = sortDescriptor;
currentPredicate = [NSPredicate predicateWithFormat:@"dataset & %d > 0", 4];
[self fetchResultsUsingSegmentedControlIndex];
}
提取请求已执行,returns数据按新顺序排列。
//SecondViewController.m
- (IBAction)fetchResultsUsingSegmentedControlIndex
{
NSString* sectionNameKeyPath = nil;
NSArray* sortDescriptors = nil;
NSSortDescriptor *scientificNameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"scientificName" ascending:YES];
NSSortDescriptor *commonNameFirstDescriptor = [[NSSortDescriptor alloc] initWithKey:@"commonNameFirst" ascending:YES];
NSSortDescriptor *commonNameLastDescriptor = [[NSSortDescriptor alloc]
initWithKey:@"commonNameLast"
ascending:YES
selector:@selector(localizedCaseInsensitiveCompare:)];
if (_sortDescriptor == kSortByCommonNameFirst )
{
sortDescriptors = [[NSArray alloc] initWithObjects:commonNameFirstDescriptor, commonNameLastDescriptor, scientificNameDescriptor, nil];
sectionNameKeyPath = @"commonNameFirst";
}
else if (_sortDescriptor == kSortByCommonNameLast )
{
sortDescriptors = [[NSArray alloc] initWithObjects:commonNameLastDescriptor, commonNameFirstDescriptor, scientificNameDescriptor, nil];
sectionNameKeyPath = @"commonNameLast";
}
else if (_sortDescriptor == kSortByScientificName )
{
sortDescriptors = [[NSArray alloc] initWithObjects:scientificNameDescriptor, commonNameFirstDescriptor, commonNameLastDescriptor, nil];
sectionNameKeyPath = @"scientificName";
}
NSError *error;
NSLog(@"current predicate: %@", currentPredicate);
[[self fetchedResultsControllerWithsectionNameKeyPath:sectionNameKeyPath sortDescriptors:sortDescriptors predicate:currentPredicate] performFetch:&error];
[scientificNameDescriptor release];
[commonNameLastDescriptor release];
[commonNameFirstDescriptor release];
[sortDescriptors release];
NSUInteger sectionsCt = [[speciesFetchedResultsController sections] count];
int sum = 0;
for (int i=1; i < sectionsCt; i++){
id <NSFetchedResultsSectionInfo> sectionInfo = [[speciesFetchedResultsController sections] objectAtIndex:i];
NSUInteger numOfObj = [sectionInfo numberOfObjects];
NSLog(@" in section %d number of objects is %lu ", i, (unsigned long)numOfObj);
sum = sum + numOfObj;
}
[_table performSelectorOnMainThread:@selector(reloadData)
withObject:nil
waitUntilDone:NO];
}
当我从主视图控制器调用 fetchResultsUsingSegmentedControlIndex
时(在下拉排序菜单之前),它工作正常。但是,当从 sortMenu
调用时,不会调用 numberOfRowsInSection
、numberOfSectionsInTableView
和 cellForRowAtIndexPath
。我试图用 performSelectorOnMainThread
在主线程上调用 reloadData
并将其分派到主队列,但都不起作用。
我最初通过在按下导航栏按钮时向主视图控制器添加一个 pickerview 创建了一个排序菜单,并且我的 table 重新加载正确。由于为菜单创建了一个单独的视图控制器(以获得更好的设计控制),它不起作用。
最终使用委托。
// SortMenuViewController.h
#import <UIKit/UIKit.h>
@protocol SortMenuViewControllerDelegate <NSObject>
-(void)sortButtonPressed:(NSInteger)sortDescriptor;
-(void)viewButtonPressed:(NSInteger)viewDescriptor;
@end
@interface SortMenuViewController : UIViewController{
}
//SortMenuViewController.m
- (IBAction)changeSort:(id)sender {
[_delegate sortButtonPressed:[sender tag]];
}
//SecondViewController.h
@interface SecondViewController : UIViewController <NSFetchedResultsControllerDelegate, SortMenuViewControllerDelegate>{
}
-(void)sortButtonPressed:(NSInteger)sortDescriptor{
_sortDescriptor = sortDescriptor;
currentPredicate = [NSPredicate predicateWithFormat:@"dataset & %d > 0", dataset];
[self fetchResultsUsingSegmentedControlIndex];
}