天道酬勤,学无止境

CGRectContainsPoint 不适用于不同的视图(CGRectContainsPoint does not work on different views)

问题

我正在制作一个简单的拖放项目。 当我使用CGRectContainsPoint将视图拖放到不同的视图上时,它可以工作。 但是两个视图应该在同一个视图中。 现在假设我有一个名为“A”的视图,它包含两个视图。 一个UIView和一个UIStackView 。 如果我将 Stack View 中的一个视图拖到 UIView 它不会下降。 简单的CGRectContainsPoint不适用于从不同视图拖放。 有什么办法可以解决吗?

回答1

由于每个视图都有自己的坐标系,因此在比较它们之前,您必须将所有坐标转换为相同的坐标系(例如,使用CGRectContainsPoint 。并且您需要了解每个点或矩形,它是在什么坐标系中给出的。Apple 总是在文档中指定它。

作为公共坐标系,选择公共父级或窗口之一。

在您的情况下,您比较视图的中心是否位于另一个视图的边界内。 所以选择一个共同的父视图作为参考坐标系,例如视图控制器主视图:

在斯威夫特:

let referenceView = self.view // assuming self is the view controller
let dropArea = referenceView.convertRect(self.dropAreaView1.bounds, fromView: self.dropAreaView1)
let center = referenceView.convertPoint(sender.view!.center, fromView: sender.view!.superview)
if CGRectContainsPoint(dropArea, center) {
   // do something
}

请注意, frame指定了超级视图坐标系中的边界。 因此,我已将其更改为bounds ,它在视图的 onw 坐标系中指定它。 此外, center使用超级视图的坐标系。 因此,我将点从超级视图的系统转换为参考视图的系统。

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 如何将 CGRectContainsPoint() 与旋转的 UIView 一起使用(How to use CGRectContainsPoint() with rotated UIView)
    问题 我有一个UIView ,用户可以点击UIView来“选择”或突出显示它代表的应用内“事物”。 我使用CGRectContainsPoint(thing.frame,tapPoint)来实现这一点,其中thing.frame是UIView的框架,而tapPoint是来自UITapGestureRecognizer的点击点。 这工作完美。 ..除非通过设置transform属性(使用CGAffineTransform值)旋转UIView 。 当UIView像这样旋转时, frame就变成了一个扁平的正方形,将旋转后的 view 封装起来。 这是问题的说明(框架属性标记为 A,可视化UIView bounds标记为 B): 不旋转时 +------------------+ | A == B | +------------------+ 旋转时 +-----------------+ | A . | | . . | | . . | | . . | | . B . | | . . | | . . | | . | +-----------------+ 我想捕获在 rect B范围内的点击( UIView的真实边界,旋转),但不是当它们只在 rect A ( UIView的frame属性的值)而不是B 。 我如何计算给定的点击点是否在旋转的UIView的真实边界/框架/边界内?
  • 确定裁剪矩形是否完全包含在旋转的UIView中(Determine if crop rect is entirely contained within rotated UIView)
    问题 前提:我正在构建一个裁剪工具,该工具可以处理图像的两指任意旋转以及任意裁剪。 有时,图像最终以某种方式旋转,即插入空白空间以填充旋转的图像和裁切区域之间的间隙(请参见下面的示例)。 我需要确保图像视图在旋转时完全适合裁剪矩形。 如果没有,那么我需要重新变换图像(缩放),以使其适合裁剪范围。 使用此答案,我实现了检查旋转的UIImageView是否与裁剪CGRect相交的功能,但是不幸的是,这并不能告诉我裁剪矩形是否完全包含在旋转的imageview中。 希望我可以对此答案进行一些简单的修改? OK的直观示例: 而且还不行,我需要检测和处理的问题: 更新:不起作用的方法 - (BOOL)rotatedView:(UIView*)rotatedView containsViewCompletely:(UIView*)containedView { CGRect rotatedBounds = rotatedView.bounds; CGPoint polyContainedView[4]; polyContainedView[0] = [containedView convertPoint:rotatedBounds.origin toView:rotatedView]; polyContainedView[1] = [containedView convertPoint
  • 如何在地图的注释的标注中添加自定义视图(How To add custom View in map's Annotation's Callout's)
    问题 这是我的代码。 我想添加自己的自定义标注视图,而不是iOS默认设置。 我知道只有左侧标注和右侧标注视图,但是我需要添加具有自己的背景和标签的视图工具提示类型。 - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation { MKAnnotationView *userAnnotationView = nil; if ([annotation isKindOfClass:MKUserLocation.class]) { userAnnotationView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:@"UserLocation"]; if (userAnnotationView == nil) { userAnnotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"UserLocation"]; } else userAnnotationView.annotation = annotation
  • 显示键盘时将 UITextField 滚动到视图中(Scrolling UITextField into view when keyboard is shown)
    问题 我正在编写一个针对 iOS 6.1 的应用程序。 如果 UITextField 被键盘遮挡,我正在尝试遵循此 Apple 文档,了解如何将 UITextField 滚动到视图中。 问题是 Apple 记录的用于计算滚动点的算法效果不佳。 我的计算滚动点的算法只是稍微好一点,但是相差了 70 个像素。 计算滚动点的正确方法是什么? 下面你可以看到,从左到右,我在显示键盘之前的视图,我使用Apple的算法计算滚动点滚动后的视图,以及使用我的算法计算滚动点的滚动后的视图。 (该网格中的每个方块都是 25 x 25 像素。) 这是我正在使用的代码。 注意#if APPLE_WAY块。 - (void)keyboardWasShown:(NSNotification*)aNotification { NSDictionary* info = [aNotification userInfo]; CGSize kbSize = [[info objectForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue].size; UIEdgeInsets contentInsets = UIEdgeInsetsMake(0.0, 0.0, kbSize.height, 0.0); self.view.contentInset =
  • hitTest:WithEvent 和子视图(hitTest:WithEvent and Subviews)
    问题 我有 2 个视图,但我想让 1 个视图(实际上)更大。 如果我将我的 tapGesture 放在 v1 上,则点击手势适用于更大的点击区域,但如果我将我的 tapGesture 放在 v2 上,它就不起作用(实际上它根本无法识别 tapGesture,甚至不在原始边界内)尽管我遍历了我的 TestView1 hittest 方法并且这些点包含在框架中。 #import "ViewController.h" @interface TestView1 : UIView @end @implementation TestView1 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { CGFloat radius = 100.0; CGRect frame = CGRectMake(0, 0, self.frame.size.width + radius, self.frame.size.height + radius); if (CGRectContainsPoint(frame, point)) { return self; } return nil; } @end @interface TestView2 : UIView @end @implementation TestView2 - (UIView
  • UIButton:使点击区域大于默认点击区域(UIButton: Making the hit area larger than the default hit area)
    问题 我有一个关于UIButton及其命中区域的问题。 我在界面构建器中使用“信息暗”按钮,但是发现命中区域不足以容纳某些人的手指。 有没有一种方法可以通过编程方式或在Interface Builder中增加按钮的点击区域,而无需更改InfoButton图形的大小? 回答1 由于我使用的是背景图片,因此这些解决方案都无法很好地满足我的需求。 这是一个执行一些有趣的Objective-C魔术的解决方案,并以最少的代码提供了一个解决方案。 首先,向UIButton添加一个类别,该类别将覆盖点击测试,还添加一个用于扩展点击测试框架的属性。 UIButton + Extensions.h @interface UIButton (Extensions) @property(nonatomic, assign) UIEdgeInsets hitTestEdgeInsets; @end UIButton + Extensions.m #import "UIButton+Extensions.h" #import <objc/runtime.h> @implementation UIButton (Extensions) @dynamic hitTestEdgeInsets; static const NSString *KEY_HIT_TEST_EDGE_INSETS = @
  • 如何判断两个物体是否相交?(How to find whether two objects intersect each other?)
    问题 我使用以下代码来创建和动画对象 //For creating two imageview UIImageView *bbl1Obj=[[UIImageView alloc]initWithFrame:CGRectMake(34,77,70, 70)]; bbl1Obj.image=[UIImage imageNamed:@"bubble1.png"]; [self.view addSubview:bbl1Obj]; UIImageView *bbl2Obj=[[UIImageView alloc]initWithFrame:CGRectMake(224,77,70, 70)]; bbl2Obj.image=[UIImage imageNamed:@"bubble2.png"]; [self.view addSubview:bbl2Obj]; // for animating the objects [UIImageView beginAnimations:nil context:NULL]; [UIImageView setAnimationDuration:3]; [bbl1Obj setFrame:CGRectMake(224,77,70, 70)]; [UIImageView commitAnimations]; [UIImageView beginAnimations
  • 将 UITouch 位置与 UIImageView 矩形进行比较(Comparing a UITouch location to UIImageView rectangle)
    问题 我有以下代码来确定触摸是否在我的表格单元格中的图像视图内。 但是,它不起作用。 我将两者与 CGRectContainsPoint 进行了比较,但是,它不起作用。 这是代码: -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { // Declare the touch and get it's location UITouch *touch = [touches anyObject]; CGPoint touchLocation = [touch locationInView:self]; if (CGRectContainsPoint(myImageView.frame, touchLocation)) { NSLog(@"Tapped image view"); } } 谢谢您的帮助! 回答1 但是,它不起作用。 请更具体。 UITouch *touch = [touches anyObject]; 为什么不检查每一次触摸,而不是简单地随机*挑选它们? * anyObject 的文档说你不能保证它会给你哪一个。 你甚至不能保证它是随机的; 每次都可能是同一个对象。 墨菲定律说,无论是否随机,都将是错误的。 CGPoint touchLocation = [touch
  • UIPicker检测当前选定行上的点击(UIPicker detect tap on currently selected row)
    问题 我有一个UIPickerView ,点击选定的行时不调用didSelectRow方法。 我需要处理这种情况。 有任何想法吗? 回答1 首先,使类符合UIGestureRecognizerDelegate协议 然后,在视图设置中: UITapGestureRecognizer *tapToSelect = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tappedToSelectRow:)]; tapToSelect.delegate = self; [self.pickerView addGestureRecognizer:tapToSelect]; 在其他地方: #pragma mark - Actions - (IBAction)tappedToSelectRow:(UITapGestureRecognizer *)tapRecognizer { if (tapRecognizer.state == UIGestureRecognizerStateEnded) { CGFloat rowHeight = [self.pickerView rowSizeForComponent:0].height; CGRect selectedRowFrame = CGRectInset(self
  • 如何处理自定义标注视图上的水龙头?(How to handle taps on a custom callout view?)
    问题 我正在添加一个标注视图,如下所示: func mapView(mapView: MKMapView!, didSelectAnnotationView view: MKAnnotationView!) { let calloutView = UIView(frame: CGRect(x: 0, y: 0, width: 300, height: 120)) calloutView.backgroundColor = UIColor.purpleColor() calloutView.center = CGPointMake(CGRectGetWidth(view.bounds) / 2.0, 0.0) calloutView.layer.anchorPoint = CGPointMake(0.5, 1.0) calloutView.layer.masksToBounds = false calloutView.userInteractionEnabled = true let calloutViewTapRecognizer = UITapGestureRecognizer(target: self, action: "onCalloutViewTap") calloutView.addGestureRecognizer(calloutViewTapRecognizer)
  • 如何检查已触摸对象的 ID (iOS)(How to check an ID of a object that has been touched (iOS))
    问题 在我的视图中,我有一个包含一堆不同点的数组,然后我通过循环运行该数组以在视图中创建一堆不同的方块。 您还可以看到我尝试使用可访问性标识符来创建类似系统的 ID。 这可能是一个非常糟糕的做法,但我没有想法哈哈。 这是视图: #import "LevelOneView.h" @implementation LevelOneView @synthesize squareLocations; - (id)initWithFrame:(CGRect)frame { self = [super initWithFrame:frame]; if (self) { // Initialization code } return self; } - (void)drawRect:(CGRect)rect { squareLocations = [[NSMutableArray alloc] init]; CGPoint dotOne = CGPointMake(1, 25); [squareLocations addObject:[NSValue valueWithCGPoint:dotOne]]; CGPoint dotTwo = CGPointMake(23, 25); [squareLocations addObject:[NSValue valueWithCGPoint:dotTwo]
  • 转发触摸到UIScrollView(Forward touches to a UIScrollView)
    问题 我有两个视图控制器。 视图控制器A具有UIScrollView并呈现视图控制器B。呈现是交互式的,并由scrollView.contentOffset控制。 我想集成一个交互式的关闭过渡:向上平移时,应该以交互方式关闭ViewControllerB。 交互式关闭过渡还应该控制ViewController A scrollView。 我的第一次尝试是使用UIPanGestureRecognizer并根据平移距离设置scrollView.contentOffset 。 这是可行的,但是当平移手势结束时,必须将scrollView偏移量设置为动画到结束位置。 使用-[UIScrollView setContentOffset:animated:不是一个好的解决方案,因为它使用了线性动画,没有考虑当前的平移速度,并且不能很好地减速。 因此,我认为应该有可能将我的平移手势识别器中的触摸事件输入到滚动视图中。 这应该给我们所有不错的滚动视图动画行为。 我尝试覆盖UIPanGestureRecognizer子类中的-touchesBegan/Moved/Ended/Cancelled withEvent:方法,如下所示: - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [scrollView
  • CGRectContainsPoint does not work on different views
    I am making a simple drag drop project. When I use CGRectContainsPoint to drag a view and drop on different view it works. But both of the view should be in a same view. Now let's say I have a view called "A" and it contains two views. One UIView and one UIStackView. If I drag a view inside of Stack View to UIView it does not drop. Simply CGRectContainsPoint does not work for dragging and dropping from different views. Is there any way to solve it?
  • 使用hitTest:withEvent捕获子视图在其父视图框架之外的触摸:(Capturing touches on a subview outside the frame of its superview using hitTest:withEvent:)
    问题 我的问题:我有一个EditView基本上占据了整个应用程序框架,一个Subview MenuView仅占据了底部约20%,然后MenuView包含了它自己的子视图ButtonView ,它实际上位于MenuView的范围之外(某些东西像这样: ButtonView.frame.origin.y = -100 )。 (注意: EditView具有其他子视图,这些子视图不属于MenuView的视图层次结构,但可能会影响答案。) 您可能已经知道这个问题:当ButtonView在MenuView的范围内时(或更具体地说,当我的触摸在MenuView的范围内时), ButtonView响应触摸事件。 当我接触的都是外面MenuView的界限(但仍然在ButtonView的界限),是由没有接收到触摸事件ButtonView 。 例子: (E)是EditView ,所有视图的父级 (M)是MenuView ,是EditView的子视图 (B)是ButtonView ,是MenuView的子视图 图表: +------------------------------+ |E | | | | | | | | | |+-----+ | ||B | | |+-----+ | |+----------------------------+| ||M || || || |+--------------
  • 检测是否在其他UIView中触摸了某些UIView(Detect if certain UIView was touched amongst other UIViews)
    问题 我有3个UIView,位于一个大uiview的顶部。 我想知道用户是否触摸顶部的那个,而不关心其他的那个。 我将在第二个UIView中有几个按钮,在第三个UIView中有一个UITable。 问题是我在第一个视图上打开了userInteractionEngabled并起作用,但是即使关闭了所有其他视图,它们也以相同的方式响应。 如果我在self.view上禁用userInteractionEnabled,则它们都不响应。 我也无法检测到touchesBegan委托方法中触摸了哪个视图。 我的代码: UIView *aView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 150)]; aView = userInteractionEnabled = YES; [self.view addSubview:aView]; UIView *bView = [[UIView alloc] initWithFrame:CGRectMake(0, 150, 320, 50)]; bView.userInteractionEnabled = NO; [self.view addSubview:bView]; -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *
  • 指向旋转的 CGRect 内(Point inside a rotated CGRect)
    问题 您将如何正确确定一个点是否在旋转的 CGRect/框架内? 框架使用 Core Graphics 旋转。 到目前为止,我已经找到了一种算法来计算一个点是否在三角形内,但这并不是我所需要的。 被旋转的框架是一个带有几个子视图的常规 UIView。 回答1 假设您使用transform属性来旋转视图: self.sampleView.transform = CGAffineTransformMakeRotation(M_PI_2 / 3.0); 如果再有一个手势识别,例如,你可以看到,如果用户使用在该位置挖掘locationInView与旋转视图,并为您的旋转自动因素: - (void)handleTap:(UITapGestureRecognizer *)gesture { CGPoint location = [gesture locationInView:self.sampleView]; if (CGRectContainsPoint(self.sampleView.bounds, location)) NSLog(@"Yes"); else NSLog(@"No"); } 或者您可以使用convertPoint : - (void)handleTap:(UITapGestureRecognizer *)gesture { CGPoint
  • iOS 7 SpriteKit - 创建游戏菜单/按钮(场景与更多视图控制器)(iOS 7 SpriteKit - Creating game menus/buttons (Scenes vs. more view controllers))
    问题 所以,我已经开始在 SpriteKit 中开展一个项目,我希望能够用几个按钮实现一个“主菜单”场景。 一个是关卡选择屏幕,一个是选项等。然后从关卡选择屏幕,会有几个其他按钮,当被选中时将开始游戏并加载选定的关卡。 我的问题是:项目应该如何设置? 每个屏幕(关卡选择、主菜单、选项)都应该是自己的场景并有一个主视图控制器吗? 或者我应该为所有东西设置多个视图控制器? 或者也许每个级别的视图控制器(尽管这没有太大意义)由故事板中的 NavigationController 管理? 在稍微玩弄它并在线阅读之后,我注意到我可以使用视图控制器为我的主菜单设置 UIButton。 然而,他们坚持通过精灵套件场景变化,这不是我想要的。 这意味着我必须将按钮设置为隐藏在每个显示的新场景中,这让我很担心,因为我不确定按钮究竟发生了什么。 我知道可以使用 SKSpriteNodes 创建按钮(类似于 Graf 发布的并且很多人都使用过的类)。 那是更好的选择吗? 我不会在 VC 上使用 UIButtons,而是检查是否在 touchBegan 方法和 touchesEnded 方法中对该按钮节点进行了触摸,如下所示: UITouch *touch = [touches anyObject]; CGPoint location = [touch locationInNode:self]
  • touchesBegin&touches移动Xcode对象C的问题(touchesBegin & touchesMove Xcode Obj C Question)
    问题 因此,当您按住并拖动时,我的应用程序运行良好。 我还将UIButtons在Interface Builder中设置为Touch Down。 同样,当您拖动时,您需要从UIButton的外部拖动。 您不能单击 UIButton 并拖动到另一个。 移动的触摸板: 代码: -(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *touch = [[event touchesForView:self.view] anyObject]; CGPoint location = [touch locationInView:touch.view]; if(CGRectContainsPoint(oneButton.frame, location)) { if (!oneButton.isHighlighted){ [self oneFunction]; [oneButton setHighlighted:YES]; } }else { [oneButton setHighlighted:NO]; } // if(CGRectContainsPoint(twoButton.frame, location)) { if (!twoButton.isHighlighted){ [self
  • 通过 UIGestureRecognizer 同时处理两个不同点的点击(handle taps in two different points at a same time via UIGestureRecognizer)
    问题 我在两个不同的位置有两个标签,当同时点击两个标签时,我希望另一个标签显示成功消息。 我该如何实现? 我可以通过一个或多个手指触摸识别单击或双击,但这是不同的情况。 请帮忙。 我试过这个,但它不起作用。 UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)]; tapRecognizer.numberOfTapsRequired = 1; tapRecognizer.numberOfTouchesRequired = 2; tapRecognizer.delegate = self; [self.view addGestureRecognizer:tapRecognizer]; -(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch { if (touch.view == tap2 && touch.view == tap1) { result.text = @"success"; } return YES; } 提前致谢。 回答1
  • 应用UIView变换后查找框架坐标(CGAffineTransform)(Find Frame Coordinates After UIView Transform is Applied (CGAffineTransform))
    问题 我使用CGAffineTransform旋转视图 [view setTransform:newTransform]; 应用变换后,帧值保持不变,但是如何找到该帧的“旋转”或变换后的值? (来源:informit.com) 我想要旋转的框架边缘的确切坐标,即a,b,c,d点。 回答1 要记住的一件事是,变换会更改坐标系,因此您将需要能够在父“视图”和子“已变换”视图之间进行转换。 同样,变换保留变换对象的中心,但不保留任何其他坐标。 因此,您需要根据中心来计算事物。 并且,您将需要几个帮手。 (我从Erica Sadun的《 Core iOS Developer的食谱》一书中获得了以下大多数方法)。 我通常将它们添加为UIView上的类别。 为了将孩子的坐标转换为父母的坐标,您需要类似以下内容: // helper to get pre transform frame -(CGRect)originalFrame { CGAffineTransform currentTransform = self.transform; self.transform = CGAffineTransformIdentity; CGRect originalFrame = self.frame; self.transform = currentTransform; return