使用 NSSet/allTargets 获取 xib 所谓的“文件所有者”?

Posted

技术标签:

【中文标题】使用 NSSet/allTargets 获取 xib 所谓的“文件所有者”?【英文标题】:Using NSSet/allTargets to get the xib so-called "File owner"? 【发布时间】:2013-12-05 08:42:55 【问题描述】:

查看这张图片,您可以看到从 nib 加载的 UIView 有一个“文件所有者”

在 xib 中注意,Apple 已将某些内容标记为“文件所有者”。

所以,打开 Xcode,打开任意 xib,查看 Placeholders,然后直接查看下方,即可看到:

“文件所有者”。

在这个特定示例中,“xib-file-owner”恰好是类 LoginScreen。

因此,在运行时,对于由此 xib 创建的特定事物,“was-xib-file-owner”(创造一个短语)实际上是:

它将是:LoginScreen 类的某个特定实例。

现在在运行时。显然,在 UIView 中,每个 UIButton 都可以简单地调用

[self.someButton sendActionsForControlEvents:UIControlEventTouchUpInside ];

你确实可以“去”,准确地说:

您转到:LoginScreen 类的实例

注意 - 当然,UIButton 可以指向任何地方。我问的是我们知道 UIButton 确实指向 UIButton 的“was-xib-file-owner”的情况。

事实上,allTargets 方法确实会返回该目标(在本例中是 LoginScreen 类的一些实例)作为它返回的 N 个目标的一部分,实际上是选择器(s) 等。

我还不够好,无法为 allTargets、NSSet 等编写代码。

谁能告诉我如何使用 allTargets 和一些计算机代码提取 LoginScreen 类的实例?即在 xib 中看到的“was-xib-file-owner”的运行实例?干杯。


稍后:

奇怪的是,这个问题的答案基本上和一般来说是:

[self.allTargets anyObject]

因为,如果从 xib 创建,将只有一个,而且,这正是上面粗体描述的内容。重复一遍:当然,UIButton 可以指向任何地方。我问的是我们知道 UIButton 确实指向 UIButton 的“was-xib-file-owner”的情况。

在那种(“正常”)情况下,答案确实非常简单——[self.allTargets anyObject]。

【问题讨论】:

为什么需要按钮的所有者? 您是指所有者还是容器? 有 N 个目标和 1 个超级视图... 0 个所有者 记录一下: giora:这是一个奇怪的问题,请注意苹果方法 sendActionsForControlEvents,例如,“需要”知道这一点。 anoop/daij:我的意思是“was-xib-file-owner”。当然,运行时没有“文件所有者”,所以我的意思是“was-xib-file-owner”。我已经编辑一遍又一遍地在问题中说明这一点,因为它可能会在未来帮助某人!干杯男人,真棒QA 【参考方案1】:

在运行时视图不知道文件所有者(如 IB 中所示)。有关文件所有者的信息不存在。你可以做的最接近的是检查目标的类:

    if([self respondsToSelector:@selector(allTargets)]) 
        NSSet *owners = self.allTargets;
                    for(id owner in owners) 
                        if([owner isKindOfClass:[UIViewController class]])
                           NSLog(@"owner: %@", owner);
                    
            

或者只是假设目标是所有者

    if([self respondsToSelector:@selector(allTargets)]) 
        id owner = [self.allTargets anyObject];
        NSLog(@"owner: %@", owner);
    

【讨论】:

再次:没有所有者,因为 Anoop 在他的回答中说:“文件的所有者只不过是一个代理,它在运行时获取类。” 不,运行时没有文件所有者...该信息不存在。 Danke .. 这个问题的实际答案基本上是:[self.allTargets anyObject],这很有趣! :) 你知道,我很好奇你为什么要检查 respondsToSelector ..? (如果是 UIButton,您可以调用 allTargets;问题是关于 UIButton。)您只是小心谨慎,还是有什么我不知道的?干杯! 小心点:防御性编程【参考方案2】:

实际上按钮没有“所有者”。

UIButton 是特定视图的子视图,在 IB 中,您将按钮拖动到某个视图中,然后该按钮成为该视图的子视图。要检索按钮的超级视图,请调用 [myButton superview];

然后可以将 Button 引用为某个类的属性或 iVar,但它是另一回事。

【讨论】:

不,我的意思是从库中将一个按钮拖到视图中。当您说“所有者”时,您指的是 IB 中显示的文件所有者?因此,它通常是 VC,也可以是视图。使用 NSSet,您可以使用 anyObject 方法访问一个随机对象,但我不确定这就是您要查找的内容。 @JoeBlow 没有这样的所有者【参考方案3】:

您有一个UIButton,它为某些控制事件附加了目标(通常是UIControlEventTouchUpInside)。

您可以按如下方式获取UIButton 的目标

NSSet *targets = [myButton allTargets];

for( NSObject *target in targets )

    //Do something with target

    //Maybe it's a view:
    if( [target isKindOfClass:[UIView class]] )
    
        //Do something to view specific target
    

需要注意两点:

目标不是UIButton 的“所有者”,也不需要是 UIView(如果我正确理解您的问题)。目标可以是任何对象,一般会从NSObject派生。

Interface Builder 中的“文件所有者”只是“拥有”笔尖的UIViewController(通常)的一个术语——它可能是也可能不是按钮的目标!

如果您确定您的按钮将您的文件所有者作为目标,那么您可以通过以下方式检查它(尽管我不建议这样编码):

//Assuming your File Owner is "LoginScreen" as in your picture
NSSet *targets = [myButton allTargets];

for( NSObject *target in targets )

    //Is the target our File Owner class type?
    if( [target isKindOfClass:[LoginScreen class]] )
    
        LoginScreen *login = (LoginScreen *)target

        //Do something with `login` 
    

更好的方法是递归检查 UIButton 的 nextResponder,直到您点击管理视图控制器。我还没有测试过以下代码,但它遵循文档:

UIResponder *responder = [myButton nextResponder];

while( [responder isKindOfClass:[UIViewController class]] == NO &&
       responder != nil )

    responder = [responder nextResponder];


//If your button is "owned" in the responder chain
// by a UIViewController, then `responder` will be it
// otherwise `responder` will be nil
if( responder )

    //Do something

但是,我不知道您为什么需要这样做。也许有更简单的解决方案来解决您的问题?

【讨论】:

Simeon,在您的代码示例二第 7 行中:** isKindOfClass:[LoginScreen class]** 我有两个难题:(A)您假设我的程序员知道它是 LoginScreen 类;没有更通用的解决方案吗? (即,我在问“对于 UIButton,如何确定 xib 上 FileOwner 的类是什么......”)。并且(B)可以匹配 LoginScreen 的“任何”实例(我相信?),我想找到实际的 LoginScreen(很可能是 UIViewController),它确实是那个 xib 的 FileOwner。有什么想法吗?! :) 更通用的解决方案可能是检查isKindOfClass:[UIViewController class],因为它会找到作为目标附加到按钮的任何视图控制器。我的解决方案的后半部分(使用nextResponder)将找到按钮的最近的视图控制器“父级” - 但是,它可能会或可能不会作为目标附加。 也许最好的答案是,如果您的程序员知道 UIButton 是 UIButton 的常见类型,那么确实 all 目标确实是实例-- the-FileOwnerClass:然后,只需在 Simeon 的代码的第 9 行取第一项(不管是哪一项).. 确实这就是答案。 (事实上​​,目标确实是通过加载 xib 并使用“FileOwner”这是由 xib-loader 理解/知道的创建的,这对于 UIView/UIButton 本身来说是完全未知的。)控件上没有标志'哦,这个目标恰好是从 xib/FileOwner 加载的。 simeon,虽然您是第一个了解并确实详细解释了情况的人,但由于他给出了结论性代码(我现在使用它!),因此单击“赏金”给 daij 似乎是合适的。的确,他事先已经在努力解决这个问题。我希望你们俩都没事。 (不能随心所欲地点击尽可能多的“赏金”,这是愚蠢的。)再次非常感谢你,Simeon!

以上是关于使用 NSSet/allTargets 获取 xib 所谓的“文件所有者”?的主要内容,如果未能解决你的问题,请参考以下文章

更改java包名称

使用 xi:include 将 JAXB 导出到模块化 xml 文件

如何获取矩阵二范数 opencv

苹果电脑使用acrobat xi pro怎么购买

使用 postgre 数据库配置水晶报表 XI 的问题

使用暹罗{(Xiānluó),泰国的旧称 one-shot} 网络进行人脸识别