2011-05-12 11 views
5

Estoy creando un NSPredicateEditor en el código y tratando de lograr lo que esperaba que fuera una tarea bastante simple. Básicamente, me gustaría mostrar un compuesto NSPredicateEditorRowTemplate (que le da al usuario la opción de realizar coincidencias cuando "Todos/Cualquiera/Ninguno de los siguientes son verdaderos") y un número de subdominios bastante básicos debajo de él. Para hacer esto, construyo mi NSPredicateEditor y ato su valor para guardar los cambios a medida que el usuario edita su predicado.Forzar la visualización de una fila compuesta con NSPredicateEditor

El problema que estoy experimentando es que, no importa qué, no puedo hacer que un compuesto NSPredicateEditorRowTemplate se muestre de manera predeterminada como la fila principal con una sola subrow. Cuando creo el predicado inicialmente que pase un predicado vacío falsa, así:

filename BEGINSWITH[cd] '' 

Con el fin de obligar a la pantalla de una fila compuesto que tengo que crear dos subfilas:

filename BEGINSWITH[cd] '' && path ==[cd] '' 

Para referencia, Así es como yo estoy construyendo el NSPredicateEditor:

NSArray *keyPaths = [NSArray arrayWithObjects:[NSExpression expressionForKeyPath:@"filename"], [NSExpression expressionForKeyPath:@"path"], nil]; 
NSArray *operators = [NSArray arrayWithObjects:[NSNumber numberWithInteger:NSEqualToPredicateOperatorType], 
                      [NSNumber numberWithInteger:NSNotEqualToPredicateOperatorType], 
                      [NSNumber numberWithInteger:NSBeginsWithPredicateOperatorType], 
                      [NSNumber numberWithInteger:NSEndsWithPredicateOperatorType], 
                      [NSNumber numberWithInteger:NSContainsPredicateOperatorType], 
                      nil]; 

NSPredicateEditorRowTemplate *template = [[NSPredicateEditorRowTemplate alloc] initWithLeftExpressions:keyPaths 
                      rightExpressionAttributeType:NSStringAttributeType 
                           modifier:NSDirectPredicateModifier 
                          operators:operators 
                           options:(NSCaseInsensitivePredicateOption | NSDiacriticInsensitivePredicateOption)]; 

NSArray *compoundTypes = [NSArray arrayWithObjects:[NSNumber numberWithInteger:NSNotPredicateType], 
                 [NSNumber numberWithInteger:NSAndPredicateType], 
                 [NSNumber numberWithInteger:NSOrPredicateType], 
                 nil]; 

NSPredicateEditorRowTemplate *compound = [[NSPredicateEditorRowTemplate alloc] initWithCompoundTypes:compoundTypes]; 
NSArray *rowTemplates = [NSArray arrayWithObjects:compound, template, nil]; 
[template release]; 
[compound release]; 

predicateEditor = [[NSPredicateEditor alloc] init]; 
[predicateEditor setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; 
[predicateEditor setRowTemplates:rowTemplates]; 
[predicateEditor setCanRemoveAllRows:NO]; 
[predicateEditor setContinuous:YES]; 
[predicateEditor setFrame:[[scrollView contentView] bounds]]; 

// Create a custom binding for our NSPredicateEditor 
SIPredicateStringValueTransformer *transformer = [[[SIPredicateStringValueTransformer alloc] init] autorelease]; 
NSMutableDictionary *bindingOptions = [NSMutableDictionary dictionaryWithObjectsAndKeys:transformer, NSValueTransformerBindingOption, [NSNumber numberWithBool:YES], NSValidatesImmediatelyBindingOption, nil]; 
[predicateEditor bind:@"value" toObject:self withKeyPath:@"self.filter.predicate" options:bindingOptions]; 

// Add our NSPredicateEditor to our NSScrollView 
[scrollView setDocumentView:predicateEditor]; 

Respuesta

5

el problema es que se está dando un predicado de comparación. Necesitas darle uno compuesto.

Supongo que su objeto SIPredicateStringValueTransformer toma una cadena y la convierte en un predicado, ¿verdad? Y es probable que hacer algo como esto:

- (id) transformedValue:(id)value { 
    return [NSPredicate predicateWithFormat:value]; 
} 

Lo que se quiere hacer en su lugar es garantía de que el transformador de valor no sólo se devuelve ningún predicado de edad, sino más bien un compuesto predicado (es decir, un NSCompoundPredicate en lugar de una NSComparisonPredicate). La forma de hacerlo es muy sencilla:

- (id) transformedValue:(id)value { 
    NSPredicate *p = [NSPredicate predicateWithFormat:value]; 
    if ([p isKindOfClass:[NSComparisonPredicate class]]) { 
    p = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObject:p]]; 
    } 
    return p; 
} 

Cuando das un NSCompoundPredicate al editor predicado, se muestra la fila compuesto. Cuando solo da un predicado de comparación, solo muestra la fila de comparación adecuada.

+1

Esto era exactamente correcto. Gracias por una respuesta tan detallada. Espero que esto ayude a alguien en el futuro. – ndg

Cuestiones relacionadas