带有 TouchEnded 的自定义 UIImageVIew 仅适用于第一个视图

发布于 2024-09-29 04:43:24 字数 2213 浏览 0 评论 0原文

抱歉,标题不好:(

我有一个控制器,它有一个滚动视图,在其中显示一些其他视图,在本例中是 IngredientImage,它是 uiimageview 的子类:

#import "IngredientImage.h"

@implementation IngredientImage    

- (id) initWithImage:(UIImage *)image {
    if (self = [super initWithImage:image]) {

    }
    [self setUserInteractionEnabled:YES];
    return self;
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    CGPoint location = [[touches anyObject] locationInView:self];

    if (CGRectContainsPoint([self frame], location)) {
         NSLog(@"This works...");   
    }
}

- (void)dealloc {
    [super dealloc];
}


@end

并且存在将视图放入滚动视图的代码,

- (void)viewDidLoad {
    [super viewDidLoad];
    [self addIngredients];

}

- (void)addIngredients {
    NSUInteger i;
    for (i = 1; i <= 10; i++) {
        UIImage *image = [UIImage imageNamed:@"ing.png"];
        IngredientImage *imageView = [[IngredientImage alloc] initWithImage:image];

        // setup each frame to a default height and width, it will be properly placed when we call "updateScrollList"
        CGRect rect = imageView.frame;
        rect.size.height = 50;
        rect.size.width = 50;
        imageView.frame = rect;
        imageView.tag = i;  // tag our images for later use when we place them in serial fashion
        [ingredientsView addSubview:imageView];
        [imageView release];
        [image release];
    }

    UIImageView *view = nil;
    NSArray *subviews = [ingredientsView subviews];

    // reposition all image subviews in a horizontal serial fashion
    CGFloat curYLoc = INGREDIENT_PADDING;
    for (view in subviews) {
        if ([view isKindOfClass:[IngredientImage class]] && view.tag > 0) {
            CGRect frame = view.frame;
            frame.origin = CGPointMake(INGREDIENT_PADDING, curYLoc);
            view.frame = frame;

            curYLoc += (INGREDIENT_PADDING + INGREDIENT_HEIGHT);
        }
    }

    // set the content size so it can be scrollable
    [ingredientsView setContentSize:CGSizeMake([ingredientsView bounds].size.width, (10 * (INGREDIENT_PADDING + INGREDIENT_HEIGHT)))];
}

问题是只有第一个视图处理触摸事件,我不知道为什么:(

你能帮我吗?

谢谢

Sorry for bad title :(

I've a controller that has a scrollview where I display some other views, in this case an IngredientImage, that is a subclass of uiimageview:

#import "IngredientImage.h"

@implementation IngredientImage    

- (id) initWithImage:(UIImage *)image {
    if (self = [super initWithImage:image]) {

    }
    [self setUserInteractionEnabled:YES];
    return self;
}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
    CGPoint location = [[touches anyObject] locationInView:self];

    if (CGRectContainsPoint([self frame], location)) {
         NSLog(@"This works...");   
    }
}

- (void)dealloc {
    [super dealloc];
}


@end

and there is the code that puts the views in the scrollview

- (void)viewDidLoad {
    [super viewDidLoad];
    [self addIngredients];

}

- (void)addIngredients {
    NSUInteger i;
    for (i = 1; i <= 10; i++) {
        UIImage *image = [UIImage imageNamed:@"ing.png"];
        IngredientImage *imageView = [[IngredientImage alloc] initWithImage:image];

        // setup each frame to a default height and width, it will be properly placed when we call "updateScrollList"
        CGRect rect = imageView.frame;
        rect.size.height = 50;
        rect.size.width = 50;
        imageView.frame = rect;
        imageView.tag = i;  // tag our images for later use when we place them in serial fashion
        [ingredientsView addSubview:imageView];
        [imageView release];
        [image release];
    }

    UIImageView *view = nil;
    NSArray *subviews = [ingredientsView subviews];

    // reposition all image subviews in a horizontal serial fashion
    CGFloat curYLoc = INGREDIENT_PADDING;
    for (view in subviews) {
        if ([view isKindOfClass:[IngredientImage class]] && view.tag > 0) {
            CGRect frame = view.frame;
            frame.origin = CGPointMake(INGREDIENT_PADDING, curYLoc);
            view.frame = frame;

            curYLoc += (INGREDIENT_PADDING + INGREDIENT_HEIGHT);
        }
    }

    // set the content size so it can be scrollable
    [ingredientsView setContentSize:CGSizeMake([ingredientsView bounds].size.width, (10 * (INGREDIENT_PADDING + INGREDIENT_HEIGHT)))];
}

the problem is that only the first view handles the touch event, and I don't know why :(

Can you help me?

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

行雁书 2024-10-06 04:43:24

当您调用时,

CGPoint location = [[touches anyObject] locationInView:self];

您正在设置相对于 imageView 边界的位置。但在 if 语句中,

if (CGRectContainsPoint([self frame], location))

您询问该位置是否在您的框架内。但框架和边界是不同的。 Frame 给出相对于你的超级视图的坐标; bounds 给出它相对于视图本身的值。

要解决此问题,请将 if 语句更改为

if (CGRectContainsPoint([self bounds], location))

现在您在两次调用中始终使用相同的坐标系,并且您的问题应该消失。

When you call

CGPoint location = [[touches anyObject] locationInView:self];

you are setting location with respect to the bounds of your imageView. But then in your if statement,

if (CGRectContainsPoint([self frame], location))

you are asking if the location is within your frame. But frame and bounds are different. Frame gives coordinates relative to your superview; bounds gives it relative to the view itself.

To fix this, change your if statement to read

if (CGRectContainsPoint([self bounds], location))

Now you are consistently using the same coordinate system in both calls, and your problem should go away.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文