有什么需要子类化UIView而不是创建我们自己的视图并将其添加到

时间:2012-05-17 04:44:23

标签: objective-c ios ios5 ios4

为什么有人会将UIView子类化而不是创建我们自己的自定义视图:

CGRect labelRect = CGRectMake(20,20,20,20); //Frame to contain the current view
UILabel *label  = [[UILabel alloc] initWithFrame:labelRect];
label.text = @”This is a custom view with out subclassing UIView”
[self.view addSubView:label];

是否看不到任何权衡或优势?我错过了什么吗?

3 个答案:

答案 0 :(得分:2)

在很多情况下,您只需重新排列文本,并使用一些内置按钮,标签等;没有必要对UIView进行子类化,而是可以通过UIViewController以编程方式完成,或者添加到storyboard / nib文件中。但是,如果您想要为您正在使用的视图添加一些自定义触摸行为或绘图,那么您希望子类化UIView的时间和原因的一个很好的示例。

所以我看到它的方式,子类化UIView的主要考虑因素归结为以下几点:

1)触摸互动,

2)自定义绘图

*请注意,您可能希望仅从程序组织的角度来创建视图子类,但这些是主要的三个行为无法委托给另一个函数,或直接添加到{{1 }}。例如,可以在不继承UIView的情况下处理对一般动画和背景图像操作的支持。

触摸互动 - 可以通过几种不同的方式处理与UIView的触摸互动,您可以直接与触摸事件进行互动,或者为{{1添加手势识别器}}。在许多情况下,您可以通过手势识别器(或自定义手势识别器)完成所需的一切,而不是尝试查看视图上发生的各个触摸,但是如果您想要/需要访问原始触摸事件,您将覆盖以下函数以实现所需的行为:

UIView

自定义绘图 - 在UIView中,您可以通过Quartz / Core Graphics进行基本的2D绘图。一个例子是,如果您正在进行图形应用程序,并希望您的-(void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event -(void) touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event -(void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event -(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 在熨平板的上下文中为您绘制实际线条。要完成此操作,您将覆盖UIView函数并在此处列出任何自定义绘图。

话虽如此,这绝不是绘制线条的唯一方法,并且无需执行自定义绘图即可完成此任务。例如,同一行或一组行可以由UIView绘制到图像缓冲区中,然后相应地显示为视图的背景或子视图。然而,当这样做时,drawRect:(CGRect)rect 失去了屏幕上线条的知识,并且直接触摸与该线条的交互变得更具挑战性。最后,请记住,有创造性的方法来绕过子类只是为了显示自定义绘图,但有时从程序设计的角度来看,创建UIViewController子类可能更有意义。

这些并不是你想要成为UIView的子类的唯一原因,但这是我用来创建UIView的子类的两大理由。我建议你查看UIView class referenceView Programming Guide for iOS了解更多详情。

答案 1 :(得分:0)

出于同样的原因UIView在UIKit中使用控件和文本布局视图进行子类化:因为现有的实现不执行所有,并且需要自定义实现或成员(有时)。

但是,在这种情况下,您可以继承UILabel,如果您需要执行特定的操作,或者重用实现和子类是一个很好的解决方案。

答案 2 :(得分:0)

我会说自定义行为和自定义布局。从外部控制器处理调整大小超出自动调整大小掩码或智能加载子视图可用的范围更加困难。

我创建了一个自定义图像视图,该视图具有滚动视图,可在三列显示中查看一长串图像。它在内部管理图像,因此它只加载屏幕上显示的图像的视图。

你能想象必须手工构建一个UITableView,将滚动视图与单元格合成,管理单元格视图的队列,只有当它们出现时才必须智能加载单元格,并处理所有的点击,滑动和平移手势每次你需要一个表格外观的屏幕?