【问题标题】:Drag UIImageView out of ScrollView将 UIImageView 拖出 ScrollView
【发布时间】:2014-02-11 13:11:32
【问题描述】:

我有一个RootViewController 和一个UIScrollViewController (boardScrollView)。 这个boardScrollView 有一个UIImageView 作为子视图(boardImage)来创建板。我可以放大和缩小并在 boardScrollView 内的 boardImage 上滚动。效果很好!

现在我想将其他 UIImageViews 拖放到 boardScrollView 内的 boardScrollImage 中,以及 boardScrollView 的 OUT 中。 对于这些其他 UIImageViews (Tiles),我创建了 UIImageView 类 (TileViewClass) 的子类。

我有拖放工作将 Tile 拖放到 boardScrollView/boardImage 并拖放到 boardScrollView/boardImage 内部,但我无法将拖放到 boardScrollView 外部工作.. 我认为这是因为我无法从子类访问rootviewcontroller 中的视图。

也许在 touchesBegan 中将 Tile 放回顶视图(窗口)会更好,因此放置位置的确定总是从同一个视图完成。 但我不知道如何做到这一点......

我在 touchesBegan 方法中尝试过[[UIApplication sharedApplication].keyWindow bringSubviewToFront:self.dragObject];,但这并不能解决问题.... 也许我在某处遗漏了 removeFromSuperView?

有人知道如何让拖放工作吗?

RootViewController.h:

@interface RootViewController : UIViewController <UIScrollViewDelegate>


@property (nonatomic, strong) IBOutlet UIScrollView *boardScrollView;
@property (nonatomic, strong) UIImageView *dragObject;
@property (nonatomic, assign) CGPoint touchOffset;
@property (nonatomic, assign) CGPoint homePosition;
@property (nonatomic, strong) UIImageView *boardImage;


@end

RootViewController.m:

@implementation RootViewController

@synthesize boardScrollView;
@synthesize dragObject;
@synthesize touchOffset;
@synthesize homePosition;
@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.canCancelContentTouches = NO;
    self.boardScrollView.userInteractionEnabled = YES;
    self.boardScrollView.clipsToBounds = YES;

}

TileImageView.h:

#import <UIKit/UIKit.h>

@interface TileImageView : UIImageView
@property (nonatomic, strong) UIImageView *dragObject;
@property (nonatomic, assign) CGPoint touchOffset;


@end

TileImageView.m:

#import "TileImageView.h"


@implementation TileImageView
@synthesize dragObject;
@synthesize touchOffset;

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];

    if (self) {
        // Initialization code
        self.exclusiveTouch = YES;
        self.userInteractionEnabled = YES;
    }
    return self;
}


- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

    if ([touches count] == 1) {
        // one finger

        CGPoint touchPoint = [[touches anyObject] locationInView:self.superview];
        for (UIImageView *iView in self.superview.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.superview bringSubviewToFront:self];
                }
            }
        }
    }
}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{

    CGPoint touchPoint = [[touches anyObject] locationInView:self.superview];
    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
{

    for (UIView *iView in self.superview.subviews) {
        if ([iView isMemberOfClass:[UIScrollView class]])
        {
            CGPoint touchPointScreen = [[touches anyObject] locationInView:[UIApplication sharedApplication].keyWindow];
            if (touchPointScreen.x > iView.frame.origin.x &&
                touchPointScreen.x < iView.frame.origin.x + iView.frame.size.width &&
                touchPointScreen.y > iView.frame.origin.y &&
                touchPointScreen.y < iView.frame.origin.y + iView.frame.size.height)
            {
                for (UIView *iView2 in iView.subviews) {
                    [iView2 addSubview:self.dragObject];
                    CGPoint touchPointImage = [[touches anyObject] locationInView:iView2];

                    self.dragObject.frame = CGRectMake(touchPointImage.x - touchOffset.x,
                                                       touchPointImage.y - touchOffset.y,
                                                       self.dragObject.frame.size.width,
                                                       self.dragObject.frame.size.height);
                }
            } 
            self.dragObject = nil;

        } 
}

【问题讨论】:

    标签: ios drag-and-drop uiimageview


    【解决方案1】:

    基本上,您会捕获 tileimageview 上的所有触摸事件并移动其原点 CGPoint。 如果触摸事件结束,您将循环通过您的 tileviews superview 的所有子视图。

    如果其中任何一个是 UIScrollview,则尝试定位接触点是否与其框架匹配。

    所以基本上你只是检查你的 uiscrollview 的框架。因此,您的接触点不能在它之外。

    解决方案:您必须检查要放置 tileimageview 的视图!您可以假设它是您的 uiscrollview 的兄弟(我假设)。

    我建议的其他方式:创建一个视图 - dropgroundview,您可以在其中捕获触摸(=> 实现 touchesend) 在那里你可以放下你的观点并检查例如的子类下拉视图。

    【讨论】:

    • 不,我想将 Tile 放到 uiScrollView 之外。因此,我希望将 Tile 作为所有视图的顶视图...
    【解决方案2】:

    解决方案:我已将触摸方法委托给 RootViewController。在那里,我可以访问所有子视图,最重要的是:最高视图。

    在这里,我说:

    [self.view bringSubviewToFront:self.tmpDragObject];
    

    然后它就起作用了!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-10-03
      • 1970-01-01
      • 1970-01-01
      • 2017-04-23
      • 2017-05-05
      • 2020-06-04
      • 2010-11-14
      相关资源
      最近更新 更多