让非Text输入类控件响应键盘弹出以及键盘输入——电子记分牌

效果图:


代码实现



重点是:实现<UITextInputTraits, UIKeyInput>

第一步:HXLDigitTestController.h实现


#import <UIKit/UIKit.h>

#import "HXLDigitInput.h"


@interface HXLDigitTestController :UIViewController{

   HXLDigitInput *digitInput;

}

@end



第二步:HXLDigitTestController.m实现


#import "HXLDigitTestController.h"


@interface HXLDigitTestController (private)


-(void)didBeginEditing:(id)sender;

-(void)didEndEditing:(id)sender;

-(void)textDidChange:(id)sender;

-(void)valueChanged:(id)sender;


@end


@implementation HXLDigitTestController


-(void)viewDidLoad{

    [superviewDidLoad];

    self.view.backgroundColor = [UIColorscrollViewTexturedBackgroundColor];

    

    digitInput = [[HXLDigitInputalloc]initWithNumberOfDigits:6];

   

    digitInput.digitOverlayImage = [UIImageimageNamed:@"digitOverlay"];

    digitInput.digitBackgroundImage = [UIImageimageNamed:@"digitControlBG"];

    

    //digitInput.backgroundView = digitBGView;

    

    digitInput.placeHolderCharacter =@"0";

    

    // we are using an overlayimage, so make the bg color clear color

    

    digitInput.digitViewBackgroundColor = [UIColorclearColor];

    digitInput.digitViewHighlightedBackgroundColor = [UIColorclearColor];

    

    digitInput.digitViewTextColor = [UIColorwhiteColor];

    digitInput.digitViewHighlightedTextColor = [UIColororangeColor];

    

    // we changed the default settings, so call redrawControl

    [digitInputredrawControl];

    

    [self.viewaddSubview:digitInput];


    // adding the target,actions for available events

    [digitInputaddTarget:selfaction:@selector(didBeginEditing:)forControlEvents:UIControlEventEditingDidBegin];

    [digitInputaddTarget:selfaction:@selector(didEndEditing:)forControlEvents:UIControlEventEditingDidEnd];

    [digitInputaddTarget:selfaction:@selector(textDidChange:)forControlEvents:UIControlEventEditingChanged];

    [digitInputaddTarget:selfaction:@selector(valueChanged:)forControlEvents:UIControlEventValueChanged];

}


// dismissing the keyboard

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

    [digitInputresignFirstResponder];

}


-(void)viewWillLayoutSubviews{

    [superviewWillLayoutSubviews];

    digitInput.frame =CGRectMake(10,90,self.view.frame.size.width-20,55);

}


/// recating on demo events ///

-(void)didBeginEditing:(id)sender{

   HXLDigitInput *input= (HXLDigitInput*)sender;

    NSLog(@"did begin editing %i",input.value);

}


-(void)didEndEditing:(id)sender{

    HXLDigitInput *input = (HXLDigitInput *)sender;

    NSLog(@"did end editing %i",input.value);

}


-(void)textDidChange:(id)sender{

    HXLDigitInput *input = (HXLDigitInput *)sender;

    NSLog(@"text did change %i",input.value);

}


-(void)valueChanged:(id)sender{

    HXLDigitInput *input = (HXLDigitInput *)sender;

    NSLog(@"value changed %i",input.value);

}


@end



第三步:HXLDigitInput.h

#import <UIKit/UIKit.h>


@interface HXLDigitInput :UIControl <UITextInputTraits,UIKeyInput>

{

    

    @protected

    NSInteger currentIndex;        // The current active digitview index

    NSMutableArray *digitViews;    // array containt UILabels

    NSString *activeString;        // The current string representation of all digitviews

    NSMutableArray *bgImageViews;   // The background imageviews for all digitViews

}


@property (nonatomic,assign)NSInteger numberOfDigits;                    // number of digitViews

@property (nonatomic,assign)NSInteger value;                             // value represented by the digitViews

@property (nonatomic,assign)BOOL matchNumberOfDigitsWithValueLength;     // sets number of digits according to value legth



Digit View Appearance /


// After changing something here call -(void)redrawControl afterwards


@property (nonatomic,strong)NSString *placeHolderCharacter;                  // Placeholder for empty digitView, default is 0


@property (nonatomic,assign)CGFloat digitPadding;                            // space between digitviews

@property (nonatomic,strong)UIView *backgroundView;                          // Background view of the control

@property (nonatomic,strong)UIColor *backgroundColor;

@property (nonatomic,strong)UIColor *highlightedBackgroundColor;


@property (nonatomic,strong)UIImage *digitBackgroundImage;                   // backgroundImage vor digitview

@property (nonatomic,strong)UIImage *digitOverlayImage;                      // Overlayimage vor digitview

@property (nonatomic,strong)UIColor *digitViewBackgroundColor;               // set to clearcolor when using digitBackgroundView

@property (nonatomic,strong)UIColor *digitViewHighlightedBackgroundColor;    // set to clearcolor when using digitBackgroundView

@property (nonatomic,strong)UIColor *digitViewTextColor;

@property (nonatomic,strong)UIColor *digitViewHighlightedTextColor;

@property (nonatomic,strong)UIFont *digitViewFont;

@property (nonatomic,strong)UIColor *digitViewShadowColor;

@property (nonatomic,assign)CGSize digitViewShadowOffset;

@property (nonatomic,strong)UIColor *digitViewHighlightedShadowColor;

@property (nonatomic,assign)CGSize digitViewHighlightedShadowOffset;


-(id)initWithNumberOfDigits:(NSInteger)digitCount;


/*

 Redraws the control, needed after setting colors, fonts, and sizes

 */

-(void)redrawControl;


@end



第四步:HXLDigitInput.m

#import "HXLDigitInput.h"


#define kDefaultDigitPadding 5.0f

#define kDefaultPlaceHolderCharacter @"0"


#define kDefaultHighlightedBackgroundColor [UIColor blueColor]

#define kDefaultNormalBackgroundColor [UIColor greenColor]


#define kDefaultHighlightedTextColor [UIColor whiteColor]

#define kDefaultNormalTextColor [UIColor blackColor]


#define kDefaultNormalShadowOffset CGSizeMake(0.0,1.0)

#define kDefaultHighlightedShadowOffset CGSizeMake(0.0,-1.0)


#define kDefaultNormalShadowColor [UIColor clearColor]

#define kDefaultHighlightedShadowColor [UIColor clearColor]


#define kDefaultFont [UIFont boldSystemFontOfSize:30]


#define kControlBackgroundColor [UIColor clearColor]

#define kControlHighlightedBackgroundColor [UIColor clearColor]


@interface HXLDigitInput (private)


-(void)setupDigitViews;

-(void)highlightIndex:(NSInteger)indexToHighlight;

-(void)unhighlightAll;

-(void)setText:(NSString *)text ForIndex:(NSInteger)index;



@end


@implementation HXLDigitInput


@synthesize value = _value;

@synthesize matchNumberOfDigitsWithValueLength =_matchNumberOfDigitsWithValueLength;

@synthesize numberOfDigits =_numberOfDigits;


@synthesize placeHolderCharacter =_placeHolderCharacter;


@synthesize digitPadding =_digitPadding;

@synthesize backgroundView =_backgroundView;

@synthesize digitOverlayImage =_digitOverlayImage;

@synthesize digitBackgroundImage =_digitBackgroundImage;


@synthesize backgroundColor =_backgroundColor;

@synthesize highlightedBackgroundColor =_highlightedBackgroundColor;


@synthesize digitViewBackgroundColor =_digitViewBackgroundColor;

@synthesize digitViewHighlightedBackgroundColor =_digitViewHighlightedBackgroundColor;

@synthesize digitViewTextColor =_digitViewTextColor;

@synthesize digitViewHighlightedTextColor =_digitViewHighlightedTextColor;

@synthesize digitViewFont =_digitViewFont;

@synthesize digitViewShadowColor =_digitViewShadowColor;

@synthesize digitViewShadowOffset =_digitViewShadowOffset;

@synthesize digitViewHighlightedShadowColor =_digitViewHighlightedShadowColor;

@synthesize digitViewHighlightedShadowOffset =_digitViewHighlightedShadowOffset;


/// Initialization ///

#pragma mark - Initializaion


-(id)init{

   self = [superinit];

    if (self) {

        // setting a default background view

        _backgroundColor = kControlBackgroundColor;

        _highlightedBackgroundColor =kControlHighlightedBackgroundColor;


       _backgroundView = [[UIViewalloc]init];

        _backgroundView.backgroundColor =_backgroundColor;

        [selfaddSubview:_backgroundView];

        

        // creating the array that holds the digit views and the bg image views

        

       digitViews = [[NSMutableArrayalloc]init];

       bgImageViews = [[NSMutableArrayalloc]init];

        

        // setting a dafault digitview appearance

        

        _digitViewHighlightedBackgroundColor =kDefaultHighlightedBackgroundColor;

        _digitViewBackgroundColor =kDefaultNormalBackgroundColor;

        

        _digitViewHighlightedTextColor =kDefaultHighlightedTextColor;

        _digitViewTextColor =kDefaultNormalTextColor;

        

        _digitViewShadowColor =kDefaultNormalShadowColor;

        _digitViewShadowOffset =kDefaultNormalShadowOffset;

        

        _digitViewHighlightedShadowOffset =kDefaultHighlightedShadowOffset;

        _digitViewHighlightedShadowColor =kDefaultHighlightedShadowColor;

        

        _digitViewFont =kDefaultFont;

        

        _matchNumberOfDigitsWithValueLength =NO;

        

        _placeHolderCharacter =kDefaultPlaceHolderCharacter;

    }

    return self;

}


-(id)initWithNumberOfDigits:(NSInteger)digitCount{

   self = [selfinit];

    if (self) {

        [self setNumberOfDigits:digitCount];

    }

    return self;

}


-(void)redrawControl{

    [selfsetupDigitViews];

}


Overriden property setters ///

#pragma mark - overriden property setters

-(void)setPlaceHolderCharacter:(NSString *)placeHolderCharacter

{

   if (placeHolderCharacter.length >1) {

        NSRange range;

        range.length =1;

        range.location =0;

        

       _placeHolderCharacter = [placeHolderCharactersubstringWithRange:range];

       @throw [NSExceptionexceptionWithName:@"PlaceholderCharacterTooLong"reason:@"The Placeholder character must be an NSString with a maximum length of 1"userInfo:nil];

    }else {

       _placeHolderCharacter = placeHolderCharacter;

    }

    // redraw everything

    [selfsetupDigitViews];

}


-(void)setMatchNumberOfDigitsWithValueLength:(BOOL)matchNumberOfDigitsWithValueLength{

   _matchNumberOfDigitsWithValueLength = matchNumberOfDigitsWithValueLength;

    // redraw everthing

    [selfsetValue:_value];

}


// Override property setter

-(void)setNumberOfDigits:(NSInteger)numberOfDigits{

   _numberOfDigits = numberOfDigits;

    if (numberOfDigits > 9) {

        @throw [NSExceptionexceptionWithName:@"NSRangeExeption"reason:@"To many digits for NSInteger"userInfo:nil];

    }

    [self setupDigitViews];

}


// Set a new integer value

-(void)setValue:(NSInteger)value{

    // do magic for displaying

    _value = value;

   NSString *valueString = [NSStringstringWithFormat:@"%i",value];

   activeString = valueString;

   int valueStringLength = valueString.length;

    // if lenght of value is bigger than

    // the number of digit view we set up

    // a new number according to the length, but

    // only if matchNumberOfDigitsWithValueLength is TRUE

    if (_matchNumberOfDigitsWithValueLength) {

       self.numberOfDigits = valueStringLength;

    }

    int padding = _numberOfDigits-valueStringLength;

   if (padding < 0) {

        padding =0;

    }

    int currentPos = 0;

   int stringIndex =0;

    

   for (UILabel *digitViewindigitViews) {

        if (currentPos >= padding) {

            NSRange range;

            range.location = stringIndex;

            range.length =1;

            digitView.text = [valueStringsubstringWithRange:range];

           stringIndex++;

        }

        currentPos++;

    }

}


-(void)setBackgroundView:(UIView *)backgroundView{

    [_backgroundViewremoveFromSuperview];

   _backgroundView = backgroundView;

    [self insertSubview:_backgroundView atIndex:0];

}


// Private Methods //

#pragma mark - private methods

// generate the digit views

-(void)setupDigitViews{

    // remove the old views

    for (UIView *digitViewindigitViews) {

        [digitViewremoveFromSuperview];

    }

    

   for (UIView *bgViewinbgImageViews) {

        [bgView removeFromSuperview];

    }

    

    [digitViewsremoveAllObjects];

    [bgImageViewsremoveAllObjects];

    

    // generate new views and set default digit to 0

    for (int i =0; i <_numberOfDigits; i++) {

        

       UILabel *newDigitView = [[UILabelalloc]init];

        // configuring the label

        newDigitView.textAlignment = UITextAlignmentCenter;

        newDigitView.textColor =_digitViewTextColor;

        newDigitView.highlightedTextColor =_digitViewHighlightedTextColor;

        newDigitView.shadowColor =_digitViewShadowColor;

        newDigitView.shadowOffset =_digitViewShadowOffset;

        newDigitView.backgroundColor =_digitViewBackgroundColor;

        newDigitView.font =_digitViewFont;

        newDigitView.adjustsFontSizeToFitWidth =YES;

        newDigitView.text =_placeHolderCharacter;

        // adding the custom background if available

        if (_digitOverlayImage) {

            UIImageView *overlayImageView = [[UIImageViewalloc]initWithImage:_digitOverlayImage];

            [newDigitView addSubview:overlayImageView];

        }


        if (_digitBackgroundImage) {

           UIImageView *bgDigitView = [[UIImageViewalloc]initWithImage:_digitBackgroundImage];

            [self addSubview:bgDigitView];

            [bgImageViewsaddObject:bgDigitView];

        }

        // adding the digit to the view and the digitview array

        [self addSubview:newDigitView];

        [digitViewsaddObject:newDigitView];

    }

    [self setNeedsLayout];

}


// highlights the digit view with the given index

-(void)highlightIndex:(NSInteger)indexToHighlight{

   for (int i =0; i < [digitViewscount]; i++) {

        UILabel *digitView = [digitViewsobjectAtIndex:i];

        if (i == indexToHighlight) {

            digitView.backgroundColor =_digitViewHighlightedBackgroundColor;

            digitView.highlighted =YES;

            digitView.shadowColor = _digitViewHighlightedShadowColor;

            digitView.shadowOffset =_digitViewHighlightedShadowOffset;

        }else {

            digitView.backgroundColor =_digitViewBackgroundColor;

            digitView.shadowColor = _digitViewShadowColor;

            digitView.shadowOffset =_digitViewShadowOffset;

            digitView.highlighted = NO;

        }

    }

}


// Unhighlights all digit views

-(void)unhighlightAll{

   for (UILabel *digitViewindigitViews) {

        digitView.backgroundColor = _digitViewBackgroundColor;

        digitView.shadowColor =_digitViewShadowColor;

        digitView.shadowOffset =_digitViewShadowOffset;

       digitView.highlighted = NO;

    }

}


// Set text for a given digitview index

-(void)setText:(NSString *)text ForIndex:(NSInteger)index{

    UILabel *activeDigitView = [digitViewsobjectAtIndex:index];

    activeDigitView.text = text;

    NSString *valueString = @"";

    for (UILabel *digitViewindigitViews) {

        NSString *digitString = digitView.text;

        if ([digitString isEqualToString:_placeHolderCharacter]) {

            valueString = [valueStringstringByAppendingString:@"0"];

        }else {

            valueString =[valueStringstringByAppendingString:digitString];

        }

    }


   activeString = valueString;

   _value = [valueStringintegerValue];

    

    [selfsendActionsForControlEvents:UIControlEventEditingChanged];

    [selfsendActionsForControlEvents:UIControlEventValueChanged];

}


// UIKeyInput Protocol implementation ///

#pragma mark - UIKeyInput Protocol implementation

// gets called when keyboard text is entered

- (void)insertText:(NSString *)text{

    // set the entered text in the digit view

    // at the current index

    [self setText:text ForIndex:currentIndex];

    // automatically jump to the next digit

    currentIndex++;


    // if currentindex is bigger than

    // number of digitviews we assume

    // that we are done with entering

    // digits and are hiding the keyboard

    if (currentIndex >=_numberOfDigits) {

        [self resignFirstResponder];

       return;

    }

   [self highlightIndex:currentIndex];

}


// get called when keboard delete button is pressed

// Delete button action is just moving

// the current position on position to

// the left

- (void)deleteBackward{

    /*

     for (int i = 0; i <= currentIndex; i++) {

     NSLog(@"current index");

     [self setText:_placeHolderCharacter ForIndex:i];

     }

     */

    //currentIndex = 0;

    /*

     if (currentIndex >= 1) {

     

     UILabel *previousDigitView = [digitViews objectAtIndex:(currentIndex-1)];

     

     if ([previousDigitView.text isEqualToString:_placeHolderCharacter]) {

     [self setText:_placeHolderCharacter ForIndex:currentIndex];

     return;

     }

     

     }

     */

    currentIndex--;

    if (currentIndex <=0) {

        currentIndex = 0;

    }

    [self highlightIndex:currentIndex];

}


-(BOOL)hasText{

    returnactiveString !=nil;

}


/ UITextInputTraits protocol implementation

#pragma mark - UITextInputTraits protocol implementation

// always return a number pad keyboard

-(UIKeyboardType)keyboardType{

    returnUIKeyboardTypeNumberPad;

}


View Stuff and other internal stuff //

#pragma mark - view stuff and other internal stuff

-(void)layoutSubviews{

    [superlayoutSubviews];

    _backgroundView.frame =self.bounds;

    

   CGFloat xOffset =0;

   CGFloat digitWidth = (self.bounds.size.width-((_numberOfDigits+1)*kDefaultDigitPadding)) / (CGFloat)_numberOfDigits;

    

   for (UIView *digitViewindigitViews) {

        digitView.frame = CGRectMake(kDefaultDigitPadding+xOffset,kDefaultDigitPadding, digitWidth,self.bounds.size.height-2*kDefaultDigitPadding);

       xOffset = digitView.frame.origin.x+digitView.bounds.size.width;

    }

    

    xOffset =0;

    

    // TODO: remove duplicate code and implement better solulition for setting

    // frames of bgimage views

    if (_digitBackgroundImage) {

       for (UIView *bgDigitViewinbgImageViews) {

            bgDigitView.frame = CGRectMake(kDefaultDigitPadding+xOffset,kDefaultDigitPadding, digitWidth,self.bounds.size.height-2*kDefaultDigitPadding);

            

            xOffset = bgDigitView.frame.origin.x+bgDigitView.bounds.size.width;

        }

    } 

}


// always return yes

-(BOOL)canBecomeFirstResponder{

    [selfsetHighlighted:YES];

    [selfsendActionsForControlEvents:UIControlEventEditingDidBegin];

    return YES;

}


// Unhighlight all digitviews

// and hide keyboard

-(BOOL)resignFirstResponder{ 

    [selfunhighlightAll];

    

    if (self.highlighted) {

        [selfsendActionsForControlEvents:UIControlEventEditingDidEnd];

    }

    [selfsetHighlighted:NO];

    return [superresignFirstResponder];

}


// determine active index and show up keyboard

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

   UITouch *touch = [touchesanyObject];

   CGPoint touchPoint = [touchlocationInView:self];    

    // TODO: ignore padding to have a bigger touch area

    

    // Check if a touch is inside a digitview

    // if so set the currentIndex and show

    // up the keyboard by becoming the first

    // responder

    NSInteger touchedIndex = 0;

    

   for (UIView *digitViewindigitViews) {

        if (CGRectContainsPoint(digitView.frame, touchPoint)) {

           currentIndex = touchedIndex;

            [self highlightIndex:currentIndex];

            [self becomeFirstResponder];

           break;

        }

        touchedIndex++;

    }

}


UIControl Methods //

#pragma mark - UIControl Methods

-(void)setEnabled:(BOOL)enabled{

    [supersetEnabled:enabled];

   if (enabled) {

        for (UIView *digitViewindigitViews) {

            digitView.alpha =1.0;

        }

    }else {

       for (UIView *digitViewindigitViews) {

            digitView.alpha =0.5;

        }

    }

}


-(void)setHighlighted:(BOOL)highlighted{

    [supersetHighlighted:highlighted];

    if (highlighted) {

        self.backgroundView.backgroundColor =_highlightedBackgroundColor;

    }else {

        self.backgroundView.backgroundColor =_backgroundColor;

    }

}


@end





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值