我成功创建了一个与Apple键盘功能类似的自定义键盘。有一件事情仍然不同。在Apple的iPhone键盘上,用户可以在键盘上滑动手指,弹出所有通过的键。在我的键盘上,这不会发生。将手指向上滑动只会导致我触摸的第一个按钮弹出,当我距离足够远时,它会向下移动。我目前正在使用此代码作为弹出键:
UIImage *bigLetter = [UIImage imageNamed:@"letter1.png"];
[keyOne setImage:bigLetter forState:UIControlStateHighlighted];
keyOne是一个UIButton,当用户“突出显示”或点击键盘上的键时,我覆盖了较大字符的图像。是否有类似的状态只是“悬停”,以便如果用户突出显示Q键并将其手指滑动到W键,W键会突出显示?
答案 0 :(得分: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”上面。这是您可以在其他地方使用的行为,但在这种情况下,您必须通过“父视图”来解决这个问题,其中“父视图”的工作是跟踪触摸。
(更新以修复内存泄漏)
答案 1 :(得分:0)
查看UIControlEvents枚举。这是您可以捕获特定视图的所有事件。
如果我不得不猜测我会说你可以使用TouchDown和TouchDrag系列的某些组合来复制这个功能。使用TouchUp来捕捉触摸的键。
答案 2 :(得分:0)
您可以使用容器UIView的touchesMoved:withEvent:方法并使用以下内容命中测试每个子视图(aka,key):
for(key in keys){
location = [touch locationInView:key];
if([key pointInside:location withEvent:event]){
// if not already animated or otherwise triggered, trigger
}
}
想法是使用父视图处理触摸序列。当触摸移动到(UIControl *)子视图的“热区”之外时,这是一种避免序列终止的简单方法。