如何从另一个对象访问我的应用程序代理的窗口访问方法?

12

如前所述-我是一个Objective-C的新手,虽然已经阅读了4本纸质书和大量电子书籍和文档,但仍然找不到我要寻找的内容。

我有一个顶级内容视图控制器,它想要通过应用程序委托的窗口属性的物理尺寸来配置其视图属性。这是一些人已经提出问题的事情。(在这个论坛上已经多次提到过的原因,[UIScreen mainScreen]不能满足要求)。因此,逻辑方法是让内容视图控制器读取应用程序委托的窗口的frame。现在,我找到的唯一接近此的答案是使用 [[[UIApplication sharedApplication] window] frame] - 但这只有在window属性被设置为keyAndVisible后才有效。内容视图控制器需要在它达到makeKeyAndVisible之前读取应用程序委托的window属性。代码按照以下顺序执行...

应用委托:

- (BOOL) application: (UIApplication *) application didFinishLaunchingWithOptions: (NSDictionary *) launchOptions {
// This next line is a test window frame for R&D purposes....
    [self setWindow: [[UIWindow alloc] initWithFrame: CGRectMake(0.0f, 20.0f, 320.0f, 320.0f)]];

    if ([self window]) {
        contentViewController = [[ContentViewControl alloc] initWithNibName: nil bundle: nil]; // Content view controller instantiated here

        if (contentViewController) {
            [[self window] addSubview: [contentViewController view]];
            [[self window] layoutSubviews];
            [[self window] makeKeyAndVisible];  // Window made key and visible here
            return YES;
        }
    }

    return NO;
}

在我的内容视图控制器的 initWithNibName: nil bundle: nil 方法中,我有以下测试代码...

- (id) initWithNibName: (NSString *) nibNameOrNil bundle: (NSBundle *) nibBundleOrNil {
    self = [super initWithNibName: nibNameOrNil bundle: nibBundleOrNil];

    if (self) {
        NSLog(@"%@", NSStringFromCGRect([[[UIApplication sharedApplication] keyWindow] frame]));
        // This does not work.
    }

    return self;
}

由于AppDelegate的窗口尚未成为关键并且可见,因此这不起作用。因此,我的问题是:我的App Delegate类的实例的名称是什么?我知道App Delegate的Class名称默认为myApplicationNameAppDelegate,但我想知道实例的名称。我想把对[[UIApplication sharedApplication] keyWindow]的调用替换为类似于以下内容的东西;

[myAppDelegatesInstanceName window].

稍微扩展一下,如何访问不是查询对象作用域后代的其他目标对象中的方法?

像我说的,我完全不懂这方面的知识,这可能是另一个愚蠢的新手问题,但似乎没有人以简单的方式回答它。

(在过程化编程中 - 我的专业领域 - 有大量的方法可以将窗口内容传递到其他级别的作用域,从使窗口全局可访问到整个程序套件,到通过各种函数层次结构将其作为特定参数传递 - 但这种Objective-C的做法似乎与已经确立的过程化实践不同)。

如果有人能帮忙,我会非常感激。这些东西绝对不直观!V.V.

3个回答

22
你可以通过单例的UIApplication实例来访问应用程序委托:
[[[UIApplication sharedApplication] delegate] window];

这是一个特殊情况,因为您可以访问一个对象(UIApplication 实例),其委托是您想要访问的对象。一般情况:

更进一步地说,如何访问不属于执行查询操作的对象范围后代的其他目标对象中的方法?

您需要向想要访问该对象的对象传递对目标对象的引用。尽管有时这是必要的,但它也意味着您会在这两个对象之间引入紧密耦合,通常情况下应该尽量避免。因此,请仔细考虑每种情况,看看是否有其他可能的设计方案。


谢谢Ole的快速回复!我会尝试一下。 - VectorVictor
抱歉看起来我有点笨,Ole,但我仍然没有得到任何乐趣。如果我正确理解了你的答案,我的构造应该像下面这样:[[(NumicatorAppDelegate *)[[UIApplication sharedApplication] delegate] window] frame]。这是正确的吗? - VectorVictor
1
是的。你收到了错误吗?你还需要 #import NumicatorAppDelegate.h - Ole Begemann

6

Swift 3

    if let window = NSApplication.shared().windows.first {
        // access window. properties now
    }

我认为你的意思是 UIApplication.shared.windows.first - thecloud_of_unknowing

3
使用此代码来处理 Swift 相关的技术问题:
let window:UIWindow? = (UIApplication.sharedApplication().delegate?.window)!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接