cocoa - NSPredicateEditorRowTemplate: how to to populate right side popup -
i trying generate nspredicateeditorrowtemplate
on left side has number of property names entity foo, among property bar. when user selects 'bar', right side should become popup contains values of 'bar'.
how can best populate right side popup? unique values of bar stored in nsmutablearray
, perhaps can use kvo change row template when array changes.
is there way can use code change values in right side popup in nspredicateeditor
row? can enter few static values in ib, not in situation.
edit
having read deal of related q&a's, including nspredicateeditor in xcode 4 , excellent answer @dave delong, think bit of work can done this:
nsarray *leftexp = @[[nsexpression expressionforkeypath:@"name"],[nsexpression expressionforkeypath:@"married"]]; nsarray *rightexp = @[[nsexpression expressionwithformat:@"one"],[nsexpression expressionwithformat:@"two"]]; nspredicateeditorrowtemplate *template = [[nspredicateeditorrowtemplate alloc] initwithleftexpressions:leftexp rightexpressions:rightexp modifier:nsdirectpredicatemodifier operators:@[@(nsequaltopredicateoperatortype)] options:0]; nspredicateeditorrowtemplate *compound = [[nspredicateeditorrowtemplate alloc] initwithcompoundtypes:@[@(nsorpredicatetype)]]; [self.predicateeditor setrowtemplates:@[template,compound]]; nsentitydescription *description = [nsentitydescription entityforname:@"person" inmanagedobjectcontext:self.managedobjectcontext]; self.predicate = [nspredicate predicatewithformat:@"name == ''"];
i've seen few ways make basic nspredicateeditor appear (with @ least compound line), seems me there has elegant way that, way meant done. can't find though, can me along this?
some argue way meant done in interface builder. fine if you're familiar how row templates work, how combined, etc. personally, prefer create programmatically because can explicit how row templates function.
let's go through example of how works together, , can decide approach works best you:
- you have object 2
nsstring
properties:bar
,baz
bar
can have number of possible values, we'll call@"bar1"
,@"bar2"
, ,@"bar3"
.baz
cannsstring
value.
with in mind, here's how you'd create programmatically:
// these defines brevity on web page; please don't #define nspert nspredicateeditorrowtemplate #define kp(_kp) [nsexpression expressionforkeypath:(_kp)] #define cv(_cv) [nsexpression expressionforconstantvalue:(_cv)] nspert *compound = [[nspert alloc] initwithcompoundtypes:@[@(nsandpredicatetype), @(nsorpredicatetype), @(nsnotpredicatetype)]]; nspert *bar = [[nspert alloc] initwithleftexpressions:@[kp(@"bar")] rightexpressions:@[cv(@"bar1"), cv(@"bar2"), cv(@"bar3")] modifier:nsdirectpredicatemodifier operators:@[@(nsequaltopredicateoperatortype), @(nsnotequaltopredicateoperatortype)] options:0]; nspert *baz = [[nspert alloc] initwithleftexpressions:@[kp(@"baz")] rightexpressionattributetype:nsstringattributetype modifier:nsdirectpredicatemodifier operators:@[@(nsequaltopredicateoperatortype), @(nsnotequaltopredicateoperatortype)] options:0]; nsarray *templates = @[compound, bar, baz]; [self.mypredicateeditor setrowtemplates:templates];
granted, lot of typing create row templates. understand that. think it's explicit , easy debug. being said, can configure exact same thing in interface builder. so, put nspredicateeditor
in xib, , give 3 row templates. compound row template you'd leave alone, other 2 you'd change configured this:
for "bar
" template:
for "baz
" template:
if compare these screenshots code above, should (hopefully) easy see how 1 maps other. row templates configured this, ib shows predicate editor in window:
if want more advanced things, such creating custom row templates, or populating list of allowed constant values data model, you'll have drop doing configuration in code.
edit answer comment question
the modifier
bit of these selectors corresponds nscomparisonpredicatemodifer
created nscomparisonpredicate
. there 3 modifiers: direct, any, , all.
@"bar = 'bar1'"; ^ no modifier means nsdirectpredicatemodifier @"any user.username = 'markjs'"; ^~~ use of "any" keyword means nsanypredicatemodifier @"all user.age < 42"; ^~~ use of "all" keyword means nsallpredicatemodifier
in these 3 examples, they're comparison predicates (because have left side, operator, , right side), use of "any" or "all" affects how left side interpreted. if either present, predicate expecting left-hand side evaluate collection of possibilities.
using "direct" option (or 0
) means you're going doing one-to-one comparison.
Comments
Post a Comment