-3

I created NSView in XIB and then add dynamic muitple NSTextField, then add NSVIew to NSScrollView. But when I chane number of TextField, it is loop. I want to clear all old NStextfield before add new NSTextField. I had add clear function but it not work, my app hangs.

guiview refer to NSView (in XIB)

This is my code:

 -(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];
    }

Can you have any suggestions?

BenMorel
  • 34,448
  • 50
  • 182
  • 322
NML611
  • 27
  • 7
  • If it's a Mac app (which it appears to be, because you're using NSTextField, NSView, etc.) then it's not Cocoa Touch (which is for iOS, as the name implies). – gtmtg Jul 28 '13 at 03:28
  • Yes,i'm building MAC app, i use NSTextView and NSView.So how can i do that correctly? – NML611 Jul 28 '13 at 03:42
  • It's been a while since I've done manual reference counting, but since you're doing `guiView = [[NSView alloc] init];`, do you really need to remove those subviews? Wouldn't the operating system automatically release all the subviews? – Kevin Low Jul 28 '13 at 06:32
  • 1
    woooah that's a lot of code for a simple question – abbood Jul 28 '13 at 07:05
  • @abbood: It not simple, i try so much but it not work correct – NML611 Jul 28 '13 at 09:55

3 Answers3

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

[viewsToRemove makeObjectsPerformSelector:@selector(removeFromSuperview)];
Community
  • 1
  • 1
Shuja H.
  • 21
  • 3
1

By calling removeFromSuperview on a subview while looping through the superview's subviews, you're modifying -[NSView subviews] which you can't do.

But let's say that your code works. It looks like you're trying to remove all subviews (including the NSMatrix and not just the text fields). If you want to remove all subviews, then you can easily just call:

[[guiView subviews] makeObjectsPerformSelector:@selector(removeFromSuperview)];

If you're still looking for just the NSTextfield objects, then you can call either:

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

[viewsToRemove makeObjectsPerformSelector:@selector(removeFromSuperview)];

Or the indexesOfObjectsPassingTest: approach (I think this one is faster than filteredArrayUsingPredicate: but I'm not entirely sure):

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)];

If you don't like selectors, then you can simply loop through the viewsToRemove array and call removeFromSuperview. Because you're looping through a different array than [guiView subviews], it should not crash or hang on that part.

Kevin Low
  • 2,672
  • 16
  • 17
0

I have never done it with OSX, but maybe something like the following?

NSArray *viewsToRemove = [guiView subviews];
for (NSView *v in viewsToRemove) {
    if ([v isKindOfClass:[NSTextField class]]) {
        [v removeFromSuperview];
    }
}
El Tomato
  • 6,479
  • 6
  • 46
  • 75
  • I try your code but my app hangs. Do you have other suggestion? – NML611 Jul 28 '13 at 05:07
  • @NML611, neither this code, nor your code for clearing out the text fields should hang your app. How do you know what's causing the hang? Are you getting any errors? – rdelmar Jul 28 '13 at 05:59
  • You are actually setting a subview to ScrollView? If so, trying changing [guiView subviews] into [ScrollView subviews] on the first line and see what happens. – El Tomato Jul 28 '13 at 05:59
  • @TBlue: Can not clear all NStextfield if use [ScrollView subviews] – NML611 Jul 28 '13 at 09:54
  • Which one can you not clear? What is the name of the view to which you are adding text fields? It is you who don't define all the variables but posts code with little explanation and then demands more and more advice without showing any form of appreciation. – El Tomato Jul 28 '13 at 20:31