【问题标题】:touchEvent for subview in UIScrollViewUIScrollView 中子视图的 touchEvent
【发布时间】:2014-02-10 11:41:58
【问题描述】:

全部,

我有一个问题,我在 StackOverflow(和其他互联网)上查看了所有可能的答案,但我尝试了所有解决方案,但没有任何效果......

我有一个 UIScrollView 和一个 UIImageView 作为子视图来创建一个板。我可以放大和缩小,工作正常。滚动效果也很好!

现在,我想将其他 UIImageView(图块)拖放到 ScrollView 以及 ScrollView 的 OUT 中。但是当我将 UIImageView 放到 ScrollView 中时,我无法拖放子视图。

我在 viewDidLoad 中设置了 UIScrollView 的 setCanCancelContentTouches:NO。
我创建了一个子类 TileImageView 并在初始化中将 ExclusiveTouch 设置为 YES。
NB:boardImage 是一个“普通”UIImageView',图块与子类一起使用!

补充:当我将 boardImage 的 UserInteraction 设置为 NO 时,ScrollView 会缩放,但 touchBegan 不会被记录。如果我将其设置为 YES,则 ScrollView 不会缩放,但会记录 touchBegan..

所以我留下它以便我可以缩放,但是一旦它们在 ScrollView 中,Tiles 就不能再拖动了。
我究竟做错了什么?或者我错过了什么?

PS:设置 delaysContentTouches 属性会使滚动无效,所以这也不是解决方案...

代码: RootViewController_iphone.m

@implementation RootViewController_iphone

@synthesize boardScrollView;
@synthesize dragObject;
@synthesize boardImage;

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.

    UIImage *image = [UIImage imageNamed:@"greyblue_numbered_15x15_900x900.png"];
    self.boardImage = [[UIImageView alloc] initWithImage:image];
    self.boardImage.frame = (CGRect){.origin=CGPointMake(0.0f, 0.0f), .size=image.size};
    [self.boardScrollView addSubview:self.boardImage];

    self.boardImage.userInteractionEnabled = YES;

    self.boardScrollView.contentSize = image.size;
    self.boardScrollView.userInteractionEnabled = YES;
    self.boardScrollView.canCancelContentTouches = NO;
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
if ([touches count] == 1) {
    // one finger

    CGPoint touchPoint = [[touches anyObject] locationInView:self.view];

    for (UIImageView *iView in self.view.subviews) {
        if ([iView isMemberOfClass:[TileImageView class]]) {
            if (touchPoint.x > iView.frame.origin.x &&
                touchPoint.x < iView.frame.origin.x + iView.frame.size.width &&
                touchPoint.y > iView.frame.origin.y &&
                touchPoint.y < iView.frame.origin.y + iView.frame.size.height)
            {
                self.dragObject = iView;
                self.touchOffset = CGPointMake(touchPoint.x - iView.frame.origin.x,
                                               touchPoint.y - iView.frame.origin.y);
                self.homePosition = CGPointMake(iView.frame.origin.x,
                                                iView.frame.origin.y);
                [self.view bringSubviewToFront:self.dragObject];
            }
        }
    }
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
    CGPoint touchPoint = [[touches anyObject] locationInView:self.view];

    CGRect newDragObjectFrame = CGRectMake(touchPoint.x - touchOffset.x,
                                           touchPoint.y - touchOffset.y,
                                           self.dragObject.frame.size.width,
                                           self.dragObject.frame.size.height);
    self.dragObject.frame = newDragObjectFrame;
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [[event allTouches] anyObject];
    NSString *tmp = touch.view.description;

    CGPoint touchPointScreen = [[touches anyObject] locationInView:self.view];
    CGPoint touchPointImage = [[touches anyObject] locationInView:self.boardImage];
    CGPoint touchPointBoard = [[touches anyObject] locationInView:self.boardScrollView];

    if (touchPointScreen.x > self.boardScrollView.frame.origin.x &&
        touchPointScreen.x < self.boardScrollView.frame.origin.x + self.boardScrollView.frame.size.width &&
        touchPointScreen.y > self.boardScrollView.frame.origin.y &&
        touchPointScreen.y < self.boardScrollView.frame.origin.y + self.boardScrollView.frame.size.height)
        {
        self.dragObject.frame = CGRectMake(touchPointImage.x - touchOffset.x,
                                           touchPointImage.y - touchOffset.y,
                                           self.dragObject.frame.size.width,
                                           self.dragObject.frame.size.height);

         [self.boardImage addSubview:self.dragObject]; // add to image


        }
}

代码: TileImageView.m

@implementation TileImageView:

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // Initialization code
        self.exclusiveTouch = YES;
    }
    return self;
}

【问题讨论】:

  • 尝试为UIImageView启用userinteraction
  • 啊,在Interaction Builder中,还有一个Interaction设置... :(现在我在de scrollview中触摸时记录了父视图中的触摸...但是现在拖放不起作用不再...
  • 你在子视图中添加了触摸代理方法吗?
  • 现在我有了,并且拖放工作!但这是在superview上。现在我不知道如何将图像添加到 [self.boardImage addSubview:self.dragObject] 的子视图中;因为 boardImage 在子类中是未知的...

标签: ios objective-c uiscrollview drag-and-drop uiimageview


【解决方案1】:

您已经有了 UIImageView 的子类,因此您可以在子类中执行以下操作:
1- 覆盖 touchsBegan、didEnd 和 didMove
2-在这些方法中将它们传递给UIScrollView的超级视图:[self.superview touchsBegan .... ]
3-如果您的 UIImageView 没有收到这些消息,那么在 init 中添加 self.userInteractionEnabled = YES; 希望对您有所帮助

【讨论】:

  • 当我调试时,应用程序没有进入子类中的touchBegan方法:(即使我添加了self.UserInteractionEnabled = YES。
  • 我认为问题在于:self.boardScrollView.contentSize = image.size;尝试这样做 self.scrollview.clipsToBounds = YES。可能是内容大小非常小,所以滚动视图不会被触及
  • ok.. 我通过 Interface Builder 添加了 ScrollView。在那里,有一个“交互启用”的设置,它没有被检查!检查后,触摸记录!但是触摸是在父视图中,而不是子视图中......如果我在子类中实现 touchBegan,我的拖放不再起作用......
  • 好的,子类方法已实现并且拖放工作。但这是在superview中。知道如何将 Tile 放到 boardScroll 中(甚至更好:在 boardImage 上)?
  • :-) 完成。它现在检测到触摸,但它不是 boardScroll 或 BoardImage 的子视图......所以从技术上讲它不是一个完整的答案;-) 但非常感谢帮助!
猜你喜欢
  • 2021-04-24
  • 1970-01-01
  • 2016-01-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多