2015-03-05 10 views
11

Mesajlaşma uygulaması geliştiriyorum ve iOS 8'deki tahmini klavyenin, bir ileti oluşturan kullanıcının bir önceki iletiye yanıt verdiğini algılamasını istiyorum.iOS tahmini klavye içeriği/kaynak metnini program aracılığıyla beslemek mümkün mü?

Bu nedenle, kestirim için bir bağlam sağlamak için klavyeye bir dize besleyebilmeyi istiyorum. Eğer bir kullanıcı polar olarak yorumlanabilecek bir soru sorulursa (evet/hayır), o zaman tahmin klavyesi Yes | No | Maybe

Bu geliştiriciler için kullanılabilir mi?

Özel bir klavye hakkında konuşmuyorum, sadece standart klavyeyi tahminleri için bazı bağlamları besliyorum. Ben de aslında hızlı tip cevaplar as in this question özelleştirme ile ilgili değilim. Klavyenin ne yazdığını bilmesini istiyorum.

cevap

8

Varsayılan klavyeye kesinlikle öneri girilmesi mümkün değildir. Bununla birlikte, kullanıcı için eşdeğer bir deneyim sunmak istiyorsanız, myTextView.autocorrectionType = UITextAutocorrectionTypeNo;'u kullanarak iOS öneri çubuğunu gizlerim ve ardından bu görünümü öneri görünümüne benzeyen kendi özel görünümümle değiştiririm. Kullanıcı bir karakter yazdığında veya bir seçenek seçtiğinde, özel öneri görünümünü gizleyip iOS öneri çubuğunu yeniden etkinleştirin.

UIInputView'ı bunun için sadece alt sınıflara ayırdım (saydamlık ve geçiş biraz kapalı, ancak her şey iyi çalışıyor güzel dak).

#import "SuggestionView.h" 

#define kScreenWidth [UIScreen mainScreen].bounds.size.width 

@implementation SuggestionView { 
    NSMutableOrderedSet *_suggestions; 
    NSMutableArray *_suggestionButtons; 
} 

- (instancetype)init { 
    self = [self initWithFrame:CGRectMake(0.0f, 0.0f, kScreenWidth, 36.0f)]; 

    if (self) { 

    } 

    return self; 
} 

- (instancetype)initWithFrame:(CGRect)frame { 
    self = [super initWithFrame:frame inputViewStyle:UIInputViewStyleKeyboard]; 

    if (self) { 
     _suggestions = [[NSMutableOrderedSet alloc] initWithCapacity:3]; 
     self.maxSuggestionCount = 3; 
     _suggestionButtons = [[NSMutableArray alloc] init]; 
     self.backgroundColor = [UIColor colorWithWhite:0.0f alpha:0.04f]; 
    } 

    return self; 
} 

#pragma mark - Modifying Suggestions 

- (void)addSuggestion:(NSString *)suggestion { 
    if (suggestion) { 
     [_suggestions addObject:suggestion]; 
    } 

    while (_suggestions.count > self.maxSuggestionCount) { 
     [_suggestions removeObjectAtIndex:self.maxSuggestionCount]; 
    } 
} 

- (void)removeSuggestion:(NSString *)suggestion { 
    [_suggestions removeObject:suggestion]; 
} 

- (void)setSuggestions:(NSObject *)suggestions { 
    if ([suggestions respondsToSelector:@selector(countByEnumeratingWithState:objects:count:)]) { 
     [_suggestions removeAllObjects]; 

     for (NSString *suggestion in (NSArray *)suggestions) { 
      if (_suggestions.count < self.maxSuggestionCount) { 
       [_suggestions addObject:suggestion]; 
      } else { 
       break; 
      } 
     } 
    } 
} 

- (NSArray *)suggestions { 
    NSMutableArray *suggestionsArray = [[NSMutableArray alloc] initWithCapacity:_suggestions.count]; 
    for (NSString *suggestion in _suggestions) { 
     [suggestionsArray addObject:suggestion]; 
    } 

    return suggestionsArray; 
} 

#pragma mark - Visual Layout of Suggestions 

- (void)layoutSubviews { 
    [self layoutSuggestions]; 
} 

- (void)layoutSuggestions { 
    for (UIView *subview in _suggestionButtons) { 
     [subview removeFromSuperview]; 
    } 

    [_suggestionButtons removeAllObjects]; 

    for (int i = 0; i < _suggestions.count; i++) { 
     NSString *suggestion = _suggestions[i]; 
     UIButton *suggestionButton = [[UIButton alloc] initWithFrame:CGRectMake(i * self.bounds.size.width/_suggestions.count, 0.0f, self.bounds.size.width/_suggestions.count, self.bounds.size.height)]; 
     [suggestionButton setTitle:suggestion forState:UIControlStateNormal]; 
     suggestionButton.titleLabel.adjustsFontSizeToFitWidth = YES; 
     suggestionButton.titleLabel.textAlignment = NSTextAlignmentCenter; 
     [suggestionButton setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; 
     [suggestionButton addTarget:self action:@selector(buttonTouched:) forControlEvents:UIControlEventTouchUpInside]; 
     [self addSubview:suggestionButton]; 

     if (i > 0) { 
      UIView *whiteLine = [[UIView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 0.5f, self.bounds.size.height)]; 
      whiteLine.backgroundColor = [UIColor whiteColor]; 
      [suggestionButton addSubview:whiteLine]; 
     } 

     [_suggestionButtons addObject:suggestionButton]; 
    } 
} 

#pragma mark - Selecting a Suggestion 

- (void)buttonTouched:(UIButton *)button { 
    NSTimeInterval animationDuration = 0.09f; 
    [UIView animateWithDuration:animationDuration animations:^{ 
     [button setBackgroundColor:[UIColor whiteColor]]; 

     if ([self.delegate respondsToSelector:@selector(suggestionSelected:)]) { 
      [self performSelector:@selector(suggestionSelected:) withObject:button.currentTitle afterDelay:animationDuration * 0.9f]; 
     } 

     [button performSelector:@selector(setBackgroundColor:) withObject:[UIColor clearColor] afterDelay:animationDuration]; 
    }]; 
} 

- (void)suggestionSelected:(NSString *)suggestion { 
    if ([self.delegate respondsToSelector:@selector(suggestionSelected:)]) { 
     [self.delegate suggestionSelected:suggestion]; 
    } 
} 

@end 

#import <UIKit/UIKit.h> 

@protocol SuggestionViewDelegate <NSObject> 

@required 
- (void)suggestionSelected:(NSString *)suggestion; 

@end 

@interface SuggestionView : UIInputView 

- (instancetype)init; 
- (instancetype)initWithFrame:(CGRect)frame; 

/** 
* The list of suggestions being displayed. 
* The array contains 0-3 strings. 
* 
* @return Array of NSString's representing the current suggested strings 
*/ 
- (NSArray *)suggestions; 

/** 
* Add a suggestion to display in the view. 
* If there are already maxSuggestionCount suggestions, the added suggestion will push one of them out. 
* If there are already maxSuggestionCount suggestions and the input is 'nil' then the last suggestion will be removed. 
* 
* @param suggestion String to suggest to the user 
*/ 
- (void)addSuggestion:(NSString *)suggestion; 

/** 
* Removes the suggestion from the list of displayed suggestions. 
* If the string is not in the set then there is no change made. 
* 
* @param suggestion NSString to remove from the suggested strings 
*/ 
- (void)removeSuggestion:(NSString *)suggestion; 

/** 
* Takes in either NSArray or NSSet and replaces 'suggestions' with the input. 
* Only the first three arguments are recognized. 
* Objects should be strings. Undefined behavior otherwise. 
* 
* @param suggestions NSArray or NSSet with 0-3 NSStrings 
*/ 
- (void)setSuggestions:(NSObject *)suggestions; 

@property (weak) id <SuggestionViewDelegate> delegate; 

/** 
* The maximum number of suggestions allowed. Default is 3. 
*/ 
@property (nonatomic) NSInteger maxSuggestionCount; 

@end 

, UITextField veya zaten subclassed ettik UITextView bir içine bu uygulamaya SuggestionView ithalat ve SuggestionViewDelegate uygulamak. Ardından UITextFieldDelegate (veya UITextViewDelegate) yöntemlerinde, ekleyin:

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField { 
    if ([textField isEqual:self.messageTextField]) { 
     if (self.suggestionView.suggestions.count > 0 && textField.text.length == 0) { 
      textField.inputAccessoryView = self.suggestionView; 
      textField.autocorrectionType = UITextAutocorrectionTypeNo; 
      [textField reloadInputViews]; 
     } 
    } 

    return YES; 
} 

- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string { 
    if ([textField isEqual:self.messageTextField]) { 
     if (string.length > 0) { 
      [self removeSuggestionView]; 
     } 
    } 

    return YES; 
} 


- (void)removeSuggestionView { 
    self.messageTextField.inputAccessoryView = nil; 
    [self.messageTextField setInputAccessoryView:nil]; 
    self.messageTextField.autocorrectionType = UITextAutocorrectionTypeYes; 
    [self.messageTextField reloadInputViews]; 

    [self.messageTextField performSelector:@selector(resignFirstResponder) withObject:self afterDelay:0.0f]; 
    [self.messageTextField performSelector:@selector(becomeFirstResponder) withObject:self afterDelay:0.0f]; 
} 

Sonra SuggestionViewDelegate uygulamak: Bu mükemmel bir çözüm olmasa da

- (void)suggestionSelected:(NSString *)suggestion { 
    [self.messageTextField setText:[NSString stringWithFormat:@"%@%@ ", self.messageTextField.text, suggestion]]; 
    [self removeSuggestionView]; 
} 

, istenilen etkiyi yaratmak gelmez.

+3

Birinin içeri girip "Evet, mümkün, sadece XYZ yap" diyeceğini umarken, bu inanılmaz bir cevap. Kodunuzu ve yaklaşımınızı paylaştığınız için teşekkür ederim - Keşke Apple'ın bunu açmasını isterdim, ancak WhatsApp, FB Messenger, Kik, vb. – sbauch

3

Resmi Apple Dokümantasyonunda bunun nasıl yapılacağı hakkında daha fazla bilgi bulmanın bir yolu olduğu için, bunun imkansız olduğunu düşünüyorum. iki seçeneğiniz vardır Ancak:

  • standart klavye tutun ve elle bunun üstüne (UIView örneği içinde) bir bar görüntüler.
  • özel klavyenizi sıfırdan (çok daha zor) oluşturun. read more here.

Ayrıca tamamen farklı bir UX hakkında düşünebilirsiniz. Örneğin,. Kullanıcınızın önerilerinizden birini seçmesi muhtemelse, sadece bu önerileri sunun ve özel bir giriş girmek için küçük bir tuş bırakın (ve klavyeyi burada iptal edin). Kullanıcının özel bir giriş girmesi muhtemel ise, yukarıdaki seçeneklerin her ikisine de bakın.

+0

Ne güzel cevap. – Cesare

+0

Bu büyük, özlü bir cevaptır (duymak istediğim kişi değil! Arghh !!!), teşekkürler. Ben ödül vermedim, ama diğer cevabı “en doğru” olarak seçmek zorunda hissediyorum.Tamamen farklı bir UX'in (benim için bu durumda), bir NLP/konuşmasal girdiden daha fazla 2 düğme daha kolay bir giriş yapmaya çalıştığım için işe yaramadığını düşünüyorum. – sbauch

+0

Sorun değil, diğer cevaplara ihtiyacınız olanı yapabileceksinizdir! –

İlgili konular