我对iOS和Objective-C以及整个MVC范式都是新手,我一直坚持以下几点:
我有一个充当数据输入表单的视图,我想让用户选择多个产品。产品列在另一个具有UITableViewController的视图中,我已启用多个选项。
如何将数据从一个视图传输到另一个视图?我会将UITableView上的选择保存在一个数组中,但如何将其传递回上一个数据输入表单视图,以便在提交表单时将其与其他数据一起保存到核心数据?
我在网上冲浪,看到一些人在应用程序委托中声明了一个数组。我读了一些关于单态的东西,但我不明白这些是什么,我读了关于创建数据模型的东西。
正确的执行方式是什么?我将如何执行?
将数据从ViewController 2(目标)传递回ViewController 1(源)是更有趣的事情。假设你使用故事板,我发现了以下所有方法:
代表通知用户默认值辛格尔顿
这些已经在这里讨论过了。
我发现有更多的方法:
使用块回调:
在VC1的prepareForSegue方法中使用它
NextViewController *destinationVC = (NextViewController *) segue.destinationViewController;
[destinationVC setDidFinishUsingBlockCallback:^(NextViewController *destinationVC)
{
self.blockLabel.text = destination.blockTextField.text;
}];
使用故事板展开(退出)
在VC1中实现一个带有UIStoryboardSegue参数的方法,如下所示:
-(IBAction)UnWindDone:(UIStoryboardSegue *)segue { }
在故事板中,将“返回”按钮挂在vc的绿色退出按钮(展开)上。现在您有了一个“返回”的segue,因此您可以使用VC2的prepareForSegue中的destinationViewController属性在返回之前更改VC1的任何属性。
使用故事板的另一种选择Unwind(退出)-您可以使用在VC1中编写的方法-(IBAction)UnWindDone:(UIStoryboardSegue*)segue{NextViewController*NextViewController=segue.sourceViewController;self.unindLabel.text=nextViewController.undPropertyPass;}
在VC1的prepareForSegue中,您可以更改您想要共享的任何属性。
在两个展开选项中,您都可以设置按钮的标记属性,并在prepareForSegue中进行检查。
如果您想将数据从一个viewController发送到另一个viewController,请使用以下方法:
假设我们有viewControllers:viewControllerA和viewControllerB
现在在文件视图ControllerB.h中
@interface viewControllerB : UIViewController {
NSString *string;
NSArray *array;
}
- (id)initWithArray:(NSArray)a andString:(NSString)s;
在文件视图ControllerB.m中:
#import "viewControllerB.h"
@implementation viewControllerB
- (id)initWithArray:(NSArray)a andString:(NSString)s {
array = [[NSArray alloc] init];
array = a;
string = [[NSString alloc] init];
string = s;
}
在文件视图ControllerA.m中:
#import "viewControllerA.h"
#import "viewControllerB.h"
@implementation viewControllerA
- (void)someMethod {
someArray = [NSArray arrayWithObjects:@"One", @"Two", @"Three", nil];
someString = [NSString stringWithFormat:@"Hahahahaha"];
viewControllerB *vc = [[viewControllerB alloc] initWithArray:someArray andString:someString];
[self.navigationController pushViewController:vc animated:YES];
[vc release];
}
因此,这就是在不设置任何委托的情况下将数据从viewControllerA传递到viewControllerB的方法。;)
这里有一个更简单的方法。
只需使用全局变量。声明传递给下一个类所需的对象或变量。
例如,我们有两个类-类A和类B。
在类A中,通常包含:
#import "classA.h"
@interface classA()
@end
@implementation classA
-(void)viewDidLoad
{
...
}
-(void)didReceiveMemoryWarning
{
...
}
B类包含:
#import "classB.h"
@interface classB()
@end
@implementation classB
-(void)viewWillLoad
{
...
}
-(void)didReceiveMemoryWarning
{
...
}
现在,将第二个类classB导入classA:
#import "classA.h"
#import "classB.h" // --- Import classB to classA.
@interface classA()
@end
@implementation classA
-(void)viewDidLoad
{
...
}
-(void)didReceiveMemoryWarning
{
...
}
现在我们有一座桥去二等B班。现在,要将变量或对象声明为全局变量,请在第一个类的.m文件中声明它,如下所示:
在A.h类中
#import "classA.h"
#import "classB.h"
@interface classA()
@end
NSString *temp; // ---- Declare any object/variable as global.
@implementation classA
-(void)viewDidLoad
{
...
temp=@"Hello";
...
}
-(void)didReceiveMemoryWarning
{
...
}
这里,对象temp是NSString类的全局对象。要访问任何类中的全局对象或变量,只需在第二个类中重新声明对象或变量。例如,如下所示:
在B.m类中
#import "classB.h"
@interface classB()
@end
extern NSString *temp; //----use `extern` keyword for using the global object/variable in classB that was declared in classA.
@implementation classB
-(void)viewDidLoad
{
...
LabeL.text=temp;
...
}
-(void)didReceiveMemoryWarning
{
...
}
现在,第二个类可以访问该值。易于理解的此方法可用于任意数量的类。
注:
您应该将第二个类的.h文件导入到第一个类。但不需要进口将第一类的.h文件转换为第二类。
记住那座桥。如果有一座桥,它应该可以从两边走。