2009-07-28 9 views
2

Ich habe erfolgreich eine benutzerdefinierte Tastatur erstellt, die ähnlich wie die Tastatur von Apple funktioniert. Es gibt eine Sache, die anders bleibt. Auf der iPhone-Tastatur von Apple kann der Benutzer mit dem Finger über die Tastatur streichen und alle Tasten, die sie passieren, werden angezeigt. Auf meiner Tastatur passiert das nicht. Wenn Sie mit Ihrem Finger über den Bildschirm fahren, wird der erste Knopf, den ich berührt habe, angezeigt. Wenn ich weit genug entfernt bin, geht er wieder nach unten. Ich bin derzeit mit diesen Code für die Pop-up-Tasten:Hover over State für UIButton auf dem iPhone

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

Keyone ein UIButton ist, und ich bin ein Bild des größeren Zeichen überlagert, wenn der Benutzer „Highlights“ oder die Taste auf der Tastatur tippt. Gibt es einen ähnlichen Zustand, der nur "schwebt", so dass, wenn der Benutzer die Q-Taste hervorhebt und ihren Finger über die W-Taste gleitet, die W-Taste hervorgehoben wird?

+0

Sie auch eine 5-Rating-System anzupassen, wie http://stackoverflow.com/a/4667025/676822 versuchen könnte prüfen, zu erreichen, was Sie – Lucas

Antwort

0

Werfen Sie einen Blick auf die UIControlEvents-Enumeration. Dies sind alle Ereignisse, die Sie für eine bestimmte Ansicht erfassen können.

Wenn ich raten müsste, würde ich sagen, dass Sie diese Funktionalität wahrscheinlich mithilfe einer Kombination aus TouchDown und der TouchDrag-Serie replizieren könnten. Verwenden Sie TouchUp, um zu erfassen, welche Taste berührt wurde.

0

können Sie die touchesMoved verwenden: withevent: Methode des Containers UIView und drücken Test jeder Subview (aka, Schlüssel) mit so etwas wie:

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

Die Idee ist, die Touch-Sequenz mit der übergeordneten Ansicht zu verarbeiten . Dies ist ein einfacher Weg, um eine Sequenzbeendigung zu vermeiden, wenn die Berührung außerhalb der "heißen Zone" für die Untersicht (UIControl *) bewegt wird.

6

Ich habe für meine App, Compounds, eine Periodic-Table-Tastatur implementiert.

Verwenden Sie keine UIB-Tasten.

Tastatur anzuzeigen, verwenden entweder: UIViews oder CALayers die einzelnen Tasten angezeigt werden

OR

Eine statische PNG. Es ist viel einfacher auf Speicher und "Zippier". (Dies ist, was ich für mein noch zu kommen Update getan habe)

Sie müssen alle Berührungen mit der übergeordneten Ansicht verfolgen. (Small hinzugefügt beiseite am Boden zu erklären, warum das so ist) Implementieren Sie die Berührungen Methoden wie so:

- (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]; 
} 

Diese Methoden die Schlüssel bekommen und angemessen „vergrößern“, um die ausgewählte Taste.

Ich führe den Punkt gegen ein Array von CGRects, um den Tastendruck zu bestimmen (dies ist schneller im Vergleich zum Treffertest).

- (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]; 
     } 
    } 

Es gibt ein paar Methoden für Sie zu implementieren, aber es ist ziemlich einfach. Sie erstellen im Grunde eine Ansicht, die ein vergrößerter Schlüssel ist. Dann bewegen Sie es herum, während der Benutzer seinen Finger schiebt.


Abgesehen:

Sie können nicht berührt mit Subviews verfolgen, denn sobald eine Berührung durch einen Blick verfolgt wird, es setzt die Note bis touchesEnded verfolgen: (oder touchesCancelled :) genannt wird.Das heißt, sobald der Buchstabe "Q" eine Berührung verfolgt, hat kein anderer Schlüssel Zugriff auf diese Berührung. Selbst wenn Sie über den Buchstaben "W" schweben. Dies ist ein Verhalten, das Sie anderswo zu Ihrem Vorteil nutzen können, aber in dieser Situation müssen Sie umgehen, indem Sie eine "Elternansicht" haben, deren Aufgabe es ist, Berührungen zu verfolgen.


(aktualisiert Speicherleck zu beheben)

+0

Nizza wollen. Es wird wahrscheinlich den Code ein wenig vereinfachen, wenn Sie den 'MagnifiedKeyController' direkt von der Fledermaus anstelle von faul instanziieren. Gerade jetzt, ich denke, Sie haben ein Speicherleck, wenn die 'MagnifiedKey' -Eigenschaft eine Retain-Eigenschaft ist. Selbst wenn es sich um eine assign-Eigenschaft handelt, ist es ungewöhnlich, während des Dealloc-Vorgangs ein Eigenschafts-ivar zu vergeben. –

+0

Es ist eine Retain-Eigenschaft und es wird in Dealloc freigegeben, aber Sie haben Recht: Ich brauche eine Autorelease in, wenn ich es instanziiere. Sie können am Anfang instanziieren und einige "ifs" loswerden. Es ist nur ein Objekt, also ist das Vorladen keine schlechte Idee. –