iOS:在独立视图控制器上将int传递给标签

时间:2013-09-09 21:04:57

标签: ios int

我正在尝试创建一个非常简单的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。例如,我对合成的东西很困惑。

感谢您的帮助!

1 个答案:

答案 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可能没有必要,但它在更复杂的应用程序中很有用,所以我将它包括在内以供将来参考。