【问题标题】:How to access values from a different UIViewController如何从不同的 UIViewController 访问值
【发布时间】:2013-05-28 17:51:44
【问题描述】:

如何从位于第二个 viewController 中的 inputField 访问值?

第二个视图控制器的类名是SettingsViewController,inputField的出口名是setRateInput

我试过了,但是没用……

double taxRateFromInput = [[self.settings.setRateInput text]doubleValue];

当我 NSLog 出来时,值为:(null)

知道我做错了什么吗?

这里是主视图控制器的实现文件:

#import "SettingsViewController.h"

@interface ViewController ()

@property (strong, nonatomic) SettingsViewController * settings;

@end

@implementation ViewController

// lazy instantiation 
-( SettingsViewController *) settings
{
    if (_settings == nil) {
        _settings = [[SettingsViewController alloc]init];
    }
    return _settings;
}


- (IBAction)calculatePrice:(id)sender {


    double taxRateFromInput = [[self.settings.setRateInput text]doubleValue];

@end

【问题讨论】:

  • _settings.setRateInput 而不是 self.settings.setRateInput?
  • 您正在实例化一个新设置,您必须调用原始设置。是设置父母吗?层次结构如何?

标签: iphone ios objective-c uiviewcontroller


【解决方案1】:

理论上,您可以创建一个全局变量。创建一个新类,将其命名为 taxRate(.h 和 .m)之类的名称

在 taxRate.h 中,添加以下代码:

#import <Foundation/Foundation.h>
@class MyTaxRate;

@interface TaxRate : NSObject {


}

@property (nonatomic, retain) double * taxRateFromInput;

+(TaxRate*)getInstance;

@end

然后,在您的控制器中,将“#import taxRate.h”放在那里。在您的 .m 文件中,添加以下内容:

#import "TaxRate.h"

@implementation TaxRate


@synthesize taxRateFromInput;

static TaxRate *instance =nil;  

+(TaxRate *)getInstance
{
    @synchronized(self)
    {
        if(instance==nil)
        {         
            instance= [TaxRate new];
        }
    }
    return instance;
}


@end

注意:这是extremely similar 在结构上符合我的目的。

【讨论】:

    【解决方案2】:

    如果你有来自对象视图控制器的引用,你可以通过你的属性的属性来访问。

    【讨论】:

      【解决方案3】:

      你实例化了一个新的SettingsViewController,但你没有做任何事情来实例化它的文本字段setRateInput。实例化的时候就可以了:

      _settings = [[SettingsViewController alloc]init];
      _settings.setRateInput = [UITextField alloc] initWithFrame:someFrame]];
      

      或者,作为更好的解决方案,实例化 -initSettingsViewController 中的文本字段

      - init {
        if (self = [super init] {
          self.setRateInput = [UITextField alloc] initWithFrame:someFrame]];
        }
        return self;
      }
      

      如果你使用 nib 文件,这会容易很多。

      注意:setRateInput 是一个不好的属性名称。请考虑使用rateTextField

      编辑我忘了补充一点,您必须将文本字段作为子视图添加到其父视图。

      所以它会像,

      _settings = [[SettingsViewController alloc]init];
      _settings.setRateInput = [[UITextField alloc] initWithFrame:someFrame] autorelease];
      [_settings.view addSubView:_settings.setRateInput];
      

      在这种情况下,setRateInput 由其超级视图保留。您没有使用 ARC,因此您可以在文本字段中调用 autorelease

      更好的解决方案:SettingsViewController 中使用- (void) loadView;。加载视图是对应视图控制器的职责。

      - (void) loadView {
          self.setRateInput = [[UITextField alloc] initWithFrame:someFrame] autorelease];
          [self.view addSubView:_settings.setRateInput];
      }
      

      编辑: xib filesstoryboards 可以帮助您。试试这些教程。

      【讨论】:

      • 当我实例化 textField 时,我收到一条警告,上面写着 Assigning reserved object to weak property;分配后对象将被释放知道这是什么吗? -( SettingsViewController *) settings { if (_settings == nil) { _settings = [[SettingsViewController alloc]init]; _settings.setRateInput = [[UITextField alloc]initWithFrame:CGRectMake(10, 20, 200, 20)]; } 返回_设置; }
      • setRateInput 的属性在SettingsViewController 中定义为weakalloc 返回一个保留对象。将其更改为retain
      • 非常感谢您的帮助和链接。 RAYWENDERLICH.com 好像有很好的教程,你用过他们的书吗?如果是,你会推荐他们吗?
      【解决方案4】:

      你在正确的轨道上,你的懒惰实例化也做得很好(如 我的意思是你掌握了这个概念的演示)。

      但请注意,在调用 viewDidLoad 之前,插座不会连接。所以如果你 只是分配/初始化你的viewController(懒惰地),你的文本字段的出口指向nil。 在访问控制器的视图属性之前,插座不会连接,即显示视图。

      你可以做的是给设置 viewController 一个句柄来处理你的计算 viewController 并让它在计算 viewController 上设置一个公共属性来表示速率。 这是一种常见的模式 - 委托 - 其中一个 viewController (settingsViewcontroller) 在其委托上调用一个方法(计算 viewController)。

      然后,您不需要在计算 viewController 中设置 settingsViewcontroller 属性,而只需在每次您希望它被调出时实例化一个新的设置 viewController,并为其提供对计算 viewController 的引用。

      另一种可能性——也许更好——是定义一个模型对象来进行计算并处理它需要计算的速率。然后你可以给你的 settingsViewcontroller 一个对该模型对象的引用(可能在你的 其他 viewController),以便它可以更改速率。

      PS:还要重新考虑一下您通常如何实例化视图控制器。指定的初始化程序是-initWithNibName:bundle: - 所以通常,你不会只分配/-init 他们。 如果您使用故事板(您可能应该!),请使用故事板的-instantiateViewControllerWithIdentifier: 或使用上面提到的指定初始化程序。

      【讨论】:

      • 感谢您的回复。我想有一些编程概念我仍然不明白,我认为一旦你导入并实例化了一个类,你就可以完全访问它的公共 API,但显然有些东西我仍然不明白。你知道我在哪里可以阅读更多关于这个概念的信息以便更好地理解吗?
      • 我总是推荐观看斯坦福的 cs193p 课程 - 可通过 iTunes U 获得
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多