我意识到当我回到tableViewController时,我的视图控制器旁边有一个白框。如果我有任何框架或子视图或类似的东西,我检查了我的代码。
这是一个显示我的问题的GIF:http://i.stack.imgur.com/P69wk.gif
这是我的MasterViewController.h和.m(这是桌面视图)的内容
MasterViewController.h
#import <UIKit/UIKit.h>
#import <CoreData/CoreData.h>
@interface XMMasterViewController : UITableViewController <NSFetchedResultsControllerDelegate>
@property (strong, nonatomic) NSFetchedResultsController *fetchedResultsController;
@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@end
MasterViewController.m
#import "XMMasterViewController.h"
#import "XMDetailViewController.h"
#import "XMEditViewController.h"
@interface XMMasterViewController ()
@property (nonatomic, strong) XMDetailViewController *detailViewController;
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath;
- (void)dataChangedFromICloud:(NSNotification*)note;
@end
@implementation XMMasterViewController
- (void)awakeFromNib
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
self.clearsSelectionOnViewWillAppear = NO;
self.preferredContentSize = CGSizeMake(320.0, 600.0);
}
[super awakeFromNib];
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.navigationItem.leftBarButtonItem = self.editButtonItem;
UIBarButtonItem *addButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(insertNewObject:)];
self.navigationItem.rightBarButtonItem = addButton;
self.detailViewController = (XMDetailViewController *)[[self.splitViewController.viewControllers lastObject] topViewController];
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(dataChangedFromICloud:) name:@"databaseChanged" object:nil];
});
[self.tableView reloadData];
}
- (void)viewDidUnload
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)insertNewObject:(id)sender
{
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
NSEntityDescription *entity = [[self.fetchedResultsController fetchRequest] entity];
NSManagedObject *newManagedObject = [NSEntityDescription insertNewObjectForEntityForName:[entity name] inManagedObjectContext:context];
// If appropriate, configure the new managed object.
// Normally you should use accessor methods, but using KVC here avoids the need to add a custom class to the template.
[newManagedObject setValue: NSLocalizedString(@"name", nil) forKey:@"title"];
[newManagedObject setValue:[NSDate date] forKey:@"timestamp"];
[newManagedObject setValue:[NSDate date] forKey:@"creationDate"];
[newManagedObject setValue: nil forKey:@"text"];
[newManagedObject setValue: NSLocalizedString(@"place", nil) forKey:@"location"];
// Save the context.
NSError *error = nil;
if (![context save:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
[self performSegueWithIdentifier:@"addSegue" sender:newManagedObject];
}
#pragma mark - Table View
/*- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
NSArray *array = [[NSArray alloc] initWithObjects:@"Noch zu erledigen",@"Erledigt",nil];
return array.count;
}*/
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [[self.fetchedResultsController sections] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController sections][section];
return [sectionInfo numberOfObjects];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return NO if you do not want the specified item to be editable.
return YES;
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSManagedObjectContext *context = [self.fetchedResultsController managedObjectContext];
[context deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]];
NSError *error = nil;
if (![context save:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
}
}
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
// The table view should not be re-orderable.
return NO;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
NSManagedObject *object = [[self fetchedResultsController] objectAtIndexPath:indexPath];
self.detailViewController.detailItem = object;
self.detailViewController.selectionView.hidden = YES;
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([[segue identifier] isEqualToString:@"showDetail"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
NSManagedObject *object = [[self fetchedResultsController] objectAtIndexPath:indexPath];
[[segue destinationViewController] setDetailItem:object];
} else if ([segue.identifier isEqualToString:@"addSegue"]) {
XMEditViewController *editVC = segue.destinationViewController;
editVC.detailItem = sender;
}
}
#pragma mark - Fetched results controller
- (NSFetchedResultsController *)fetchedResultsController
{
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSManagedObjectContext* context = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription* entity = [NSEntityDescription entityForName:@"Todo" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
// Set the batch size to a suitable number.
[fetchRequest setFetchBatchSize:20];
// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"timestamp" ascending:YES];
NSArray *sortDescriptors = @[sortDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"done == %@", @(NO)];
[fetchRequest setPredicate:predicate];
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"done" cacheName:nil];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _fetchedResultsController;
}
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
{
switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath
{
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:@[newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
[self.tableView reloadData];
[self.tableView endUpdates];
}
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
NSManagedObject *object = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.textLabel.text = [object valueForKey:@"title"];
cell.detailTextLabel.text = @"Test";
NSDate *date = [object valueForKey:@"timestamp"];
NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:@"dd.MM.yyyy"];
NSDate *time = [object valueForKey:@"timestamp"];
NSDateFormatter *timeformat = [NSDateFormatter new];
[timeformat setDateFormat:@"HH:mm"];
cell.detailTextLabel.text = [NSString stringWithFormat:NSLocalizedString(@"display",nil), [format stringFromDate:date], [timeformat stringFromDate:time]];
}
#pragma mark - iCloud refresh
- (void)dataChangedFromICloud:(NSNotification*)note
{
dispatch_async(dispatch_get_main_queue(), ^{
NSError *error = nil;
if(self.fetchedResultsController) {
if([self.fetchedResultsController performFetch:&error]) {
NSLog(@"Error! %@ %@", error, [error userInfo]);
}
[self.tableView reloadData];
}
});
}
@end
以下是DetailViewController的.h和.m文件(这个文件在返回时为我提供了空白区域)
DetailViewController.h
#import <UIKit/UIKit.h>
@interface XMDetailViewController : UIViewController {
// IBOutlet UISwitch *switchButton;
}
@property (strong, nonatomic) id detailItem;
@property (weak, nonatomic) IBOutlet UILabel *titleLabel;
@property (weak, nonatomic) IBOutlet UILabel *locationLabel;
@property (weak, nonatomic) IBOutlet UILabel *timeLabel;
@property (weak, nonatomic) IBOutlet UITextView *todoTextView;
@property (weak, nonatomic) IBOutlet UIView *selectionView;
- (IBAction)todoDoneTouched:(UIButton *)sender;
- (IBAction)shareTouched:(id)sender;
@end
DetailViewController.m
#import "XMDetailViewController.h"
#import "XMEditViewController.h"
#import "XMInfoViewController.h"
#import <Social/Social.h>
@interface XMDetailViewController ()
@property (strong, nonatomic) UIPopoverController *masterPopoverController;
- (void)configureView;
@end
@implementation XMDetailViewController
#pragma mark - Managing the detail item
- (void)setDetailItem:(id)newDetailItem
{
if (_detailItem != newDetailItem) {
_detailItem = newDetailItem;
// Update the view.
[self configureView];
}
if (self.masterPopoverController != nil) {
[self.masterPopoverController dismissPopoverAnimated:YES];
}
}
- (void)configureView
{
// Update the user interface for the detail item.
if (self.detailItem) {
self.titleLabel.text = [self.detailItem valueForKey:@"title"];
self.todoTextView.text = [self.detailItem valueForKey:@"text"];
self.locationLabel.text = [self.detailItem valueForKey:@"location"];
NSDate *date = [self.detailItem valueForKey:@"timestamp"];
NSDateFormatter *format = [NSDateFormatter new];
[format setDateFormat:@"dd.MM.yyyy"];
NSDate *time = [self.detailItem valueForKey:@"timestamp"];
NSDateFormatter *timeformat = [NSDateFormatter new];
[timeformat setDateFormat:@"HH:mm"];
self.timeLabel.text = [NSString stringWithFormat:NSLocalizedString(@"display",nil), [format stringFromDate:date], [timeformat stringFromDate:time]];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
// switchButton.on = [[self.detailItem valueForKey:@"done"] boolValue];
}
- (void)viewWillAppear:(BOOL)animated
{
[self configureView];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)todoDoneTouched:(UIButton *)sender {
[self.detailItem setValue:@(YES) forKey:@"done"];
NSManagedObjectContext *context = [self.detailItem managedObjectContext];
NSError *error = nil;
if(![context save:&error]) {
NSLog(NSLocalizedString(@"error1",nil), error, [error userInfo]);
abort();
}
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPad) {
self.selectionView.hidden = NO;
}
[self.navigationController popViewControllerAnimated:YES];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"myTodo" message:NSLocalizedString(@"done2",nil) delegate:nil cancelButtonTitle:@"Okay" otherButtonTitles:nil, nil];
[alert show];
NSLog(NSLocalizedString(@"done1",nil));
}
/*-(IBAction)theSwitch {
if (switchButton.on) {
[self.detailItem setValue:@(YES) forKey:@"done"];
NSManagedObjectContext *context = [self.detailItem managedObjectContext];
NSError *error = nil;
if(![context save:&error]) {
NSLog(NSLocalizedString(@"error1",nil), error, [error userInfo]);
abort();
}
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"myTodo" message:NSLocalizedString(@"done2",nil) delegate:nil cancelButtonTitle:@"Okay" otherButtonTitles:nil, nil];
[alert show];
NSLog(NSLocalizedString(@"done1",nil));
} else {
[self.detailItem setValue:@(NO) forKey:@"done"];
NSManagedObjectContext *context = [self.detailItem managedObjectContext];
NSError *error = nil;
if(![context save:&error]) {
NSLog(NSLocalizedString(@"error1",nil), error, [error userInfo]);
abort();
}
}
}
*/
- (IBAction)shareTouched:(id)sender {
NSString *titleString = [self.detailItem valueForKey:@"title"];
NSDate *date = [self.detailItem valueForKey:@"timestamp"];
NSDateFormatter *format = [NSDateFormatter new];
[format setDateFormat:@"dd.MM.yyyy"];
NSDate *time = [self.detailItem valueForKey:@"timestamp"];
NSDateFormatter *timeformat = [NSDateFormatter new];
[timeformat setDateFormat:@"HH:mm"];
NSString *initialString = [NSString stringWithFormat:NSLocalizedString(@"post",nil), titleString, [format stringFromDate:date], [timeformat stringFromDate:time]];
NSURL *url = [NSURL URLWithString:@"http://s.xnmn.de/mytodo"];
UIImage *image = [UIImage imageNamed:@"AppIcon76x76@2x"];
NSArray *activityItems = [NSArray arrayWithObjects:initialString, image, url, nil];
UIActivityViewController *activityViewController = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil];
activityViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
activityViewController.excludedActivityTypes = @[UIActivityTypePrint, UIActivityTypeCopyToPasteboard, UIActivityTypeAssignToContact, UIActivityTypeSaveToCameraRoll, UIActivityTypeAddToReadingList];
[self presentViewController:activityViewController animated:YES completion:nil];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([segue.identifier isEqualToString:@"editSegue"]){
XMEditViewController *editVC = segue.destinationViewController;
editVC.detailItem = self.detailItem;
}
}
- (void)splitViewController:(UISplitViewController *)splitController willHideViewController:(UIViewController *)viewController withBarButtonItem:(UIBarButtonItem *)barButtonItem forPopoverController:(UIPopoverController *)popoverController
{
barButtonItem.title = NSLocalizedString(@"Master",nil);
[self.navigationItem setLeftBarButtonItem:barButtonItem animated:YES];
self.masterPopoverController = popoverController;
}
- (void)splitViewController:(UISplitViewController *)splitController willShowViewController:(UIViewController *)viewController invalidatingBarButtonItem:(UIBarButtonItem *)barButtonItem
{
// Called when the view is shown again in the split view, invalidating the button and popover controller.
[self.navigationItem setLeftBarButtonItem:nil animated:YES];
self.masterPopoverController = nil;
}
@end
也许有人已经遇到过这个问题,或者知道这个问题并且知道如何解决这个问题。