NSView上的唯一ID

Jay*_*Jay 12 cocoa objective-c

是否可以通过Xcode在.nib/.xib中使用和设置任何类型的ID,可以在运行时查询以从代码中识别特定的视图实例?

特别是在我们的界面中拥有相同NSView子类的多个副本时,我们如何知道我们当前正在查看哪个?

Chr*_*ahl 13

在Interface Builder中,有一种方法可以设置NSView的"标识符".在这种情况下,我将使用标识符"54321"作为标识符字符串.

NSView符合NSUserInterfaceItemIdentification协议,它是NSString的唯一标识符.您可以遍历视图层次结构并找到具有该标识符的NSView.

因此,要建立关于获取NSViews列表,获取所有视图和NSWindow子视图的帖子,您可以找到具有您想要的标识符的NSView:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    NSView *viewToFind = [self viewWithIdentifier:@"54321"];
}  

- (NSView *)viewWithIdentifier:(NSString *)identifier
{
    NSArray *subviews = [self allSubviewsInView:self.window.contentView];

    for (NSView *view in subviews) {
        if ([view.identifier isEqualToString:identifier]) {
            return view; 
        }
    }

    return nil;
}

- (NSMutableArray *)allSubviewsInView:(NSView *)parentView {

    NSMutableArray *allSubviews     = [[NSMutableArray alloc] initWithObjects: nil];
    NSMutableArray *currentSubviews = [[NSMutableArray alloc] initWithObjects: parentView, nil];
    NSMutableArray *newSubviews     = [[NSMutableArray alloc] initWithObjects: parentView, nil];

    while (newSubviews.count) {
        [newSubviews removeAllObjects];

        for (NSView *view in currentSubviews) {
            for (NSView *subview in view.subviews) [newSubviews addObject:subview];
        }

        [currentSubviews removeAllObjects];
        [currentSubviews addObjectsFromArray:newSubviews];
        [allSubviews addObjectsFromArray:newSubviews];

    }

    for (NSView *view in allSubviews) {
        NSLog(@"View: %@, tag: %ld, identifier: %@", view, view.tag, view.identifier);
    }

    return allSubviews;
}
Run Code Online (Sandbox Code Playgroud)

或者,由于您使用的是NSView子类,因此可以在运行时设置每个视图的"标记".(或者,您可以在运行时设置标识符.)标记的好处是,有一个预先构建的函数,用于查找具有特定标记的视图.

// set the tag
NSInteger tagValue = 12345;
[self.myButton setTag:tagValue];

// find it 
NSButton *myButton = [self.window.contentView viewWithTag:12345];
Run Code Online (Sandbox Code Playgroud)


Rob*_*ger 11

通用NSView对象不能tag在Interface Builder中设置其属性.的tag上方法NSView是只读方法,只能在的子类来实现NSView.NSView没有实现setTag:方法.

我怀疑其他答案指的NSControl是定义-setTag:方法的实例,并且有一个Interface Builder字段允许您设置标记.

可以用通用视图做的是使用用户定义的运行属性.这允许您在视图对象中预设属性的值.因此,如果您的视图定义了这样的属性:

@property (strong) NSNumber* viewID;
Run Code Online (Sandbox Code Playgroud)

然后,在Interface Builder中Identity检查器的用户定义属性部分中,可以添加包含keypath viewID,类型Number和值的属性123.

在视图的-awakeFromNib方法中,您可以访问该属性的值.您会发现在上面的示例中,viewID视图的属性已预先设置为123.