从另一个类调用方法无法正常工作

时间:2013-12-30 18:37:00

标签: ios iphone class methods uiviewcontroller

我正在尝试从另一个班级更改文本和UILabel的位置。

我已成功设法从我的SecondViewController类调用我的-changeLabel方法,该方法位于我的FirstViewController类中。这是我在两个类中使用的代码:

SecondViewController:

#import "FirstViewController.h"

@interface SecondViewController ()
@property (nonatomic,strong) FirstViewController *firstViewController;
@end

@implementation SecondViewController
@synthesize firstViewController;

- (IBAction)button:(id)sender {
    firstViewController = [[FirstViewController alloc] init];
    [firstViewController changeLabel];
}

FirstViewController:

- (void)changeLabel {
    NSLog(@"changeLabel is called!");
    label.text = @"New text.";
    label.frame = CGRectMake(10, 100, 150, 40);
    NSLog(@"%@", label.text);
    NSLog(@"%f", label.frame.size.width);
}

奇怪的是,在按下调用方法的“按钮”后,记录器看起来像这样:

"2013-12-30 19:24:50.303 MyApp[655:70b] changeLabel is called!"
"2013-12-30 19:24:50.305 MyApp[655:70b] New text."
"2013-12-30 19:24:50.308 MyApp[655:70b] 0.000000"

所以看起来标签文字发生了变化,但它并没有出现在屏幕上。标签宽度记录为0.0 ..即使我只是将其设置为150。

为什么会这样?我无法从另一个类更改帧变量吗?还有另一种方法吗?

重要:

由于FirstViewController是主视图控制器,而SecondViewController是侧边菜单,类似于Facebook应用程序:

enter image description here

我希望能够按下SecondViewController(侧边菜单)上的“按钮”并调用FirstViewController(主要)中改变{{{1}位置(框架)的方法1}}。

编辑:

以下是我创建UILabel的方法:

UILabel

4 个答案:

答案 0 :(得分:1)

我认为问题是这样的。您正在从FirstViewController的新实例调用方法。

假设

1. FirstViewController at stack[0].
2. SecondViewController at stack[1].

如果您正在导航或从

移动

FirstViewController->SecondViewController

在这种情况下FirstViewController已经在内存中,地址为0x23ffff

SecondViewController中,您再次创建FirstViewController的新实例,该实例指向另一个地址'0x234jurhu`

- (IBAction)button:(id)sender {
    firstViewController = [[FirstViewController alloc] init];
    [firstViewController changeLabel];
}

请勿在此处创建新实例。

您可以使用delegateNSNotification概念。

答案 1 :(得分:1)

您如何展示FirstViewController

问题在于:

firstViewController = [[FirstViewController alloc] init];
[firstViewController changeLabel];

您创建FirstViewController的新实例并更新标签文本。如果您在导航堆栈中使用这些VC并从SecondViewController弹回FirstViewController,则不会看到任何标签更改,因为they是该类的不同实例。

如果你使用FirstViewController作为SecondViewController的childViewController(用它们命名我不认为这是你做的),那么在- (IBAction)button:(id)sender方法中你不需要在按下每个按钮时实例化FirstViewController的新实例。

答案 2 :(得分:1)

由于“@Gaurav Wadhwani”在这个问题上回答了call method from other class (self issue),我已经想出办法来做到这一点。

我在FirstViewController.h

中添加了此代码
+ (FirstViewController *)singletonInstance;

然后在我的FirstViewController.m

中添加了此代码
static FirstViewController  *_singletonInstance = nil;


+(FirstViewController*)singletonInstance
{
    @synchronized([FirstViewController class])
    {
        if (!_singletonInstance)
            _singletonInstance = [[self alloc] init];
        return _singletonInstance;
    }

    return nil;
}


+(id)alloc
{
    @synchronized([FirstViewController class])
    {
        NSAssert(_singletonInstance == nil, @"Attempted to allocate a second instance of a singleton.");
        _singletonInstance = [super alloc];
        return _singletonInstance;
    }

    return nil;
}

然后我在SecondViewController中添加了此代码以运行changeLabel方法:

[[FirstViewController singletonInstance] changeLabel];

到目前为止,这似乎工作得很好。我希望它在将来不会引起任何其他“问题”,但现在它似乎是完美的。

答案 3 :(得分:-2)

尝试这样做:

[label setNeedsDisplay];

changeLabel的最后一行之后。