iOS:处理 UI(子)视图中的 UIGestureRecognisers

Posted

技术标签:

【中文标题】iOS:处理 UI(子)视图中的 UIGestureRecognisers【英文标题】:iOS: handling of UIGestureRecognisers in UI(Sub)Views 【发布时间】:2011-07-14 00:30:40 【问题描述】:

我想知道如何最好地解决以下问题:

我有一个 ViewController。它的视图包含大量复杂的子视图(UIView 的子类)。由于复杂性,其中一些 UIView 会初始化它们自己的 UIGestureRecognisers 并实现相应的目标操作。由于我想协调各种子视图的手势,我必须将单个 ViewController 设置为手势的委托。 有多种可能性。

1) 初始化 viewController 中的所有手势(这将导致大量 viewController)

2) 在 UIVIews (getViewController) 中定义一个协议,由 ViewController 实现

@protocol CustomViewDelegate <NSObject>
@required
- (UIViewController *)getViewController;
@end

3) 自定义 UIViews 的 init 方法并使用 ViewController 作为选项。

- (id)initWithFrame:(CGRect)frame andViewController:(UIViewController *)vc;

解决这个问题最优雅的方法是什么?在 UIView 对象中实现目标动作可以吗?

感谢您的意见...

【问题讨论】:

【参考方案1】:

如果您要定义自定义 UIView 子类,您可以为它们添加尽可能多的逻辑,以便将它们存储在本地,为它们提供委托协议以传递其他任何内容,并且只要您将委托公开为IBOutlet,您可以直接在 Interface Builder 或 Xcode 4 的 UI 设计器部分中将您的视图控制器连接为相关委托。我个人认为这将是最自然的方式,因为它直接在视图中整合任何特定于视图的逻辑并让您在通常进行接线的地方进行接线。

就整体设计而言,如果您的视图仅执行与视图相关的逻辑,则此类方案符合模型-视图-控制器。因此,例如,如果您有一个自定义矩形视图,可以在其上的任意位置滑动以重新定位图钉,并且图钉的 2d 位置会影响其他一些系统设置,那么在视图中捕捉手势是正确的,重新定位引脚,然后将其位置的更新发送到委托,这将履行控制器的角色并将值推送到任何其他受影响的视图并输出到模型。

直接评论您建议的解决方案:

(1) 这会将所有逻辑集中到一个控制器中;从设计的角度来看它是否正确取决于您必须询问自定义视图的程度(因为您不想最终将它们视为外部参与者必须知道如何处理的主要数据操作)以及您希望重用逻辑的程度。

(2) 我不确定我是否完全理解了这个建议——getViewController 是在什么基础上定义的,它如何知道如何响应?如果是 UIViews 本身并且视图控制器必须首先识别自己,那么我建议只采用委托模式,而不是专门针对视图和视图控制器,例如因为您可能想要构建将多个子视图的逻辑联系在一起的复合视图。

(3) 根据经验,传递给 init 的东西是类实际上需要知道才能初始化的东西;事后使用普通属性设置控制器可能会更好。或者将其设为 IBOutlet 并将其连接起来,以便通过 NIB 自动发生。

【讨论】:

嗨汤米,感谢您的评论。有些东西我没有得到:正如你所写的,在特定的 UIView 类中“捕捉”手势很好。由于我有很多这样的类,我必须通过将手势委托设置为一个协调器来协调它们的手势(例如包含- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:)。这应该是控制器还是我应该为此使用一个新类? 对于 2) 我的意思如下。从 UIView 继承的每个 Class 都有其协议,由相应的 ViewController 实现以协调手势。当这些 Classes 想要设置手势 delegetae(用于协调 iof 手势)时,它们会调用[leftSwipeRecognizer setDelegate:[delegate getViewController]];。这是由所有继承自 UIView 并合并gestureRecognizer 的 Classes 完成的。 我在想例如一个 UIScrollView。这捕获了一大堆手势,包括滑动、双击和捏合,但显然它是所有这些的代表,它以某种以视图为中心的方式处理它们以影响平移和缩放,并且只将结果传递给它的代表。因此,许多不同手势的协调和过滤发生在最本地的视图中,并由委托通知结果。

以上是关于iOS:处理 UI(子)视图中的 UIGestureRecognisers的主要内容,如果未能解决你的问题,请参考以下文章

iOS10 UI教程子视图和父视图UI层次结构和Views继承

iOS开发基础-UI学习

iOS MVVM 处理初始视图状态

iOS UI基础控件之UIView 详解

iOS - 子视图不使用帧更改进行动画处理

iOS 子视图、SRP 和自定义事件