从 json 获取数据后将数据加载到 UILabels 和 UITextFields

Posted

技术标签:

【中文标题】从 json 获取数据后将数据加载到 UILabels 和 UITextFields【英文标题】:Load Data to UILabels and UITextFields after getting data from a json 【发布时间】:2017-10-25 18:55:53 【问题描述】:

我是 ios 开发和堆栈溢出的新手。我需要在多个 UILabel 和 UITextField 中显示用户的数据,数据是从 POST 方法中获取的。从服务器获取数据有一点延迟。获取详细信息后如何重新加载或填充元素。 这是我的 viewDidLoad()

@interface EditProfileViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *displayPictureView;
@property (weak, nonatomic) IBOutlet UITextField *firstnameFeld;
@property (weak, nonatomic) IBOutlet UITextField *lastNameField;
@property (weak, nonatomic) IBOutlet UITextField *emailField;
@property (weak, nonatomic) IBOutlet UITextField *bdayField;
@property (weak, nonatomic) IBOutlet UIButton *calField;
@property (weak, nonatomic) IBOutlet UITextView *addressTextView;
@property (weak, nonatomic) IBOutlet UILabel *userIDLabel;
@property (weak, nonatomic) IBOutlet UILabel *phoneNumberLabel;
@property (weak, nonatomic) IBOutlet UIScrollView *editScrollView;
@end

@implementation EditProfileViewController

- (void)viewDidLoad 
     [super viewDidLoad];

     self.editScrollView.delegate=self;

我使用代码从服务器接收数据,我在 viewDidLoad() 中有这个 POST 方法

NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject delegate: nil delegateQueue: [NSOperationQueue mainQueue]];
NSMutableURLRequest * urlRequest = [NSMutableURLRequest requestWithURL:urlEdit];
[urlRequest setHTTPMethod:@"POST"];
[urlRequest setHTTPBody:[editParameters dataUsingEncoding:NSUTF8StringEncoding]];
NSURLSessionDataTask * dataTask =[defaultSession dataTaskWithRequest:urlRequest
                                                   completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) 
     NSLog(@"Response:%@ \nError:%@\n", response, error);
     if(error == nil)
     
      NSString * text = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
      NSLog(@"DataText = %@",text);
      
      NSError *error2 = nil;
      jsonDicEditAcc = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error2];
      if (error2 != nil) 
             NSLog(@"Error parsing JSON.");
        
      else 
        NSLog(@"JsonDictEditAcc: \n%@",jsonDicEditAcc);

        [self dismissViewControllerAnimated:alert completion:nil];
         ];
[dataTask resume];

我将从“jsonDicEditAcc”中提取数据,我需要知道如何在获取数据后填充 UILabel 和 UITextField,因为在获取数据之前已加载视图。我试过 viewWillAppear() 没用。帮帮我..提前谢谢..

【问题讨论】:

有很多方法都取决于您的要求。您可以在初始时隐藏这些标签,并在加载数据时分配数据并显示标签,或者您可以使用任何活动指示器来显示正在发生的事情。 如何在收到数据之前隐藏标签并在之后加载 uielements..?? 【参考方案1】:

您需要知道您尝试应用的数据的内容。如果您知道与每个值关联的键,则可以将这些值应用于文本字段(以及标签和按钮)并完成。当您成功更新它们时,它们会发生变化。

在您的块内,您需要触发文本字段的填充。您可以添加如下内容:

      else 
    NSLog(@"JsonDictEditAcc: \n%@",jsonDicEditAcc);

    [self updateLabelsAndTextFields];

    [self dismissViewControllerAnimated:alert completion:nil];
     ];

此函数将从 jsonDicEditAcc 中提取数据并更新每个相关 UILabel 的文本。视图已经加载,但 UILabel 会在您更改文本时更新。

解决方案可能如下所示:

- (void)updateLabelsAndTextFields
    self.firstnameFeld.text = jsonDicEditAcc[@"key"];
    self.lastNameField.text = jsonDicEditAcc[@"key"];
    self.emailField.text = jsonDicEditAcc[@"key"];
    self.bdayField.text = jsonDicEditAcc[@"key"];
    self.userIDLabel.text = jsonDicEditAcc[@"key"];
   [calField setTitle:jsonDicEditAcc[@"key"] forState:UIControlStateNormal];



确保将 UIButton 命名为按钮,即“calButton”而不是“calField”

【讨论】:

【参考方案2】:

这很简单,将类似的代码添加到 if (error2 != nil) 语句的 else 分支:

weakSelf.firstnameFeld = jsonDicEditAcc[@"<key-for-firstname>"];

此外,您可能会发现有必要从该分支中​​删除此语句,因为它将关闭当前的 viewController:

[self dismissViewControllerAnimated:alert completion:nil];

我可能会指出,您需要在块内使用weakSelf 来防止内存泄漏。在块内使用 self 会创建一个保留周期,这意味着您的整个 viewController 将保持分配状态,直到 iOS 最终因过度使用内存而导致您的应用程序崩溃。

把它放在你的方法的顶部,它可以在块内访问,然后将块内的所有self引用更改为weakSelf。

typeof(self) __weak weakSelf = self;

【讨论】:

感谢您的快速响应.. 我有一个疑问,在我将数据加载到其中之前,不会加载 uielements 吗?导致获取数据略有延迟..如何再次重新加载元素?还是 _weak 变量在获取后会立即将数据直接加载到 uitextfields 中? 如果您从 viewDidLoad 或 viewWillAppear 调用调用 POST 请求的方法,则与您的插座的连接应该就位,并且按照建议更新它们应该没有问题。但仔细想想,完成块可能是从后台线程调用的,所以将 UI 更新包装在:a dispatch_async(dispatch_get_main_queue(), ^ );因为 UIKit 只能从主线程调用。

以上是关于从 json 获取数据后将数据加载到 UILabels 和 UITextFields的主要内容,如果未能解决你的问题,请参考以下文章

Swift 5:给定的数据不是有效的JSON(将数据从API加载到表格视图)

从 API 获取 JSON,将其添加到 sqlite3 数据库并自动获取下一页

节点 - 承诺后将 JSON 结果写入文件

在程序 c# 开始时加载 JSON 数据

如何在展平嵌套字段后将数据​​从一个 bigquery 表流式插入到另一个表?

应用更新后将 plist 加载到核心数据中