【问题标题】:remove all NSTextField in NSVIew删除 NSVIew 中的所有 NSTextField
【发布时间】:2013-07-28 03:10:36
【问题描述】:

我在 XIB 中创建了 NSView,然后添加了动态的多个 NSTextField,然后将 NSVIew 添加到 NSScrollView。但是当我改变TextField的数量时,它是循环的。我想在添加新的 NSTextField 之前清除所有旧的 NStextfield。我添加了清除功能,但它不起作用,我的应用程序挂起。

guiview refer to NSView (in XIB)

这是我的代码:

 -(void) createTextDynamic : (int) number
{
    for (NSView *subview in [guiView subviews]) { // function to clear all NStextfield but not work
        [subview removeFromSuperview];
    }
    guiView = [[NSView alloc] init];
    float heightView =(8*25 +50)+ (25+30) * number;
    NSPoint pointToScrollTo = NSMakePoint( 400, 0);  // Any point you like.
    [[ScrollView contentView] scrollToPoint: pointToScrollTo];
    [ScrollView reflectScrolledClipView: [ScrollView contentView]];
    guiView.frame = NSMakeRect(0, 0, 400, heightView);
    float label_Y = heightView - 25;
    float textfield_Y = heightView - 25;
    for(int i=1; i<=number;i++)
    {
        NSTextField *ssid = [[NSTextField alloc] initWithFrame:NSMakeRect (10,label_Y,150,25)];
        [ssid setStringValue:[NSString stringWithFormat:@"SSID %d :",i]];
        [ssid setSelectable:NO];
        [ssid setEditable:NO];
        [ssid setBordered:NO];
        [ssid setDrawsBackground:NO];
        [ssid setAutoresizingMask:NSViewWidthSizable];
        [guiView addSubview:ssid];
        label_Y -=30;
        [ssid release];

        NSTextField *key = [[NSTextField alloc] initWithFrame:NSMakeRect (10,label_Y,150,25)];
        [key setStringValue:@"KEY :"];
        [key setSelectable:NO];
        [key setEditable:NO];
        [key setBordered:NO];
        [key setDrawsBackground:NO];
        [key setAutoresizingMask:NSViewWidthSizable];
        [guiView addSubview:key];
        label_Y -=30;
        [key release];

        ssidtxt = [[NSTextField alloc] initWithFrame:NSMakeRect (200,textfield_Y,200,25)];
        [ssidtxt setBezelStyle:NSTextFieldSquareBezel];
        ssidtxt.tag=i;
         [ssidtxt setAutoresizingMask:NSViewWidthSizable];

        [guiView addSubview:ssidtxt];
        textfield_Y -=30;
        [ssidtxt release];

        keytxt = [[NSTextField alloc] initWithFrame:NSMakeRect (200,textfield_Y,200,25)];
        [keytxt setBezelStyle:NSTextFieldSquareBezel];
        keytxt.tag=100+i;
        [keytxt setAutoresizingMask:NSViewWidthSizable];

        [guiView addSubview:keytxt];
        textfield_Y -=30;
        [keytxt release];

    }
    startLbl_Y = label_Y;
    NSTextField *serverpath = [[NSTextField alloc] initWithFrame:NSMakeRect (10,label_Y,150,25)];
    [serverpath setStringValue:@"Server Path :"];
    [serverpath setSelectable:NO];
    [serverpath setEditable:NO];
    [serverpath setBordered:NO];
    [serverpath setDrawsBackground:NO];
    [guiView addSubview:serverpath];
    [serverpath release];

    startText_Y = textfield_Y;
    servertxt = [[NSTextField alloc] initWithFrame:NSMakeRect (200,textfield_Y,200,25)];
    [servertxt setBezelStyle:NSTextFieldSquareBezel];

    [guiView addSubview:servertxt];
    [servertxt release];

    label_Y-=30;
    NSTextField *username = [[NSTextField alloc] initWithFrame:NSMakeRect (10,label_Y ,150,25)];
    [username setStringValue:@"User Name :"];
    [username setSelectable:NO];
    [username setEditable:NO];
    [username setBordered:NO];
    [username setDrawsBackground:NO];
    [guiView addSubview:username];
    [username release];

    textfield_Y -=30;
    usertxt = [[NSTextField alloc] initWithFrame:NSMakeRect (200,textfield_Y,200,25)];
    [usertxt setBezelStyle:NSTextFieldSquareBezel];

    [guiView addSubview:usertxt];
    [usertxt release];
      label_Y-=30;
    NSTextField *key = [[NSTextField alloc] initWithFrame:NSMakeRect (10,label_Y,150,25)];
    [key setStringValue:@"KEY :"];
    [key setSelectable:NO];
    [key setEditable:NO];
    [key setBordered:NO];
    [key setDrawsBackground:NO];
    [guiView addSubview:key];
    [key release];
     textfield_Y -=30;
    keytxt = [[NSTextField alloc] initWithFrame:NSMakeRect (200,textfield_Y,200,25)];
    [keytxt setBezelStyle:NSTextFieldSquareBezel];

    [guiView addSubview:keytxt];
    [keytxt release];

      label_Y-=30;
    NSTextField *buzz = [[NSTextField alloc] initWithFrame:NSMakeRect (10,label_Y,150,25)];
    [buzz setStringValue:@"Buzzer Mode :"];
    [buzz setSelectable:NO];
    [buzz setEditable:NO];
    [buzz setBordered:NO];
    [buzz setDrawsBackground:NO];
    [guiView addSubview:buzz];
    [buzz release];
    textfield_Y -=60;
    prototype= [[NSButtonCell alloc] init];
    [prototype setTitle:@"Normal"];
    [prototype setButtonType:NSRadioButton];
    NSRect matrixRect = NSMakeRect(200, textfield_Y, 150, 50);
    NSMatrix *myMatrix = [[NSMatrix alloc] initWithFrame:matrixRect
                                                    mode:NSRadioModeMatrix
                                               prototype:(NSCell *)prototype
                                            numberOfRows:2
                                         numberOfColumns:1];
    [myMatrix setAction:@selector(radioButtonClicked:)];
    [myMatrix setTarget:self];
    NSArray *cellArray = [myMatrix cells];
    [[cellArray objectAtIndex:0] setTag:0];
    [[cellArray objectAtIndex:1] setTitle:@"Mute"];
    [[cellArray objectAtIndex:1] setTag:1];

    [guiView addSubview:myMatrix];
        [prototype release];
        [myMatrix release];

        [ScrollView  setDocumentView :guiView];
    }

你有什么建议吗?

【问题讨论】:

  • 如果它是 Mac 应用程序(它看起来是,因为您使用的是 NSTextField、NSView 等),那么它不是 Cocoa Touch(顾名思义,它适用于 iOS)。
  • 是的,我正在构建 MAC 应用程序,我使用 NSTextView 和 NSView。那么我该如何正确地做到这一点?
  • 我已经有一段时间没有做手动引用计数了,但是既然你在做guiView = [[NSView alloc] init];,你真的需要删除那些子视图吗?操作系统不会自动释放所有子视图吗?
  • 哇哦,一个简单的问题需要这么多代码
  • @abbood:这不简单,我尝试了很多但它不正确

标签: objective-c macos cocoa nsview nstextfield


【解决方案1】:
NSArray *viewsToRemove = [[guiView subviews] filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
        return [evaluatedObject isKindOfClass:[NSTextField class]];
    }]];

[viewsToRemove makeObjectsPerformSelector:@selector(removeFromSuperview)];

【讨论】:

    【解决方案2】:

    通过在子视图上调用removeFromSuperview,同时循环通过父视图的子视图,您正在修改-[NSView subviews],这是您无法做到的。

    但是假设您的代码有效。看起来您正在尝试删除所有子视图(包括 NSMatrix 而不仅仅是文本字段)。如果你想删除所有子视图,那么你可以很容易地调用:

    [[guiView 子视图] makeObjectsPerformSelector:@selector(removeFromSuperview)];

    如果您仍在寻找 NSTextfield 对象,那么您可以调用:

    NSArray *viewsToRemove = [[guiView subviews] filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id evaluatedObject, NSDictionary *bindings) {
            return [evaluatedObject isKindOfClass:[NSTextField class]];
        }]];
    
    [viewsToRemove makeObjectsPerformSelector:@selector(removeFromSuperview)];
    

    或者indexesOfObjectsPassingTest: 方法(我认为这个比filteredArrayUsingPredicate: 更快,但我不完全确定):

    NSIndexSet *indexesToRemove = [[guiView subviews] indexesOfObjectsPassingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
            return [obj isKindOfClass:[NSTextField class]];
        }];
    
    NSArray *viewsToRemove = [[guiView subviews] objectsAtIndexes:indexesToRemove];
    
    [viewsToRemove makeObjectsPerformSelector:@selector(removeFromSuperview)];
    

    如果您不喜欢选择器,那么您可以简单地遍历viewsToRemove 数组并调用removeFromSuperview。因为您循环的数组与 [guiView subviews] 不同,所以它不应在该部分崩溃或挂起。

    【讨论】:

      【解决方案3】:

      我从来没有在 OSX 上做过,但可能是这样的?

      NSArray *viewsToRemove = [guiView subviews];
      for (NSView *v in viewsToRemove) {
          if ([v isKindOfClass:[NSTextField class]]) {
              [v removeFromSuperview];
          }
      }
      

      【讨论】:

      • 我尝试了您的代码,但我的应用程序挂起。您还有其他建议吗?
      • @NML611,无论是这段代码,还是您清除文本字段的代码,都不应该挂起您的应用程序。你怎么知道是什么导致了挂起?你有任何错误吗?
      • 您实际上是在为 ScrollView 设置子视图?如果是这样,尝试在第一行将 [guiView subviews] 更改为 [ScrollView subviews] 看看会发生什么。
      • @TBlue: 如果使用 [ScrollView 子视图],则无法清除所有 NStextfield
      • 哪一个不清楚?您要向其中添加文本字段的视图的名称是什么?是你没有定义所有变量,而是发布了几乎没有解释的代码,然后要求越来越多的建议而没有表现出任何形式的赞赏。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-11
      • 1970-01-01
      • 1970-01-01
      • 2013-02-08
      • 1970-01-01
      • 2011-11-09
      相关资源
      最近更新 更多