ios, getting a pointer to a controller from a view

2019-02-20 03:42发布

I'm trying to make an ios UI element where I can drag items on the screen onto a tableView and the tableView will add corresponding elements. I'm using the hitTest function to identify which view I'm dragging elements onto, and that's working fine. My problem is that hitTest gets me a pointer to a tableView, when I need the pointer to the tableView's controller so that I can call an "add new item" function. How do I go from a pointer to a view to a pointer to that view's controller?

5条回答
forever°为你锁心
2楼-- · 2019-02-20 04:13

The view controller is part of the responder chain. So from any view, just keep calling nextResponder until you reach an object that is a view controller.

UIResponder* r = someView;
while (![r isKindOfClass: [UIViewController class]])
    r = [r nextResponder];
UIViewController* vc = (UIViewController*)r;

Another very cool trick when you need to call a method in your view controller from a view is to use a nil-targeted action. That's because a nil-targeted action walks up the responder chain looking for someone who handles the action. For example, here's code that sets a button's action to be nil-targeted:

[b addTarget:nil action:@selector(doButton:)
   forControlEvents:UIControlEventTouchUpInside];

If the view controller implements doButton:, it will be called when this button is tapped.

查看更多
甜甜的少女心
3楼-- · 2019-02-20 04:14

You should not get the pointer to the viewController from a view. That will break the MVC as views should not know about its controller but controllers should know for which view(s) it is responsible.

It can be done but bad practice obviously: How to get UIViewController of a UIView's superView in iPhone SDK?

查看更多
别忘想泡老子
4楼-- · 2019-02-20 04:18

You can usually use: tableView.dataSource or tableView.delegate

查看更多
可以哭但决不认输i
5楼-- · 2019-02-20 04:19

You shouldn't want to. Wanting to indicates that you are managing the drag in the wrong place.

Presumably you have a container view controller whose view has a number of subviews (each with a child view controller), and the table view is one of those.

In this situation, make the container view controller the target of the drag gesture attached to the items you want to drag around. When the drag gesture fires, the controller can reposition the view as appropriate and also has access to the table controller and its view (the drop target).

In this way you don't need to abuse any of the existing connections between views and controllers to try to repurpose them.

查看更多
聊天终结者
6楼-- · 2019-02-20 04:20

Well, you could use the dataSource and/or delegate and assume (or assume and verify) that they're the controller you want. A marginally better solution would be to subclass your UITableView and add a property that refers to the view controller.

As Anindya pointed out, you shouldn't be holding references to view controllers in views. A better approach entirely would be for the UI element that is handling the drags to have a delegate property (set to the table view's controller) with specific methods for dealing with the drag results. The view you're dragging things from shouldn't really know anything about the view you're dragging them to, handle that through the delegate methods.

查看更多
登录 后发表回答