1

是否有一种更简单、更少复制/粘贴的方式来实现与下面的代码相同的功能?什么是最好的方法?

if (self.title.selectedSegmentIndex !=-1)
{
    [self.form setValue:[self.title titleForSegmentAtIndex:self.title.selectedSegmentIndex] forKey:@"titleKey"];
}
if (self.author.selectedSegmentIndex !=-1)
{
    [self.form setValue:[self.author titleForSegmentAtIndex:self.author.selectedSegmentIndex] forKey:@"authorKey"];
}
if (self.description.selectedSegmentIndex !=-1)
{
    [self.form setValue:[self.description titleForSegmentAtIndex:self.description.selectedSegmentIndex] forKey:@"descriptionKey"];
}
etc....

编辑:对不起,它不是一个 bool if 语句(我相信我需要这个检查,否则当尝试从索引中获取标题时没有选择段时它会崩溃)

我觉得我对这些 if 语句进行了很多重复检查,并且不知道更好的方法,任何建议都值得赞赏。

4

2 回答 2

4

这种事情有几种方法。(这里的代码都没有经过测试甚至编译。)

最明显的是一个简单的方法:

- (void)setFormValueFromSegmentedControl:(UISegmentedControl *)seg forKey:(NSString *)key {
  if (seg.selectedSegmentIndex !=-1) {
    [self.form setValue:[seg titleForSegmentAtIndex:seg.selectedSegmentIndex] forKey:key];
  }
}

现在您的代码简化为:

[self setFormValueFromSegmentedControl:self.title forKey:@"titleKey"];
[self setFormValueFromSegmentedControl:self.author forKey:@"authorKey"];
...

就个人而言,我喜欢这个,因为它非常简单明了,用最少的魔法阅读。但是,如果即使该块变得笨拙,还有其他解决方案。

您可以执行@Cyrille 和@H2CO3 建议的操作:

for (NSString *key in [@"title", @"author", ...]) {
  UISegmentedControl *seg = [self valueForKey:key];
  if (seg.selectedSegmentIndex != -1) {
    NSString *formKey = [key stringByAppendingString:@"Key"];
    [self.form setValue:[seg titleForSegmentAtIndex:seg.selectedSegmentIndex] forKey:formKey];
  }
}

您还可以tag在控件上使用 a 来指示它适用于哪个表单键(您可以在 IB 中配置标签或setTag:在代码中使用)。所以title会有一个标签 0,author会有一个标签 1,等等。

NSArray *formKeyForTag = @[@"titleKey", @"authorKey", ...];
for (UISegmentedControl *seg = [... IBOutletCollection of controls ...]) {
  if (seg.selectedSegmentIndex != -1) {
    NSString *formKey = formKeyForTag[seg.tag];
    [self.form setValue:[seg titleForSegmentAtIndex:seg.selectedSegmentIndex] forKey:formKey];
  }

或者,您可以将关联对象添加到分段控件,指向表单键。请参阅什么是 objc_setAssociatedObject() 以及在什么情况下应该使用它?有关更多信息。(我碰巧喜欢相关的对象……)

或者您可以使用 anNSDictionary来保留映射。

这么多选择。但我有点喜欢顶部的简单方法。这是最明显的。

于 2013-07-12T14:39:19.923 回答
0
@protocol ObjectsWithSegmentAtIndex <NSObject>

@property (assign, atomic) NSInteger selectedSegmentIndex;

@end

。H

@interface BaseClass : NSObject    
@property (assign, atomic) id<ObjectsWithSegmentAtIndex> title;
@property (assign, atomic) id<ObjectsWithSegmentAtIndex> description;
...
@property (assign, atomic) Form* form;
@end

.m

NSString* KeyForValue (id<ObjectsWithSegmentAtIndex> value) {
    return [value description]; // example, not to be used this way
}

+(void) fillForm:(Form*)form withValues:(NSArray*) values {
    for (id<ObjectsWithSegmentAtIndex> value in values) {
        [self fillForm:form withValue:value forKey:KeyForValue(value)];
    }
}

+(void) fillForm:(Form*)form withValue:(id<ObjectsWithSegmentAtIndex>)value forKey:(id<NSCopying>)key {
    if (value.selectedSegmentIndex != kUndefinedSegmentIndex) {
        [form setValue:[value titleForSegmentAtIndex:value.selectedSegmentIndex] forKey:key];
    }
}
于 2013-07-12T14:39:54.003 回答