2015-02-04 9 views
9

키보드가 uitextview에서 열렸을 때 제안 된대로 특정 응용 프로그램 수준의 구문을 필요로하는 quicktype 제안을 원합니다.iOS 키보드의 quicktype 제안 사용자 정의

예를 들어 사용자가 "모두"를 입력 한 경우 - quicktype suggesstion에서 "모두 좋음"또는 "모두 예상대로"를 표시하려고합니다.

퀵팁 제안 텍스트를 사용자 정의 할 수 있습니까?

그렇지 않은 경우 키보드가 열렸을 때 표시 할 수있는 방법이 무엇일까요?

답변

8

quicktype 제안을 변경하는 방법이 없으므로 사용자 지정 제안을 입력 보조보기로 허용하기 위해 UIInputView를 하위 클래스로 만들었습니다 (투명도 및 전환은 다소 느리지 만 다른 모든 기능은 pretty) .

참고 : 이미 UITextField 또는 UITextView에 입력 액세서리보기가있는 경우이 기능이 작동하지 않습니다.

#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하거나 이미 서브 클래 싱 한 UITextView에이 기능을 구현하는 SuggestionView를 가져오고 SuggestionViewDelegate을 구현합니다. 그런 다음, UITextFieldDelegate (또는 UITextViewDelegate) 방법에서, 추가 :

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

다음, SuggestionViewDelegate 구현 :이 완벽한 해결책은 아니지만

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

을, 원하는 효과를 창출합니다.

+0

멋진 답변! 이것은 많은 도움이됩니다! 정말 고맙습니다. 이것은 분명히 더 많은 upvotes받을 자격이 ... – vib