0

我正在尝试制作一个非常简单的 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

第二视图控制器.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。例如,我对合成的东西很困惑。

谢谢你的帮助!

4

1 回答 1

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对象。您可以使用单例执行此操作,但使用选项卡栏控制器应用程序,我可能会ModelUITabBarController子类中实例化(并确保在情节提要中使用此子类):

//  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

而已。

现在,如果该模型可以在第二个选项卡可见时发生更改,您还可以使用键值观察(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 可能不是必需的,但它在更复杂的应用程序中很有用,因此我将其包含在您的未来参考中。

于 2013-09-09T21:54:56.287 回答