2009-07-28 47 views
2

我成功创建了一个自定义键盘,其功能类似于Apple的键盘。有一点仍然不同。在Apple的iPhone键盘上,用户可以通过键盘轻扫他们的手指,并且他们通过的所有按键都会弹出。在我的键盘上,这不会发生。用手指擦拭手指只会导致我碰到的第一个按钮弹出,而当我距离足够远时它会回落。我目前使用此代码为弹出键:悬停在iPhone上的UIButton状态

UIImage *bigLetter = [UIImage imageNamed:@"letter1.png"]; 
[keyOne setImage:bigLetter forState:UIControlStateHighlighted]; 

keyOne是一个UIButton,当用户“亮点”,或轻敲键盘上的键,我将覆盖更大的字符的图像。是否有类似的状态只是“悬停”,以便如果用户突出显示Q键并将他们的手指滑动到W键上,则W键突出显示?

+0

你也可以考虑在努力适应一个5等级系统,如http://stackoverflow.com/a/4667025/676822来完成你想要什么 – Lucas 2013-01-22 16:50:40

回答

0

查看UIControlEvents枚举。这是您可以为特定视图捕捉的所有事件。

如果我不得不猜测,我会说你可以使用TouchDown和TouchDrag系列的一些组合来复制这个功能。使用TouchUp来捕捉被触摸的键。

0

可以使用touchesMoved:withEvent:方法你的容器的UIView的方法和喜欢的东西击中测试每个子视图(又名键):

for(key in keys){ 
    location = [touch locationInView:key]; 
    if([key pointInside:location withEvent:event]){ 
    // if not already animated or otherwise triggered, trigger 
    } 
} 

的想法是使用父视图处理触摸序列。当触摸移动到(UIControl *)子视图的“热区”之外时,这是避免顺序终止的简单方法。

6

我为我的应用程序,化合物实施了周期表键盘。

不要使用UIButtons。

要显示你的键盘,使用: UIViews或CALayers显示各个键

OR

静态PNG。记忆和“zippier”更容易。 (这是我为我的未来更新所做的)

您必须使用父视图跟踪所有触摸。 (小抛开添加在底部来解释为什么会是这样)执行触摸方法,像这样:

- (void)touchesBegan: (NSSet *)touches 
      withEvent: (UIEvent *)event { 
    NSLog(@"TouchDown"); 

    CGPoint currentLocation = [[touches anyObject] locationInView:self.view]; 
    [self magnifyKey:[self keyAtPoint:currentLocation]]; 
} 

-(void)touchesMoved: (NSSet *)touches 
      withEvent: (UIEvent *)event { 
    NSLog(@"TouchMoved"); 

    CGPoint currentLocation = [[touches anyObject] locationInView:self.view]; 
    [self magnifyKey:[self keyAtPoint:currentLocation]];  
} 


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

    NSLog(@"TouchUp"); 

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

    int key = [self keyAtPoint:currentLocation]; 
    [self selectKey:aKey]; 
} 

这些方法拿到钥匙,并适当地“放大”的选择键。

我对CGRects数组运行该点以确定按键(这与点击测试相比更快)。

- (int)keyAtPoint:(CGPoint)aPoint{ 

    int aKey=1; 
    for(NSString *aRect in keys){ 
     if(CGRectContainsPoint(CGRectFromString(aRect), aPoint)){ 
      break; 
     } 
     aKey++; 
    } 

    if(aKey==kKeyOutOfBounds) 
     aKey=0; 
    NSLog([NSString stringWithFormat:@"%i",aKey]); 
    return aKey; 
} 


- (void)magnifyKey:(int)aKey{ 

     if(aKey!=0) { 

      if(magnifiedKey==nil){ 

       self.magnifiedKey = [[[MagnifiedKeyController alloc] initWithKey:aKey] autorelease]; 
       [self.view addSubview:magnifiedKey.view];  

      }else{ 

       [magnifiedKey setKey:aKey]; 
       if([magnifiedKey.view superview]==nil) 
        [self.view addSubview: magnifiedKey.view];  

      } 

     }else{ 

      if(magnifiedKey!=nil) 
       [magnifiedKey.view removeFromSuperview]; 
     } 
    } 


    - (void)selectKey:(int)aKey{ 

     if(magnifiedKey!=nil){ 

      if(aKey!=0){ 

       [magnifiedKey flash]; 
       [self addCharacterWithKey:aKey]; 
      } 
      [magnifiedKey.view performSelector:@selector(removeFromSuperview) withObject:nil afterDelay:0.5]; 
     } 
    } 

有几种方法可供您实施,但它非常简单。你基本上正在创造一个放大的关键视图。然后在用户滑动手指时移动它。


旁白:

因为一旦触摸是由一个视图跟踪你不能跟踪与子视图触摸,它会继续跟踪触摸到touchesEnded:(或touchesCancelled :)被调用。这意味着,一旦字母“Q”正在跟踪触摸,其他键就无法访问该触摸。即使你在字母“W”上盘旋。这是一种可以在其他地方使用的行为,但在这种情况下,您必须通过拥有一个“父视图”来处理它,而“父视图”的作用是跟踪触摸。


(更新修复内存泄漏)

+0

尼斯。如果你将`MagnifiedKeyController`实例化为蝙蝠而非懒惰,它可能会简化代码。现在,如果`magnifiedKey`属性是retain属性,我认为你有内存泄漏。即使它是一个赋值属性,在dealloc期间释放一个赋值属性ivar也不常见。 – 2009-07-29 16:20:09