添加新元素后无法重新加载tableviewcontroller

时间:2014-05-23 01:29:08

标签: ios objective-c uitableview

所以我现在已经尝试了一段时间了,这让我感到非常沮丧,但这里是对我要做的事情的简要总结。我有一个LocationTableViewController,右上角有一个加号按钮,可以向表格视图添加新位置。当发生这种情况时,我进入LocationEditViewController,在那里我可以输入我想要添加的位置的名称。添加我的文本并点击保存位置按钮后,我希望代码将我带回到LocationTableViewController,在我的表格中,我看到了我新添加的位置。下面发布的是两个视图控制器的代码。希望你们能帮助我,谢谢你们!

#import <UIKit/UIKit.h>
#import "Location.h"
#import "User.h"

@interface LocationEditViewController : UIViewController <UITextFieldDelegate>

@property (strong, nonatomic) Location *location;
@property (strong, nonatomic) User *user;
@property (strong, nonatomic) UITextField *locationNameField;

- (void)saveLocation:(id) sender;

@end


#import "LocationEditViewController.h"

@interface LocationEditViewController ()

@end

@implementation LocationEditViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        self.title = @"Edit";
        self.location = [[Location alloc] init];
        self.user = [[User alloc] init];
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.view.backgroundColor = [UIColor whiteColor];

    UILabel *locationLabel = [[UILabel alloc] init];
    locationLabel.frame = CGRectMake(20,15,50,30);
    locationLabel.text = @"Name:";
    [self.view addSubview:locationLabel];

    self.locationNameField = [[UITextField alloc] init];
    self.locationNameField.frame = CGRectMake(15,50,290,30);
    self.locationNameField.borderStyle = UITextBorderStyleBezel;
    self.locationNameField.keyboardType = UIKeyboardTypeDefault;
    self.locationNameField.delegate = self;
    [self.view addSubview:self.locationNameField];

    UIButton *saveLocationButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    saveLocationButton.frame = CGRectMake(15,400,290,50);
    [saveLocationButton setTitle:@"Save Location" forState:UIControlStateNormal];
    [saveLocationButton addTarget:self action:@selector(saveLocation:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:saveLocationButton];
}

- (BOOL)textFieldShouldReturn:(UITextField *)textField {
    [textField resignFirstResponder];
    return YES;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

- (void)saveLocation:(id)sender {
    self.location.name = self.locationNameField.text;

    NSMutableArray *tempArray = [[NSMutableArray alloc] initWithArray:self.user.createdLocations];
    [tempArray addObject:self.location];
    self.user.createdLocations = [[NSArray alloc] initWithArray:tempArray];

    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Location Added"
                                                    message:@"This location is now accessable in the locations tab"
                                                   delegate:nil
                                          cancelButtonTitle:@"Ok"
                                          otherButtonTitles:nil];
    [alert show];

    [self.tabBarController.tabBar.items[1] setBadgeValue:[NSString stringWithFormat:@"%i",self.user.createdLocations.count]];

    [self dismissViewControllerAnimated:YES completion:^{
        [[NSNotificationCenter defaultCenter] postNotificationName:@"somethingAddedNotification" object:nil];
    }];
}

/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end

这是LocationTableViewController代码:

#import <UIKit/UIKit.h>
#import "User.h"

@interface LocationTableViewController : UITableViewController

@property (strong, nonatomic) NSArray *locations;
@property (strong, nonatomic) User *user;
@property (strong, nonatomic) id _observer;

- (void) addLocationPressed;

@end



#import "LocationTableViewController.h"
#import "LocationEditViewController.h"
#import "LocationViewController.h"

@interface LocationTableViewController ()

@end

@implementation LocationTableViewController

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        self.title = @"Locations";
        self.user = [[User alloc] init];
        UIBarButtonItem *addLocationButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAdd target:self action:@selector(addLocationPressed)];
        self.navigationItem.rightBarButtonItem = addLocationButton;

    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    //Location *loc = [[Location alloc] init];
    //self.user.createdLocations = @[loc];

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

- (void) addLocationPressed
{
    LocationEditViewController *locationEditVC = [[LocationEditViewController alloc] init];
    [self presentViewController:locationEditVC animated:YES completion:nil];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return self.user.createdLocations.count;
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
    if(cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"Cell"];
    }
    cell.textLabel.text = [self.user.createdLocations[indexPath.row] name];
    NSLog(@"%@", [self.user.createdLocations[indexPath.row] name]);

    return cell;
}

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    [tableView deselectRowAtIndexPath:indexPath animated:YES];

    LocationViewController *locationVC = [[LocationViewController alloc] init];
    locationVC.location = self.user.createdLocations[indexPath.row];

    [self.navigationController pushViewController:locationVC animated:YES];
}

- (void)viewWillAppear:(BOOL)animated {
    __observer = [[NSNotificationCenter defaultCenter] addObserverForName:@"somethingAddedNotification"
                                                                  object:nil
                                                                   queue:nil
                                                              usingBlock:^(NSNotification *notification)
    {
        [self.tableView reloadData];
    }];
}

- (void)viewWillDisappear:(BOOL)animated {
    [[NSNotificationCenter defaultCenter] removeObserver:__observer];
}

有关其他信息,请参阅我获取数组的用户类

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

@interface User : NSObject

@property (strong, nonatomic) Location *profilePhoto;
@property (strong, nonatomic) NSString *location;
@property (strong, nonatomic) NSArray *createdLocations;


-(id) initWithTitle: (Location *) aLoc
             detail: (NSString *) aDet
           filename: (NSArray *) aLocList;

//-(id)initWithJSON;
//+(NSString *)getPathToArchive;

//+(User *)getUser;
//+(void)saveUser:(User *)aUser;

@end

#import "User.h"
#import "Location.h"

@implementation User

- (id)init;
{
    self = [self initWithTitle: [[Location alloc] init]
                        detail: @"Temp"
                      filename: [[NSArray alloc] init]];
    return self;
}

-(id) initWithTitle: (Location *) aLoc
             detail: (NSString *) aDet
           filename: (NSArray *) aLocList
{
    self = [super init];
    if (self) {
        self.profilePhoto = aLoc;
        self.location = aDet;
        self.createdLocations = aLocList;
    }
    return self;

}

@end

以及必要时的Locations类

#import <Foundation/Foundation.h>

@interface Location : NSObject

@property (strong, nonatomic) NSString *name;
@property (strong, nonatomic) NSString *detail;
@property (strong, nonatomic) NSString *filename;
@property (strong, nonatomic) NSString *thumbnail;

-(id) initWithTitle: (NSString *) aTitle
             detail: (NSString *) aDetail
           filename: (NSString *) aFilename
          thumbnail: (NSString *) aThumbnail;

@end

#import "Location.h"

@implementation Location

-(id)init
{
    self = [self initWithTitle:@"Title"
                        detail:@"Detail"
                      filename:@"placeholder.jpg"
                     thumbnail:@"placeholder.jpg"];
    return self;
}

-(id)initWithTitle:(NSString *)aTitle
            detail:(NSString *)aDetail
          filename:(NSString *)aFilename
         thumbnail:(NSString *)aThumbnail
{
    self = [super init];
    if (self) {
        self.name = aTitle;
        self.detail = aDetail;
        self.filename = aFilename;
        self.thumbnail = aThumbnail;
    }
    return self;
}

@end

希望你们能帮助我!再次感谢!!!

2 个答案:

答案 0 :(得分:0)

你有没有设置断点......

[self.tableView reloadData];

...在你的观察者区块?会受到打击吗?另外,Drew Crawford对您正在使用的API(http://sealedabstract.com/code/nsnotificationcenter-with-blocks-considered-harmful/)持谨慎态度。

答案 1 :(得分:0)

就像评论所说,这绝对是一个问题,实际上可能是根本原因。您必须在块内使用__weak引用,否则NSNotificationCenter拥有对self的强引用,并且self拥有对NSNotificationCenter的强引用,并且您有一个保留周期。

- (void)viewWillAppear:(BOOL)animated {

    __weak LocationTableViewController *weakSelf = self;

    __observer = [[NSNotificationCenter defaultCenter] addObserverForName:@"somethingAddedNotification"
                                                                  object:nil
                                                                   queue:nil
                                                              usingBlock:^(NSNotification *notification)
    {
        [weakSelf.tableView reloadData];
    }];
}