iOS:在 UI(Sub)Views 中处理 UIGestureRecognisers
我想知道如何最好地解决以下问题:
我有一个 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 对象内实现目标操作吗?
谢谢你的想法...
I would like to know how to best possible address the following issue:
I have a single ViewController. Its view contains a great number of complex subviews (subclass of UIView). Due to the complexity some of these UIViews initialise their own UIGestureRecognisers and implement the according target actions. As I want to coordinate the gestures of various subviews I have to set the single once ViewController as the gesture's delegate.
There are various possibilities for that.
1) Initialize ALL gestures in the the viewController (this will lead to a massive viewController)
2) defining a protocol in the UIVIews (getViewController), implemented by the ViewController
@protocol CustomViewDelegate <NSObject>
@required
- (UIViewController *)getViewController;
@end
3) customise the init method of the UIViews and using the ViewController as an option.
- (id)initWithFrame:(CGRect)frame andViewController:(UIViewController *)vc;
What is the most elegant possibility to solve this issue? Is it OK to implement target actions inside a UIView object?
Thanks for your thoughts...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
如果您正在定义自定义 UIView 子类,您可以为它们投入尽可能多的逻辑,以存储本地数据,为它们提供委托协议来传递其他任何内容,并且只要您将委托公开为 IBOutlet,您就可以可以直接在 Interface Builder 或 Xcode 4 的 UI 设计器部分中将视图控制器连接为相关委托。我个人认为这将是最自然的方法,因为它直接在视图中整合任何特定于视图的逻辑,并让您可以在你的地方接线通常会进行接线。
就整体设计而言,只要您的视图仅执行与视图相关的逻辑,这种方案就符合模型-视图-控制器。因此,例如,如果您有一个自定义矩形视图,可以在其上的任何位置滑动以重新定位图钉,并且图钉的 2d 位置会影响某些其他系统设置,那么您在视图中捕获手势是正确的,重新定位引脚,然后将其位置的更新发送给委托,这将履行控制器的角色,并将值推送到任何其他受影响的视图并推送到模型。
直接评论您建议的解决方案:
(1)这会将所有逻辑集中到一个控制器中;从设计的角度来看它是否正确取决于您必须询问自定义视图的程度(因为您不希望最终将它们视为外部参与者必须知道如何处理的主要数据)操作)以及您想要重用逻辑的程度。
(2) 我不确定我完全理解这个建议—— getViewController 定义在什么上以及它如何知道如何响应?如果是 UIView 本身,并且视图控制器必须首先识别自己,那么我建议只采用批发委托模式,而不是专门针对视图和视图控制器,例如,因为您可能想要构建将多个子视图的逻辑结合在一起的复合视图。
(3) 根据经验,传递给 init 的内容是类实际上需要知道才能初始化的内容;事后使用普通属性来设置控制器可能会更好。或者将其设置为 IBOutlet 并将其连接起来,以便通过 NIB 自动发生。
If you're defining custom UIView subclasses, you can invest them with as much logic as it makes sense to store local to them, give them delegate protocols to pass anything else up and, as long as you expose the delegate as an IBOutlet, you can wire up your view controller as the relevant delegate directly in Interface Builder or the UI designer part of Xcode 4. I personally think that would be the most natural way forward, since it consolidates any view-specific logic directly in the view and lets you do the wiring up where you would normally do the wiring up.
In terms of overall design, such a scheme conforms to model-view-controller provided your views are doing only view-related logic. So, for example, if you had a custom rectangular view that can take a swipe anywhere on it to reposition a pin, and the 2d position of the pin affects some other system setting, you'd be correct to catch the gesture in the view, reposition the pin and then send updates on its position down to the delegate, which would fulfil the role of controller and push the value to any other views that are affected and out to the model.
Commenting on your suggested solutions directly:
(1) this would focus all logic into the one controller; whether it's correct from a design point-of-view depends on the extent to which you're having to interrogate your custom views (in that you don't want to end up treating them as mostly data that external actors have to know how to manipulate) and the extent to which you want to reuse logic.
(2) I'm not sure I entirely understand the suggestion — what is getViewController defined on and how does it know how to respond? If it's the UIViews themselves and the view controller has to identify itself first then I'd suggest just adopting the delegate pattern wholesale rather than specialising to views and view controllers, e.g. as you may want to build compound views that tie together logic from several subviews.
(3) as a rule of thumb, the sort of things to pass to init are those that the class actually needs to know to be able to initialise; it would probably be better to use a normal property to set the controller after the fact. Or make it an IBOutlet and wire it up so that it happens automatically via the NIB.