如何为控件指定名称并在事件方法中检索它?

时间:2008-12-11 13:18:52

标签: objective-c cocoa-touch interface-builder

我有一个IBAction,例如:

- (IBAction)showPicker:(id)sender;

如何从sender变量中获取控件的名称?

我通常是一个c#编码器,所以尝试了以下无效

senderName = ((UIButton *)sender).name;

我需要比控件ID更具描述性的东西(也不是按钮标题)。我有5个按钮都调用相同的方法。我需要确定单击哪个以便在适当的控件上执行方法操作。 I.E我有一个地址选择器方法,但想要用5个按钮中的每一个填充5个不同细节的文本字段。只是试图保持代码整洁

N.B最初我打算使用Interface Builders名称字段,但我已被告知(如下所示)这在运行时不可用。

6 个答案:

答案 0 :(得分:5)

您可能希望查看使用标记属性。它是整数而不是名称,但可用于区分两个控件。它是从UIView继承的,所以任何发送事件的控件都应该拥有它。

它可以在Interface Builder下的Interface Builder中编辑。

它是一个属性,因此可以使用点表示法以编程方式访问它:

control.tag

或者您可以按如下方式转换为字符串:

[stringWithFormat:@"%d", control.tag]

答案 1 :(得分:3)

您不使用Interface Builder中的对象名称来引用该对象;它只是供参考。 (Interface Builder还将使用它作为连接到控件的出口和控件发送的操作可能被命名的提示,但仅作为提示。)

而是将插座添加到连接到对象的控制器对象。这使您可以在运行时直接从控制器访问对象,而无需执行任何查找步骤。

此外,听起来你有五个按钮,有五个要做的事情,都连接到同一个动作方法。不要那样做。

在Cocoa和Cocoa Touch中,您通常不应该“按事件”创建操作方法,然后根据发送事件的控件决定要执行的操作。 Cocoa中的控件自己处理事件,并将它们转换为更高级别的操作。因此,您可以在控制器中实现五种操作方法,将每个按钮连接到其相应的操作方法,而不必根据发送操作的控件来决定要执行的操作。

显然这并不适用于所有情况。例如,如果您有一个按钮矩阵,其图像在运行时会发生变化,您可能希望它们全部连接到同一个动作,并根据它们的标记属性区分它们。一个好的经验法则是在处理“不同”的事情时使用不同的动作方法,并在处理“许多相同的”事物时使用相同的动作方法和控制标记。

答案 2 :(得分:3)

虽然我同意标签在许多情况下都能正常工作,但是如果你有一个100个按钮的矩阵可以在你想要识别的地方使用,那么使用整数标签是很痛苦的:(1)推送的内容和(2)什么价值被推高了。我发现自己开始发明行/列命名方案,标签号已经失控。

我希望多个控件共享同一个处理程序,我想在IB中仔细设计我的UI,根据推送的内容将名称/值对传递给键值存储。

作为标签的替代品,我想出了UISegmentedControl的另一种解决方法(它也适用于其他控件)。

(1)创建一个新的类和子类UISegmentedControl。将字符串属性MyCustomKey添加到新类中。

@interface CustomSegmentedControl : UISegmentedControl
@property (nonatomic, retain) NSString* myCustomKey; 
@end

(2)返回IB,将UISegmentedContol实例修改为CustomSegmentedControl的实例。使用IB“用户定义的运行时属性”来使用IB设置myCustomKey的值。 KeyValueCoding将为您设置属性:

screen shot of setting your custom property through interface building

(3)将所有按钮连接到一个IBAction。

(4)在您的IBAction中,您现在可以通过回读自定义属性来提取键值对:

- (IBAction)myButtonPressed:(id) sender
{
    if ([sender isKindOfClass:[CustomSegmentedControl class]] == false)
        return;

    // get the key-values from the control
    CustomSegmentedControl *control = (CustomSegmentedControl *)sender;
    NSString *key = [control valueForKey:@"myCustomKey"];
    NSNumber *value = [NSNumber numberWithInteger:[control selectedSegmentIndex]];
    NSLog(@"Pressed control %@ with a value of %@", key, value);
}

在这种情况下,我只对分段控件的整数值感兴趣,但您可以将任何属性从控件中取出作为值。

希望这有帮助。

答案 3 :(得分:2)

Interface Builder Identity下的name字段是Interface Builder特有的;我实际上并不确定它是如何使用的,但是它并没有映射到实际控制中的可用属性,ivar或方法。相反,使用tag属性(在View属性下)可以区分不同的控件和操作方法,如果您不将它们作为ivar引用它们。如果我误解了您并且您想要按钮的标题,请改用currentTitle

答案 4 :(得分:0)

如果控件具有name属性,则:

NSString *senderName = [sender name];

这不是大多数控件所具有的。你可能想要:

NSString *senderName = [sender title];

例如,如果它是NSButton。或者正如Marc所说,对于UIButton,请使用currentTitle。

答案 5 :(得分:0)

尝试:

senderTitle = [sender currentTitle];