【问题标题】:A More Concise Way to do This in Objective C?在 Objective C 中执行此操作的更简洁的方法?
【发布时间】:2011-03-19 06:26:29
【问题描述】:

所以我的代码中有这样的内容:

    leftMostLabel = [[UILabel alloc] initWithFrame:CGRectMake(60.0f, 2.0f, 80.0f, 40.0f)];
    leftMostLabel.text = @"Some text";
    leftMostLabel.textColor = [UIColor colorWithWhite:1.0 alpha:1.0];
    leftMostLabel.backgroundColor = [UIColor clearColor];
    leftMostLabel.textAlignment = UITextAlignmentCenter;
    leftMostLabel.font = [UIFont boldSystemFontOfSize:13.0];
    leftMostLabel.userInteractionEnabled = NO;

    centerLeftLabel = [[UILabel alloc] initWithFrame:CGRectMake(115.0f, 2.0f, 80.0f, 40.0f)];
    centerLeftLabel.text = currentDate;
    centerLeftLabel.textColor = [UIColor colorWithWhite:1.0 alpha:1.0];
    centerLeftLabel.backgroundColor = [UIColor clearColor];
    centerLeftLabel.textAlignment = UITextAlignmentCenter;
    centerLeftLabel.font = [UIFont systemFontOfSize:12.0];
    centerLeftLabel.userInteractionEnabled = NO;

这很好用,但我重复了很多次这种格式。理想情况下,我希望将变量(leftMostLabel、centerLeftLabel 等)传递给一个函数,该函数根据我传递给它的 变量名称 在幕后为我创建标签,如以及我提供的任何其他参数。这可能吗?如果是这样,我将如何处理?

提前致谢!

【问题讨论】:

    标签: objective-c cocoa-touch coding-style


    【解决方案1】:

    Objective-C 提供了通过类别扩展现有类的可能性,因此您可以轻松地将方法添加到 UILabel,例如:+labelWithFrame:text:textColor:backgroundColor:alignment:font:interaction:。这会缩短一些时间,所以你的代码看起来像:

    UILabel *leftLabel = [UILabel labelWithFrame:CGRectMake(...)
                                            text:@"Yoo hoo!"
                                       textColor:[UIColor blueColor]
                                 backgroundColor:[UIColor clearColor]
                                   textAlignment:UITextAlignmentLeft
                                            font:[UIFont systemFontOfSize:12];
                          userInteractionEnabled:NO];
    

    这看起来不那么杂乱,可能值得。

    如果您的大多数标签都相似,另一种选择是添加一个使用原型创建标签的方法。 UIView 没有实现 NSCopying,因此您不能只使用 -copy 方法制作标签的副本,但您可以编写一个创建新标签并基于现有标签进行配置的方法。调用它可能看起来像:

    UILabel *centerLabel = [UILabel labelWithFrame:CGRectMake(...)
                                         likeLabel:leftLabel];
    centerLabel.text = @"Hey there!";
    

    最后,考虑使用 Interface Builder 创建所有这些标签。 Cocoa 和 Cocoa Touch 代码将充满调用查看配置方法的调用,例如 -initWithFrame: 和 -addSubview: 如果不是用于 IB。它可能适合您的情况,也可能不适合,但有时人们会避免使用 IB,因为他们认为它需要更多工作或使他们的代码更难管理;我认为恰恰相反。

    【讨论】:

    • 我实际上经常从我的应用程序的工具栏中删除和添加标签,而且我认为在代码中这样做肯定更容易。我有在 IB 中制作的按钮,但是它们很难通过代码进行操作,因此我尽量避免使用 IB。
    • 在 IB 中创建的对象与在代码中创建的对象没有什么不同,因此它们不可能更难操作——它们是同一回事。如果您不了解如何使用 IB,“在代码中执行”只会“更容易”。不过,公平地说,IB 乍一看是相当神秘的。我的建议是:帮自己一个忙,强迫自己学习 IB——你不会后悔的!
    【解决方案2】:

    简洁,有一个词你在与 Objective-C 结合时不常看到。来自另一种语言,我对像这样的 sn-ps 感到痛苦。

    我只写过一次必要的标签变体,然后重复多次。其他发布的答案都是可行的选择,尽管我不太确定简洁的论点。 @Caleb 的“likeLabel”答案是最通用的,但您仍然需要能够引用其他标签。

    我在 UILabel 上创建了一个特定于项目的类别,并在其中放置了我自己的各种标签。我唯一愿意为每个标签重复的是框架和文本。没有必要将 +methods 放在一个类别中,但 UILabel 确实很好地总结了你想要的东西。设置好类别后,您可以这样使用它:

    UILabel *someLabel = [UILabel headerLabelWithFrame:CGRectMake(10, 10, 256, 32) andText:@"Conciseness"];
    

    这就是仅使用一种标签类型的类别。如果需要,您可以添加更多:

    @interface UILabel (ProjectSpecificLabels)
    +(UILabel *)headerLabelWithFrame:(CGRect)frame andText:(NSString *)text;
    @end
    
    @implementation UILabel (ProjectSpecificLabels)
    +(UILabel *)headerLabelWithFrame:(CGRect)frame andText:(NSString *)text {
      UILabel *label = [[[self alloc] initWithFrame:frame] autorelease];
      label.text = text;
      label.textColor = [UIColor colorWithWhite:1.0 alpha:1.0];
      label.backgroundColor = [UIColor clearColor];
      label.textAlignment = UITextAlignmentCenter;
      label.font = [UIFont boldSystemFontOfSize:13.0];
      label.userInteractionEnabled = NO;
      return label;
    }
    @end
    

    希望对您有所帮助。
    干杯, EP。

    【讨论】:

    • +1 以获得优雅(简洁)的解决方案,但您可能需要考虑在类方法中调用 [self alloc] 而不是 [<ClassName> alloc]。这将允许继承的方法对子类正常工作。
    【解决方案3】:

    我会将它分解为一个设置我的值的函数。

    leftMostLabel = [[UILabel alloc] initWithFrame:CGRectMake(60.0f, 2.0f, 80.0f, 40.0f)];
    leftMostLabel.text = @"Some text";
    [self initLabelValues:leftMostLabel withFont:[UIFont boldSystemFontOfSize:13.0]];
    
    centerLeftLabel = [[UILabel alloc] initWithFrame:CGRectMake(115.0f, 2.0f, 80.0f, 40.0f)];
    centerLeftLabel.text = currentDate;
    [self initLabelValues:centerLeftLabel withFont:[UIFont boldSystemFontOfSize:12.0]];
    
    -(void) initLabelValues:(UILabel*)inLabel withFont:(UIFont*)font {
    
        [inLabel setTextColor:[UIColor colorWithWhite:1.0 alpha:1.0]];
        [inLabel setBackgroundColor:[UIColor clearColor]];
        [inLabel setTextAlignment:UITextAlignmentCenter];
        [inLabel setUserInteractionEnabled:NO];
    
        [inLabel setFont:font];
    }
    

    【讨论】:

    • 避免命名方法 -init... 除非它们是初始化方法。 UILabel 的 -init... 方法应该调用指定的初始化程序 -initWithFrame:.
    • 我同意,setLabelValues 可能是一个更好的选择。所以你得到了我的 +1。
    • setLabelValues 将是一个同样糟糕的名称,因为它暗示该方法设置了一个实例变量。顺便说一句,您发布的示例是一个方法,而不是一个函数,尽管我认为一个函数会更合适,因为您的实现不会触及对象的实例变量。
    • jlehr 你能发布一下你将如何使用函数和适当的名称吗?
    • 不得不接受这个答案,因为这是我第一次提出这个问题时所设想的方法,也是我在项目中成功使用的方法。感谢其他所有人的回答,因为您无疑拓宽了我的视野,我将永远记住这些建议。我已经给你所有的答案+1。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 2019-09-01
    • 1970-01-01
    • 2021-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多