1

我添加了一些视图作为子视图并处理 UILongPressGestureRecognizer (这是识别我已将手指放在 UI 元素中的正确手势吗??)和 UIPanGestureRecognizer 以在屏幕中移动视图(请参阅我以前的问题以获得想法我正在建造的东西-> SO

我想在放手指时添加动画(翻转,像小缩放一样),然后在移动视图时重新排列其他视图,最后放置并重新排列视图。

我的第一个问题是,当长按视图时,手势被识别,但是虽然这个手势还没有结束,但我无法将视图移动到屏幕上并重新定位。我该如何解决这个问题?LongPress 一个 UI 元素 (UIMyView) 为这个事件做任何动画,然后不拿走我的手指开始移动它,就像 PanGesture 已经在工作一样。

创建了一个 UIView 子类并在其中添加了所需的 UIGestureRecognizers。

我使用 NSNotificationCenter 通知 MainViewController 发生了手势,因此我可以更改视图的布局(这是正确的方法,或者我可以将这个手势以其他方式发生推送到我的超级视图控制器,例如将事件推送到下一个响应者) ?

我使用 drawTextInRect 方法将字符绘制到视图的大小,这就是为什么我不能只更改视图内部的布局。

在 MainViewController 中,我在 NSNotification 观察者选择器中为特定视图调用 setNeedsDisplay,但是在拖动它时不起作用,它只显示一个空的白色视图,就像我需要的视图已更改但尚未显示线程暂停的原因或某物。

当 PanGesture 结束时,我再次通知 MainViewController 并再次调用 setNeedsDisplay,但现在它可以工作,除了我设置的背景颜色(并且已设置),保持在拖动时应显示的先前条件,但角色再次正确绘制。

我的思想进入了线程!?

[编辑] 一些代码示例:

   // Inside the UIMyView
-(void) touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event
{
     [[NSNotificationCenter defaultCenter] postNotificationName:@"MyViewNotification" object:self];
    // Here I will put my animations, not yet proceed with them
    // Code for lastLocation
    isViewTouched = YES;
    [self setNeedsDisplay];
}
- (void) touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event
{
     // code for moving the View with finger
}

-(void) touchesEnded:(NSSet*)touches withEvent:(UIEvent*)event
{
  isViewTouched = NO;
  [self setNeedsDisplay];
}

-(void) drawLayout
{
  UILabel* labelToDraw = [[UILabel alloc] init];
  labelToDraw.text = @"1";
  labelToDraw.font = [self getFont];
  labelToDraw.textcolor = [UIColor blackColor];
  self.backgroundColor = [UIColor whiteColor];
  [labelToDraw drawTextInRect:self.bounds];
}
// The same method with other color values and text exist for another layout.
// Called inside of drawRect:(CGRect)rect when calling setNeedsDisplay as I know and it is

-(void) drawRect:(CGRect)rect
{
  if (isViewTouched) [self drawLayout];
  else [self drawLayoutMoving];
}
    //Superview Controller notified
-(void) handleMyViewNotification:(NSNotification*)notification
{
  myViewMoving = [notification object];
  [self performSelectorInbackground:@selector(manageArrayOfMyViews) withObject:nil];
}

-(void) manageArrayOfMyViews
{
  // animate and reorder the array of views not touched
}

我是 Objective-C 的新手,所以我在这里遗漏了一些东西,我想知道我的方法总体上是否正确。

谢谢你。

4

1 回答 1

1

手势识别器似乎不是解决问题的最简单方法。尝试使用

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

检测触摸的开始并播放开始动画。然后

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

拖动您的视图。和

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

当手指不再出现在屏幕上时,进行最终设置。

例如:

- (void)touchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
   UITouch *touch = [touches anyObject];
   if ([touch.view isKindOfClass: [MyView class]]) {
      //play animation on touch.view
      lastLocation = [touch locationInView: self.view];
   }
}

- (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event {
   UITouch *touch = [touches anyObject];
    if ([touch.view isKindOfClass: [MyView class]]) {
       CGPoint location = [touch locationInView: self.view];

       CGFloat xDisplacement = location.x - lastLocation.x;
       CGFloat yDisplacement = location.y - lastLocation.y;

       CGRect frame = touch.view.frame;
       frame.origin.x += xDisplacement;
       frame.origin.y += yDisplacement;
       touch.view.frame = frame;
   }
}

[编辑]

正如我从您的代码中猜想的那样,您正在尝试在要移动的视图顶部绘制一个带有数字的标签。您不需要实现自定义 drawRect 方法,您的任务可以更轻松地完成。当您创建一个稍后将要拖动的视图时,您添加一个 UILabel 作为子视图并按照您想要的方式对其进行自定义:

UIView* viewToDrag = [[UIView alloc] initWithFrame: // your frame];
UILabel* subLabel = [[UILabel alloc] initWithFrame: CGRectMake(0, 0, viewToDrag.frame.size.width, viewToDrag.frame.size.height)];
 subLabel.tag = 0xff; // example tag, you can define it 
 [self customizeStaticLabel: subLabel]; //subroutine to customize your usual label appearance: set text, font, etc
[viewToDrag addSubview: subLabel];
[self.view addSubview: viewToDrag];

//insert release calls for subLabel and viewToDrag if you're NOT using ARC

仅此而已,您的标签现在是可拖动视图的子项。而且您不需要任何通知,也不需要调用 setNeedsDisplay。

拖动视图时,可以更改视图的 subLabel:

UILabel* labelToChange = (UILabel*)[touch.view viewWithTag: 0xff]; //this will get a subview label
[self customizeDraggedLabel: labelToChange];

在 touchesEnded 中,你需要让你的标签恢复正常状态,所以

UILabel* labelToChange = (UILabel*)[touch.view viewWithTag: 0xff];
[self customizeStaticLabel: labelToChange];

以及更改标签外观的子程序,例如:

-(void) customizeStaticLabel: (UILabel*) label{
   label.textColor = [UIColor redColor];
}

-(void) customizeDraggedLabel: (UILabel*) label{
   label.textColor = [UIColor blackColor];
}
于 2012-07-12T13:37:32.130 回答