将从核心数据中获取的数据分配给 UIPickerView

Posted

技术标签:

【中文标题】将从核心数据中获取的数据分配给 UIPickerView【英文标题】:assign fetched data from core data to UIPickerView 【发布时间】:2013-07-23 09:19:13 【问题描述】:

我已经搜索了所有堆栈溢出,但没有任何答案能真正帮助我解决我的问题,尽管这似乎很容易。

我有一个应用程序,其中包含一个存储字符串的实体。我可以很好地存储它们并在 UITableView 中获取它们,但有时我需要获取它们并将它们放在 UIPickerView 中。 这是我的课程,其中是 UIPickerView。 就像在模态视图中一样,有一个委托可以带回父视图中的数据,但这很好用。 头文件:

#import <UIKit/UIKit.h>


@protocol TextChoiceDelegate <NSObject>
- (void) takeBackViewController:(id)controller didFinishSelectingText:(NSString *)text;
@end

@interface ChooseTextViewController : UIViewController
<UIPickerViewDelegate, UIPickerViewDataSource> 
    UIPickerView *pickerView;
    NSMutableArray *list;


@property (nonatomic, assign) id <TextChoiceDelegate> delegate;
@property (strong, nonatomic) IBOutlet UIPickerView *pickerView;
@property (strong, nonatomic) NSString *text;

- (IBAction)didFinishChoosingText:(id)sender;

@end

还有.m文件:

#import "ChooseTextViewController.h"

@interface ChooseTextViewController ()
@property (strong) NSMutableArray *list;
@end


@implementation ChooseTextViewController

@synthesize delegate;

@synthesize pickerView;
@synthesize list;
@synthesize text;


#pragma mark - IBActions

- (IBAction)didFinishChoosingText:(id)sender

    NSString *textToPassBack = text;
    NSLog(@"returning: %@", textToPassBack);
    [self.delegate takeBackViewController:self didFinishSelectingText:textToPassBack];

    [self dismissViewControllerAnimated:YES completion:NULL];


#pragma mark - UIPickerViewDataSource methods

// Number of components in the pickerView
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView

    return 1;


// Number of elements in the pickerView component
- (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent: (NSInteger)component

    return [self.list count];


- (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component

    return [self.list objectAtIndex:row];



#pragma mark - PickeView delegate methods

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component

    NSLog(@"Selection of element: %@", [self.list objectAtIndex:row]);
    text = [self.list objectAtIndex:row];



#pragma mark - View Controller LifeCycle

- (void)viewDidLoad

    [super viewDidLoad];
// Do any additional setup after loading the view.
    /*
    list = [[NSMutableArray alloc] init];
    [list addObject:@"1"];
    [list addObject:@"2"];
    [list addObject:@"3"];
    [list addObject:@"4"];
    [list addObject:@"5"];
     */


- (void)viewDidAppear:(BOOL)animated

    [super viewDidAppear:animated];
    self.list = [[NSMutableArray alloc] init];

    NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"LolText"];

    self.list = [[managedObjectContext executeFetchRequest:fetchRequest error:nil] mutableCopy];



#pragma mark - Core Data Stack Methods

- (NSManagedObjectContext *)managedObjectContext

    NSManagedObjectContext *context = nil;
    id localDelegate = [[UIApplication sharedApplication] delegate];
    if ([localDelegate performSelector:@selector(managedObjectContext)]) 
        context = [localDelegate managedObjectContext];
    
    return context;


@end

当我运行它时,pickerView 显示为空,一旦我单击它,应用程序就会崩溃并显示以下错误日志: 2013-07-23 10:51:55.010 MemeGen[51428:c07] *-[UITableViewRowData rectForRow:inSection:]、/SourceCache/UIKit_Sim/UIKit-2380.17/UITableViewRowData.m:1630 中的断言失败 2013-07-23 10:51:55.012 MemeGen[51428:c07] 由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“在无效索引路径(2 个索引)处请求 rect [0, 0])' ** 首先抛出调用堆栈: (0x22bb012 0x16e5e7e 0x22bae78 0xe6b665 0x502f20 0x3c62de 0x756086 0x755f7a 0x37940d 0x37b9eb 0x5e485a 0x5e399b 0x5e50df 0x5e7d2d 0x5e7cac 0x5dfa28 0x34c972 0x34ce53 0x32ad4a 0x31c698 0x264fdf9 0x264fad0 0x2230bf5 0x2230962 0x2261bb6 0x2260f44 0x2260e1b 0x264e7e3 0x264e668 0x319ffc 0x27ad 0x26d5) libc++abi.dylib:终止调用抛出异常

出于测试目的,当我运行 viewDidLoad 方法的注释部分(注释所有关于 cora 数据的内容)时,它工作正常。 如果我将 viewDidAppear 中的代码放在 viewDidLoad 中,一旦 viewController 出现在屏幕上就会崩溃

我觉得我离真相不远了,但我找不到出路。 请问有人可以帮我吗?

【问题讨论】:

首先检查您分配的核心数据的值是什么,并保持警惕 UIPicker View 的委托方法 我会努力回来的... 好的,那么如果我使用 UIPickerView 直接进入 viewController 我获得:2013-07-23 16:59:50.175 MemeGen[45906:c07] 列表元素: ( entity: LolText; id: 0xc03bac0 ; data: ) 如果先去 UITableView 然后去 PickerView 我得到: 2013-07-23 17:03:03.662 MemeGen [46266:c07] 列表元素:(实体:LolText;ID:0x1046e9c0 ; data: text = "TEST LOLTEXT"; ) 但它仍然崩溃 我也将不得不再次处理这个问题.. 【参考方案1】:

这是因为您的 Pickerview 没有行,这就是系统崩溃的原因。

您可以检查您的列表是否提供数据?如果是,那么应该没有问题。

检查是否没有数据然后不要打开pickerview。

【讨论】:

你好,我不确定我是否理解你的问题。如果我手动设置列表的内容,它工作得很好。此外,我有一个 UITableViewController 可以很好地显示核心数据的数据。这应该意味着它不是空的,不是吗?还是我错过了你的意思? 认为您可能指的是 Ashutosh Mishra 之类的东西,我记录了列表的内容,它正在提供数据。但我确实遇到了崩溃,屏幕上出现了一个空的选择器视图,以及我在开篇文章中写的日志。【参考方案2】:

嗯,最后我更改了我的大部分代码,并且它在一定程度上起作用。现在最大的问题是,当我想将 UIPickerView 返回的值用作字符串时,这是不可能的,我被一个类型的值卡住了:NSKnownKeysDictionary1。

这是有问题的部分,但我找不到获取简单字符串的方法。

- (void)viewDidLoad

    [super viewDidLoad];
    // Do any additional setup after loading the view.
    // Core Data
    if (_managedObjectContext == nil)
    
        _managedObjectContext = [(AppDelegate *)[[UIApplication sharedApplication] delegate] managedObjectContext];
    

    NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"LolText"];

    NSEntityDescription *entity = [NSEntityDescription entityForName:@"LolText" inManagedObjectContext:_managedObjectContext];
    request.resultType = NSDictionaryResultType;
    request.propertiesToFetch = [NSArray arrayWithObject:[[entity propertiesByName] objectForKey:@"text"]];
    request.returnsDistinctResults = YES;


    _list = [[_managedObjectContext executeFetchRequest:request error:nil] mutableCopy];

    for (id key in _list) 
        NSLog(@"class of %@ = %@", key, [key class]);
        NSLog(@"string: %@", (NSString *)[[_list objectAtIndex:1] allValues]);
    

    NSLog (@"texts: %@",_list);

这里是日志:

2013-07-23 22:23:16.178 MemeGen[79886:c07] class of 
    text = "MY TEST LOLTEXT";
 = NSKnownKeysDictionary1
2013-07-23 22:23:16.178 MemeGen[79886:c07] string: (
    "MY TEST LOLTEXT!"
)

我将它转换为 NSString 的事实并不能解决问题。每次我使用 NSString 方法时,我总是以相同的“无法识别的选择器错误”结束,例如:

2013-07-23 22:38:06.497 MemeGen[80800:c07] -[NSKnownKeysDictionary1 stringByReplacingCharactersInRange:withString:]: 无法识别的选择器发送到实例 0x94e0a60 2013-07-23 22:38:06.498 MemeGen[80800:c07] * 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[NSKnownKeysDictionary1 stringByReplacingCharactersInRange:withString:]: 无法识别的选择器发送到实例 0x94e0a60'

有没有办法在从核心数据中获取数据时不获取 NSKnownKeysDictionary1?

【讨论】:

【参考方案3】:

哈!终于做到了!问题在于方法中:

- (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component

我是这样分配我的 NSString 的:

_text = [self.list objectAtIndex:row];

但正确的分配方式是:

_text = _list[row][@"text"];

问题解决了! 感谢您的帮助。

【讨论】:

以上是关于将从核心数据中获取的数据分配给 UIPickerView的主要内容,如果未能解决你的问题,请参考以下文章

为啥我不能将从 Firestore 获取的值分配给 Swift 中的数组?

如何将从核心数据获取的数据发送到另一个 VC?

如何将从 API 获取的数组分配给 Vue.js 中的数据属性?

swift 3 - 核心数据关系 - 获取数据

如何将从核心数据加载的数据保存在数组中?

核心数据 - 如何将核心数据中的属性值分配给变量