如何在一行代码中将多个子视图添加到我的 iOS 视图中? (也许通过“monkeypatching”一个 `addSubviews` 实例方法到 UIView?)

Posted

技术标签:

【中文标题】如何在一行代码中将多个子视图添加到我的 iOS 视图中? (也许通过“monkeypatching”一个 `addSubviews` 实例方法到 UIView?)【英文标题】:How to add multiple subviews to my iOS view in one line of code? (via "monkeypatching" an `addSubviews` instance method to UIView perhaps?) 【发布时间】:2014-02-23 03:16:30 【问题描述】:

假设我在给定 ViewController.m 的 viewDidLoad 方法中只有一个 UILabel 子视图元素和一个 UITextView 子视图元素,如下所示:

UILabel *name = [[UILabel alloc] initWithFrame:CGRectMake(20, 140, 280, 40)];
name.text = @"Name: Eric";
UITextView *bio = [[UITextView alloc] initWithFrame:CGRectMake(20, 190, 280, 80)];
bio.text = "Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature fro...";

按照正常方式,我可以一次添加一个:

[self.view addSubview:name];
[self.view addSubview:bio];

但是,如果有几十个甚至几百个 UI 组件,一次添加一个会在我的项目中添加几十到几百行代码。

来自红宝石背景,我认为简洁非常重要。有没有办法像这样将我的 UI 元素作为数组传递?:

[self.view addSubviews:@[name, bio]];

对我来说,在启动时开始修补 ios 的库可能还为时过早,但这对我来说绝对是一个可以接受的解决方案。

来自对 ruby​​/rails 模板的理解,我想知道,iOS 应用程序中是否有与 Rail 的 /initializers 文件夹等效的东西?仅供参考,非/pre-rails 的人,rails 中的 /initializers 文件夹在任何 rails 会话开始时都会被 rails 扫描,并且其 .rb 文件中的所有代码在加载除了依赖库之外的任何其他内容之前执行。在此之前加载。因此,例如 ActiveRecord gem(库)可以在初始化程序中重新实例化并在此时修改。我知道 Objective C 在很多情况下是不可变的,但不知道这是否会成为问题。

现有的 Cocoa 库方法当然是首选。

在 ruby​​ 中,我可能会将方法修补到 UIViewController 可能有点像这样:

class UIViewController
  def addSubviews(subviews)
    subviews.each |obj| self.view.addSubview(obj) 
  end
end

【问题讨论】:

不就是创建一个函数,然后用for循环使用那个函数吗? 只循环遍历数组。 @ElTomato 是的,但我对目标 C 非常熟悉,我认为我什至不知道如何做到这一点,如果我做的比工作知识更“隐藏的潜力”,如果你知道我的话意思是。在 Apple 是否允许 iOS 开发人员将方法修补到 App Store 批准的应用程序中的核心 iOS 类上? @boulder_ruby 是的。您可以为此在 UIView 上创建一个类别。但是,在创建类别时,您希望在方法名称前加上前缀,以免与其他人的类别冲突。因此,您可以将该方法称为 blr_addSubviews(blr 是 boulder_ruby 的缩写,但您很可能会根据您的公司名称来选择) 【参考方案1】:

我会选择UIView 上的category。

文件 --> 新建 --> 文件 --> Objective-C 类别。将其命名为 EasyAdditionOfSubviews,使其成为 UIView 上的一个类别。

UIView+EasyAdditionOfSubviews.h

#import <UIKit/UIKit.h>

@interface UIView (EasyAdditionOfSubviews)

- (void)addSubviews:(NSArray *)views;

@end

UIView+EasyAdditionOfSubviews.m

#import "UIView+EasyAdditionOfSubviews.h"

@implementation UIView (EasyAdditionOfSubviews)

- (void)addSubviews:(NSArray *)views

    for (UIView *view in views) 
        if ([view isKindOfClass:[UIView class]]) 
            [self addSubview:view];
        
    


@end

这样,您只需 #import UIView+EasyAdditionOfSubviews.h 在任何您希望能够一次添加视图数组的地方。

您最好确保传递给addSubview: 的内容确实是UIView,否则您将面临崩溃的风险(例如,尝试将其传递给NSArray)。

但为了解决您更广泛的担忧:

但如果有几十个甚至几百个 UI 组件, 一次添加一个会增加几十到几百行 我的项目的代码。

如果您以编程方式构建 UI,您希望准确确定子视图添加到视图中的内容、方式和时间;在视图中添加子视图时,显式是完全可以的。

事实上,不将子视图显式添加到其父视图的解决方法是...显式将其添加到数组中,然后将其添加到父视图中。不利于简洁!

【讨论】:

我应该把它放在我的 iOS 应用程序源代码文件系统的什么地方,我必须在哪里引用它才能使它工作?【参考方案2】:

假设 subViews 是一个数组,你可以这样做:

[subViews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) 
    [superview addSubview:obj];
];

正如@pranav 提到的,另一种方法是使用 for..in 语法:

for (UIView* view in subViews) 
    [superview addSubview:view];

【讨论】:

使用 for...in 应该更简洁,即for (NSArray *subview in subviews) @DaveWood 哈哈没问题,我都在 Cocoa 上做了调整,所以忍不住编辑它

以上是关于如何在一行代码中将多个子视图添加到我的 iOS 视图中? (也许通过“monkeypatching”一个 `addSubviews` 实例方法到 UIView?)的主要内容,如果未能解决你的问题,请参考以下文章

如何在swift ios中将多个图像添加到自定义表格视图单元格?

如何在所有视图控制器中将自定义 uibarbuttonItem 添加到我的导航项?

如何在 iOS 7 中将 UITableView 添加到 UIAlertView

在选择器中将子视图添加到主 uiview

如何在代码中将子菜单项添加到 ActionBar 操作?

IOS如何在目标c中将AFNetworking添加到我的xcode项目中