我正在尝试创建一个非常简单的iOS应用程序,它有两个按钮:一个+1和一个-1,然后在一个单独的选项卡上,一个标签将显示总数。我一直在阅读关于如何在视图控制器之间传递数据的最后一小时,但它对我没有任何意义。我是完整的iOS新手。这是我的代码:
FirstViewController.h:
#import <UIKit/UIKit.h>
@interface FirstViewController : UIViewController
- (IBAction)takeOne:(id)sender;
- (IBAction)addOne:(id)sender;
@end
FirstviewController.m:
#import "FirstViewController.h"
#import "SecondViewController.h"
@interface FirstViewController ()
@end
@implementation FirstViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)takeOne:(id)sender {
SecondViewController.counter--;
[label setText:[NSString stringWithFormat:@"%d", counter]];
}
- (IBAction)addOne:(id)sender {
SecondViewController.counter++;
[label setText:[NSString stringWithFormat:@"%d", counter]];
}
@end
SecondViewController.h
#import <UIKit/UIKit.h>
@interface SecondViewController : UIViewController
@property (nonatomic) int counter;
@property (weak, nonatomic) IBOutlet UILabel *label;
@end
SecondViewController.m
#import "SecondViewController.h"
@interface SecondViewController ()
@end
@implementation SecondViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
@end
在FirstViewController.m中,XCode告诉我错误“在'SecondViewController'类型的对象上找不到”属性'计数器',并且“使用未声明的标识符'标签'”。
我感到困惑的部分原因是,有很多信息似乎适用于旧版本的iOS。例如,我对合成的东西很困惑。
感谢您的帮助!
答案 0 :(得分:0)
您的增量(SecondViewController.counter++
)和减量(SecondViewController.counter--
)引用了类名SecondViewController
,但如果您要这样做,则必须引用该特定的实例要增加/减少的类。
但就个人而言,我不喜欢视图控制器尝试更新另一个视图控制器中的其他内容。视图控制器应仅更新(a)其视图; (b)该模型。然后,另一个视图控制器应该观察模型上的更改并反映UI中的更改。
所以,我们假设您有模型类:
// Model.h
#import <Foundation/Foundation.h>
@interface Model : NSObject
@property (nonatomic) NSInteger counter;
@end
和
// Model.m
#import "Model.h"
@implementation Model
- (id)init
{
self = [super init];
if (self) {
_counter = 0;
}
return self;
}
@end
并实例化一个Model
对象。您可以使用单例,但使用标签栏控制器应用程序,我可以在Model
子类中实例化UITabBarController
(并确保在故事板中使用此子类):
// TabBarController.h
#import <UIKit/UIKit.h>
#import "Model.h"
@interface TabBarController : UITabBarController
@property (nonatomic, strong) Model *model;
@end
和
// TabBarController.m
#import "TabBarController.h"
@implementation TabBarController
- (id)initWithCoder:(NSCoder *)aDecoder
{
self = [super initWithCoder:aDecoder];
if (self) {
_model = [[Model alloc] init];
}
return self;
}
@end
然后第一个选项卡的视图控制器可以有递增和递减按钮来更新模型:
// FirstViewController.m
#import "FirstViewController.h"
#import "TabBarController.h"
@implementation FirstViewController
- (IBAction)didTouchUpInsideDecrementButton:(id)sender
{
Model *model = [(TabBarController *)self.parentViewController model];
model.counter--;
}
- (IBAction)didTouchUpInsideIncrementButton:(id)sender
{
Model *model = [(TabBarController *)self.parentViewController model];
model.counter++;
}
@end
当视图出现时,第二个视图控制器可以从模型中检索当前值并显示它:
// SecondViewController.m
#import "SecondViewController.h"
#import "TabBarController.h"
@implementation SecondViewController
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
Model *model = [(TabBarController *)self.parentViewController model];
self.label.text = [NSString stringWithFormat:@"%d", model.counter];
}
@end
就是这样。
现在,如果在第二个选项卡可见时该模型可能正在更改,您还将使用Key-Value-Observing(KVO),在这种情况下,您的第二个视图控制器将在模型更改时得到通知。坦率地说,您描述的UI并不是必需的,但是如果您在第二个视图控制器可见且您希望在UI中反映这些更改时异步更新模型,那么KVO就是解决方案:
// SecondViewController.m
#import "SecondViewController.h"
#import "TabBarController.h"
@implementation SecondViewController
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
Model *model = [(TabBarController *)self.parentViewController model];
self.label.text = [NSString stringWithFormat:@"%d", model.counter];
// also observe any changes to the model while the second view controller is visible
[model addObserver:self forKeyPath:@"counter" options:NSKeyValueObservingOptionNew context:nil];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
// if this view isn't visible, we don't need to observe the model any more
Model *model = [(TabBarController *)self.parentViewController model];
[model removeObserver:self forKeyPath:@"counter"];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
NSLog(@"%s", __FUNCTION__);
Model *model = [(TabBarController *)self.parentViewController model];
self.label.text = [NSString stringWithFormat:@"%d", model.counter];
}
@end
坦率地说,基于你到目前为止所描述的内容,KVO可能没有必要,但它在更复杂的应用程序中很有用,所以我将它包括在内以供将来参考。