如何在一行代码中将多个子视图添加到我的 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 添加到我的导航项?