【问题标题】:how to pass data from a UIVIewController to a TableView subview?如何将数据从 UIVIewController 传递到 TableView 子视图?
【发布时间】:2014-11-07 15:08:02
【问题描述】:

我是 ios 编程新手,我正在尝试编写一个视图控制器,它将在视图顶部显示一个问题(通过标签),然后在下面的 tableview 子视图中显示答案列表。该视图是使用界面生成器设置的,但我以编程方式添加了 tableview。

我能够从 JSON 源加载数据并使用滑动手势将其打印出来,但无法在我的表格视图中访问数据。我通过放置 NSLog 知道 numberOfRowsInSection 在开始时运行一次以返回 0,但在我调用 [self.tableView reloadData] 时不再运行,这意味着该表仍然认为它有 0 行,即使它应该有大约 20 行。我将 UIViewController 设置为表视图委托和数据源。我还需要做什么?

主要问题:当表视图是我的视图控制器的子视图时,如何在我的表视图函数中访问视图控制器的 NSMutablearray 属性?谢谢!

这是我的初始声明和设置:

@interface BNRJudgeViewController () <UITextFieldDelegate, UINavigationControllerDelegate, UIGestureRecognizerDelegate, UITableViewDataSource, UITableViewDelegate >    
@property (nonatomic, strong) NSURLSession *session;
@property (weak, nonatomic) IBOutlet UILabel *question;
@property (weak, nonatomic) UITableView *tableView;
@property (nonatomic) NSMutableArray *answerArray;
@end

@implementation BNRJudgeViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if ([self isKindOfClass:[UIViewController class]]) {
        if(self){
            // Custom initialization
            self.title=@"Judge";
            self.navigationController.navigationItem.title = @"Judge";
            self.answerArray = [[NSMutableArray alloc] init];
            NSURLSessionConfiguration *config = [NSURLSessionConfiguration defaultSessionConfiguration];
            _session = [NSURLSession sessionWithConfiguration:config delegate:nil delegateQueue:nil];
            CGRect frame = CGRectMake(61, 252, 200, 225);
            UITableView *tableView = [[UITableView alloc] initWithFrame:frame];
            tableView.delegate = self;
            tableView.dataSource = self;
            [self.view addSubview:tableView];
        }

    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    if ([self isKindOfClass:[UIViewController class]]) {
        [self fetchFeed];
    }

    UISwipeGestureRecognizer *rightSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeRight:)];
    rightSwipe.direction = UISwipeGestureRecognizerDirectionRight;
    rightSwipe.numberOfTouchesRequired = 1;
    [self.view addGestureRecognizer:rightSwipe];

    UISwipeGestureRecognizer *leftSwipe = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeLeft:)];
    leftSwipe.direction = UISwipeGestureRecognizerDirectionLeft;
    leftSwipe.numberOfTouchesRequired = 1;
    [self.view addGestureRecognizer:leftSwipe];

}

这里是我获取 JSON 数据并将其分配给我的视图控制器的 NSMutableArray 属性的地方:

- (void)fetchFeed
{

    NSString *requestString = @"http://wsomeurl";
    NSURL *url = [NSURL URLWithString:requestString];
    NSURLRequest *req = [NSURLRequest requestWithURL:url];

    NSURLSessionDataTask *dataTask =
    [self.session dataTaskWithRequest:req completionHandler:
     ^(NSData *data, NSURLResponse *response, NSError *error){

         NSMutableArray *jsonObject = [NSJSONSerialization JSONObjectWithData:data
                                                                      options:0
                                                                        error:nil];

         self.answerArray = jsonObject;
        // NSLog(@"%@", self.answerArray);
               dispatch_async(dispatch_get_main_queue(), ^{
         [self.tableView reloadData];
               });


     }];
        [self.tableView reloadData];
    [dataTask resume];
    [self.tableView reloadData];
}

这是我的 tableview 所需的功能,在我的视图控制器中实现:

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    NSLog(@"recent integer count is %d", [self.answerArray count]);
    return [self.answerArray count];
}


- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"UITableViewCell"];
 //   NSDictionary *cellD = self.answerArray[indexPath.row];
   NSLog(@"%@", self.answerArray);
    NSLog(@"hi hi!");
     //  NSLog(@"%@", [cellD objectForKey:@"username"]);
 //   cell.textLabel.text = [cellD objectForKey:@"username"];
    return cell;

}

最后还有一些滑动函数显示这些函数可以看到数组 - 只是表格视图函数不能。

- (void)swipeRight:(UISwipeGestureRecognizer *) gr
{
    NSLog(@"right swipe worked");
    NSLog(@"right swipe array count is %d", [self.answerArray count]);

}

- (void)swipeLeft:(UISwipeGestureRecognizer *) gr
{
    NSLog(@"left swipe worked");
    NSLog(@"left swipe array count is %d", [self.answerArray count]);

}

抱歉,帖子太长了。再次,主要问题:如何在我的表视图函数中访问视图控制器的 NSMutablearray 属性?谢谢!


额外的技术相关问题/cmets...我重新编写了一个自定义 tableviewcontroller 类来加载这些数据并具有正确的大小和位置,然后在我的视图控制器中初始化这个 tableview 控制器类并将其视图作为子视图。但是我不想在两个视图控制器之间传递数据,因为我想尽可能干净地在视图上滑动来更新视图和子视图……但这可能是更好的方法吗?

还有两个相关的技术问题。首先,将这些信息填充到我可以从任何视图控制器访问的单例类中是否更有意义?其次,编写一些协议(还没有这样做,只是知道它)以在正确的位置传递信息强制重新加载是否更有意义?)作为一个新手,我认为这两个都比仅仅坚持更草率我正在尝试做一个视图控制器,但我可能还不太了解目标 c。提前致谢。

【问题讨论】:

  • NSLogs的结果是什么?
  • numberOfRowsInSection 中的 NSLog 打印“最近的整数计数为 0”。左右滑动 NSLogs 打印“左右滑动数组计数为 18”。 cellForRowAtIndex 中的 NSLog 从不打印。
  • 注意我也调用了 reloadData 三次。最初我调用了一次 - 如果问题是它没有执行,我不知道它为什么没有执行。
  • 您好像在给[tableView reloadData] 打了三次电话。您应该只在您的数据更改时调用它(即,在您设置 self.answerArray 之后)。尝试改用dispatch_sync 并将NSLog 放在您请求reloadData 的块中。此时answerArray的状态如何?
  • 好的,我重新编码如下 dispatch_sync(dispatch_get_main_queue(), ^{ NSLog(@"from dispatch before reload%@", self.answerArray[3]); [self.tableView reloadData]; NSLog (@"从重新加载后的调度 %@", self.answerArray[3]); }); }]; [数据任务恢复]; }` 两个 NSLog 都正确打印出数组成员,但表仍然是空的。

标签: ios objective-c uitableview subview


【解决方案1】:

您的 init 方法中有 UITableView *tableView = [[UITableView alloc] initWithFrame:frame];,因此 tableView 是一个局部变量。在其他地方你有 [self.tableView reloadData],但你从来没有将你的属性分配给 table view,所以 self.tableView 是 nil。您应该将 init 方法中的代码更改为,

        _tableView = [[UITableView alloc] initWithFrame:frame];
        _tableView.delegate = self;
        _tableView.dataSource = self;
        [self.view addSubview:_tableView];

【讨论】:

  • 就是这样。非常感谢!
  • @SunnysideProductions,您应该摆脱对 reloadData 的额外调用。您只需要 dispatch_async 块中的那个。此外,不需要“if ([self isKindOfClass:[UIViewController class]])”语句。在您的 cellForRowAtIndexPath 中,您应该使用常规方式使用 dequeueReusableCellWithIdentifier 获取单元格:。
  • 感谢您的意见!有一段时间对此感到困惑,我在想也许 init 和 didload 命令会转到 UITableView 并以这种方式搞砸,但我更好地理解了逻辑,现在明白你的意思是什么,这是不必要的。
猜你喜欢
  • 1970-01-01
  • 2020-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-08
  • 1970-01-01
  • 2018-07-14
  • 1970-01-01
相关资源
最近更新 更多