我可以将手势识别器的代码放在视图的子类中吗?

时间:2014-01-07 01:02:41

标签: ios objective-c inheritance subclass uipangesturerecognizer

我的程序中有一个主视图,其中有一个可拖动的视图。可以使用平移手势拖动此视图。目前虽然它使用了很多我希望放在子类中以减少复杂性的代码。 (我最终希望通过允许用户使用进一步的平移手势来扩展视图来增加功能。这意味着如果我不能先将其排除,将会有更多代码堵塞我的视图控制器。

是否可以在类的子类中包含手势识别器的代码,并且仍然可以与父类中的视图进行交互。

这是我用于在父类中启用平移手势的当前代码:

-(void)viewDidLoad {

    ...


   UIView * draggableView = [[UIView alloc]initWithFrame:CGRectMake(highlightedSectionXCoordinateStart, highlightedSectionYCoordinateStart, highlightedSectionWidth, highlightedSectionHeight)];
draggableView.backgroundColor = [UIColor colorWithRed:121.0/255.0 green:227.0/255.0 blue:16.0/255.0 alpha:0.5];
   draggableView.userInteractionEnabled = YES;

   [graphView addSubview:draggableView];

   UIPanGestureRecognizer * panner = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panWasRecognized:)];

   [draggableView addGestureRecognizer:panner];

}

- (void)panWasRecognized:(UIPanGestureRecognizer *)panner {

    UIView * draggedView = panner.view;
    CGPoint offset = [panner translationInView:draggedView.superview];
    CGPoint center = draggedView.center;

    // We want to make it so the square won't go past the axis on the left
    // If the centre plus the offset

    CGFloat xValue = center.x + offset.x;

    draggedView.center = CGPointMake(xValue, center.y);

    // Reset translation to zero so on the next `panWasRecognized:` message, the
    // translation will just be the additional movement of the touch since now.
    [panner setTranslation:CGPointZero inView:draggedView.superview];
}

(Thanks to Rob Mayoff for getting me this far)

我现在已经添加了视图的子类,但无法弄清楚我需要创建手势识别器的方式或位置,因为视图现在正在子类中创建并添加到父类中。

我真的希望手势识别器的目标位于此子类中,但是当我尝试编码时,没有任何事情发生。

我已经尝试将所有代码放在子类中并将pan手势添加到视图中,但是当我尝试拖动它时,我遇到了错误的访问崩溃。

我目前正在尝试使用

[graphView addSubview:[[BDraggableView alloc] getDraggableView]];

将其添加到子视图,然后在子类中的函数getDraggableView中设置视图(添加平移手势等)

必须有一种更直接的方式来做到这一点,我还没有概念化 - 我仍然很新处理子类,所以我仍然在学习它们如何组合在一起。

感谢您提供任何帮助

2 个答案:

答案 0 :(得分:1)

我想我可能会想出这个。

在父类中,我创建了子类变量:

BDraggableView * draggableViewSubClass;
draggableViewSubClass = [[BDraggableView alloc] initWithView:graphView andRangeChart:   [rangeSelector getRangeChart]];

这允许我初始化子类,其中包含我想要的可拖动视图的视图:graphView

然后在子视图中,我按照惯例设置了平移手势,但将其添加到此视图中:

- (id)initWithView:(UIView *) view andRangeChart: (ShinobiChart *)chart {
    self = [super initWithNibName:nil   bundle:nil];
    if (self) {
        // Custom initialization
        parentView = view;

        [self setUpViewsAndPans];
    }
return self;
}

- (void)setUpViewsAndPans {

    draggableView = [[UIView alloc]initWithFrame:CGRectMake(highlightedSectionXCoordinateStart, highlightedSectionYCoordinateStart, highlightedSectionWidth, highlightedSectionHeight)];
    draggableView.backgroundColor = [UIColor colorWithRed:121.0/255.0 green:227.0/255.0 blue:16.0/255.0 alpha:0.5];
    draggableView.userInteractionEnabled = YES;

    // Add the newly made draggable view to our parent view
    [parentView addSubview:draggableView];
    [parentView bringSubviewToFront:draggableView];

    // Add the pan gesture
    UIPanGestureRecognizer * panner = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panWasRecognized:)];
    [draggableView addGestureRecognizer:panner];
}

- (void)panWasRecognized:(UIPanGestureRecognizer *)panner {

    UIView * draggedView = panner.view;
    CGPoint offset = [panner translationInView:draggedView.superview];
    CGPoint center = draggedView.center;

    CGFloat xValue = center.x + offset.x;

    draggedView.center = CGPointMake(xValue, center.y);

    // Reset translation to zero so on the next `panWasRecognized:` message, the
    // translation will just be the additional movement of the touch since now.
    [panner setTranslation:CGPointZero inView:draggedView.superview];
}

我花了一些时间来理清我们想要在子类中完成所有设置,然后将这个视图及其特性添加到父视图中。

感谢所有的答案,他们让我思考正确的方法来解决它

答案 1 :(得分:0)

我认为您想要继承UIView并创建自己的DraggableView类。在这里,您可以添加滑动和平移手势识别器。这将是UIView

的子类的实现
- (id)initWithFrame:(CGRect)frame
{
     if (self = [super initWithFrame:frame]) {
         UIGestureRecognizer *gestRec = [[UIGestureRecognizer alloc] initWithTarget:self 
                                                                             action:@selector(detectMyMotion:)];
         [self addGestureRecognizer:gestRec];
     }
     return self;
}

- (void)detectMyMotion:(UIGestureRecognizer *)gestRect
{
    NSLog(@"Gesture Recognized");
    // maybe even, if you wanted to alert your VC of a gesture...
    [self.delegate alertOfGesture:gestRect];
    // your VC would be alerted by delegation of this action.
}