iOS开发一行代码系列:一行搞定输入框优化

iOS8以前,我们设置键盘为UIKeyboardTypeNumberPad类型的,我们就不太容易输入字母或者其他的。
iOS8以后,由于支持了第三方输入法,就算设置键盘为UIKeyboardTypeNumberPad类型的,我们随便切换下就很容易输入其他字母啦。
为了解决这样的问题,我们对InputHelper进行优化,这样以后我们就不用为这样的小问题浪费时间了。
常见的小问题还有,评论字数的限制,如果超过120字可能会做截取或者弹出提示框;或者不能输入空格;或者只能输入英文。

源码下载地址:inputHelper

代码如下:

#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>

typedef void(^InputHelperDoneBlock)(id);
typedef void(^InputHelperValidationError)(id,NSString*);

typedef NS_ENUM(NSInteger, InputHelperDismissType) {

    InputHelperDismissTypeNone = 0,
    InputHelperDismissTypeCleanMaskView,
    InputHelperDismissTypeTapGusture
};

typedef NS_ENUM(NSInteger, ValidationType) {

    ValidationTypeNone = 0,       //no limit
    ValidationTypeNoWhiteSpace,   //no whitespace character
    ValidationTypeNumberInt,      //int number only
    ValidationTypePhone,          //phone only
    ValidationTypeAlphabetAndNumber,     //alphabet and number
};

@interface InputHelper : NSObject

+ (InputHelper *)sharedInputHelper;
- (void)dismissInputHelper;

//keyboard
- (void)setupInputHelperForView:(UIView *)view withDismissType:(InputHelperDismissType)dismissType;
- (void)setupInputHelperForView:(UIView *)view withDismissType:(InputHelperDismissType)dismissType doneBlock:(InputHelperDoneBlock)doneBlock;

//validation
- (void)setupValidationType:(ValidationType)type forInputField:(UIView *)inputField;
- (void)limitTextLength:(NSInteger)length forInputField:(UIView *)inputField;
@end

@interface NSString (InputHelper)
- (NSString *)trimmedString ;
@end
#import "InputHelper.h"
#import <objc/objc.h>
#import <objc/runtime.h>

static NSString *kInputHelperTapGusture= @"kInputHelperTapGusture";
static NSString *kInputHelperDismissType= @"kInputHelperDismissType";
static NSInteger tapTag = 2014;

static NSString *kInputHelperRootViewOriginalOriginY = @"kInputHelperRootViewOriginalOriginY";
static NSString *kInputHelperRootViewAllInputFieldOriginYDictionary = @"kInputHelperRootViewAllInputFieldOriginYDictionary";
static NSString *kInputHelperRootViewSortedInputFieldArray = @"kInputHelperRootViewSortedInputFieldArray";

static NSString *kInputHelperDoneBlock = @"kInputHelperDoneBlock";

static NSString *kInputHelperValidationType = @"kInputHelperValidationType";
static NSString *kInputHelperInputFiedlTextLength = @"kInputHelperInputFiedlTextLength";
static NSString *kInputHelperTextLengthLimit = @"kInputHelperTextLengthLimit";

static void setAssociatedObjectForKey(UIView *view ,NSString *key,id value){
    objc_setAssociatedObject(view, (__bridge  const void *)(key), value, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

static id getAssociatedObjectForKey(UIView *view ,NSString *key) {
   return  objc_getAssociatedObject(view, (__bridge  const void *)(key));
}

#define INT_NUMBER_SET  @"^\\d*$"
#define PHONE_SET   @"^1{1,}\\d*$"
#define ALPHABET_NUMBER_SET @"^[[email protected]_.\\-]+$"

@interface InputHelperTapGusture: UITapGestureRecognizer
@property (assign, nonatomic) NSInteger tag;
@end
@implementation InputHelperTapGusture
@end

@interface InputHelper ()

@property (strong, nonatomic) UIView *cleanMaskView;
@property (strong, nonatomic) UIToolbar *toolBarForCleanMaskView;

@property (strong, nonatomic) UIToolbar *toolBar;

@property (assign, nonatomic) CGSize keyboardSize;
@property (assign, nonatomic) CGFloat perMoveDistanceForInputField;

@property (assign, nonatomic) CGRect defaultToolBarFrame;
@property (assign, nonatomic) CGRect defaultMaskViewFrame;
@property (assign, nonatomic) CGRect toolBarFrameInMaskView;

//current root view
@property (weak, nonatomic) UIView *currentRootView;

@end

@implementation InputHelper

- (UIToolbar *)createInputHelperToolBar{

    UIToolbar *toolBar = [[UIToolbar alloc]initWithFrame:_defaultToolBarFrame];
    toolBar.barStyle = UIBarStyleBlackTranslucent;
    UIBarButtonItem *btnPrevious = [[UIBarButtonItem alloc]initWithTitle:@"上一项" style:UIBarButtonItemStyleDone target:self action:@selector(didClickButtonPrevious)];
    UIBarButtonItem *btnNext = [[UIBarButtonItem alloc]initWithTitle:@"下一项" style:UIBarButtonItemStyleDone target:self action:@selector(didClickButtonNext)];
    UIBarButtonItem *spaceItem = [[UIBarButtonItem alloc]initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:self action:nil];
    UIBarButtonItem *btnDown = [[UIBarButtonItem alloc]initWithTitle:@"完成" style:UIBarButtonItemStyleDone target:self action:@selector(didClickButtonDone)];
    [toolBar setItems:[[NSArray alloc]initWithObjects:btnPrevious,btnNext,spaceItem,btnDown, nil]];
    return toolBar;
}

- (void)initilize
{

    _defaultToolBarFrame = CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, 40);
    _defaultMaskViewFrame = CGRectMake(0, 0, [[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height);
    _toolBarFrameInMaskView = CGRectMake(0, [[UIScreen mainScreen] bounds].size.height - 40, [[UIScreen mainScreen] bounds].size.width, 40);

    _perMoveDistanceForInputField = 40;

    _keyboardSize = CGSizeMake(320, 256);

    //tool bar
    self.toolBar = [self createInputHelperToolBar];

    self.toolBarForCleanMaskView = [self createInputHelperToolBar];
    _toolBarForCleanMaskView.frame = _toolBarFrameInMaskView;

    //tap mask view
    _cleanMaskView = [[UIView alloc]initWithFrame:_defaultMaskViewFrame];
    _cleanMaskView.backgroundColor = [UIColor clearColor];

    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(didClickButtonDone)];
    [_cleanMaskView addGestureRecognizer:tap];
    [_cleanMaskView addSubview:_toolBarForCleanMaskView];

    NSNotificationCenter *notifCenter = [NSNotificationCenter defaultCenter];

    [notifCenter addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
    [notifCenter addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];

    [notifCenter addObserver:self selector:@selector(updateFirstResponder:) name:UITextFieldTextDidBeginEditingNotification object:nil];
    [notifCenter addObserver:self selector:@selector(updateFirstResponder:) name:UITextFieldTextDidEndEditingNotification object:nil];
    [notifCenter addObserver:self selector:@selector(updateFirstResponder:) name:UITextViewTextDidBeginEditingNotification object:nil];
    [notifCenter addObserver:self selector:@selector(updateFirstResponder:) name:UITextViewTextDidEndEditingNotification object:nil];

    [notifCenter addObserver:self selector:@selector(updateInputFieldText:) name:UITextFieldTextDidChangeNotification object:nil];
    [notifCenter addObserver:self selector:@selector(updateInputFieldText:) name:UITextViewTextDidChangeNotification object:nil];

}

- (instancetype)init{
    self = [super init];
    if (self) {

        [self initilize];
    }
    return self;
}
+ (InputHelper *)sharedInputHelper{
    static InputHelper *instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[InputHelper alloc]init];
    });
    return instance;
}

#pragma mark - APIs
- (void)setupInputHelperForView:(UIView *)view withDismissType:(InputHelperDismissType)dismissType doneBlock:(InputHelperDoneBlock)doneBlock{

    self.currentRootView = view;

    setAssociatedObjectForKey(view, kInputHelperDismissType, @(dismissType));

    NSMutableDictionary *dic= [NSMutableDictionary new];
    setAssociatedObjectForKey(view, kInputHelperRootViewAllInputFieldOriginYDictionary, dic);

    NSMutableArray *array = [NSMutableArray new];
    setAssociatedObjectForKey(view, kInputHelperRootViewSortedInputFieldArray, array);

    objc_setAssociatedObject(view, (__bridge  const void *)(kInputHelperDoneBlock), doneBlock, OBJC_ASSOCIATION_COPY_NONATOMIC);

    [self checkInputFieldInView:view withViewOriginY:view.frame.origin.y];

    NSArray *keys = [getAssociatedObjectForKey(view, kInputHelperRootViewAllInputFieldOriginYDictionary) allKeys];
    if (keys.count == 0) {
        return;
    }

    NSArray *sortedOriginYArray = [keys sortedArrayUsingComparator:^(id obj1, id obj2){
        if ([obj1 compare:obj2] == NSOrderedDescending){
            return NSOrderedDescending;
        }
        if ([obj1 compare:obj2] == NSOrderedAscending){
            return NSOrderedAscending;
        }
        return NSOrderedSame;
    }];

    UIView *inputAccessoryView = _toolBar;

    if (dismissType == InputHelperDismissTypeNone) {

        _toolBar.frame = _defaultToolBarFrame;

    } else if (dismissType == InputHelperDismissTypeCleanMaskView){

        inputAccessoryView = _cleanMaskView;

    } else if (dismissType == InputHelperDismissTypeTapGusture){

        setAssociatedObjectForKey(view, kInputHelperTapGusture, kInputHelperTapGusture);
    }

    for (NSNumber *key in sortedOriginYArray){

        UIView *inputField = [getAssociatedObjectForKey(view, kInputHelperRootViewAllInputFieldOriginYDictionary) objectForKey:key];

        [getAssociatedObjectForKey(view, kInputHelperRootViewSortedInputFieldArray) addObject:inputField];

        if ([inputField isKindOfClass:[UITextField class]]) {

            ((UITextField *)inputField).inputAccessoryView = inputAccessoryView;

        } else if([inputField isKindOfClass:[UITextView class]]){

            ((UITextView *)inputField).inputAccessoryView = inputAccessoryView;

        } else if([inputField isKindOfClass:[UISearchBar class]]){

            ((UISearchBar *)inputField).inputAccessoryView = inputAccessoryView;
        }

    }

}

- (void)setupInputHelperForView:(UIView *)view withDismissType:(InputHelperDismissType)dismissType{
    [self setupInputHelperForView:view withDismissType:dismissType doneBlock:nil];
}

- (void)dismissInputHelper{
    [self didClickButtonDone];
}

- (void)setupValidationType:(ValidationType)type forInputField:(UIView *)inputField {

    setAssociatedObjectForKey(inputField, kInputHelperValidationType, @(type));

    switch (type) {
        case ValidationTypeNumberInt:
        {
            [self setKeyBoardType:UIKeyboardTypeNumberPad forInputField:inputField];
        }
            break;
        case ValidationTypePhone:
        {
            [self limitTextLength:11 forInputField:inputField];
            [self setKeyBoardType:UIKeyboardTypePhonePad forInputField:inputField];
        }
            break;
        default:
        {
            [self setKeyBoardType:UIKeyboardTypeDefault forInputField:inputField];
        }
            break;
    }

}

- (void)limitTextLength:(NSInteger)length forInputField:(UIView *)inputField{
    setAssociatedObjectForKey(inputField, kInputHelperTextLengthLimit, @(length));
}

#pragma mark -
- (void)updateFirstResponder:(NSNotification *)aNotification {

    [self updateButtonEnabledStateForInputField:[self getFirstResponder]];
}

- (void)checkInputFieldInView:(UIView *)view
              withViewOriginY:(CGFloat)y
{

    for (UIView *subView in view.subviews){

        if (subView.hidden == YES) {
            continue;
        }

        if ([subView isKindOfClass:[UITextField class]] ||
            [subView isKindOfClass:[UITextView class]] ||
            [subView isKindOfClass:[UISearchBar class]]) {

            NSNumber *key = [NSNumber numberWithFloat: y + subView.frame.origin.y];

            NSMutableDictionary *dic = getAssociatedObjectForKey(_currentRootView, kInputHelperRootViewAllInputFieldOriginYDictionary);
            [dic setObject:subView forKey:key];

        } else {
            [self checkInputFieldInView:subView
                        withViewOriginY:y + subView.frame.origin.y];
        }
    }
}

- (UIView *)getFirstResponder
{
    for (UIView *tf in getAssociatedObjectForKey(_currentRootView, kInputHelperRootViewSortedInputFieldArray)) {
        if ([tf isFirstResponder]) {
            return tf;
        }
    }
    return nil;
}

- (void)didClickButtonPrevious
{
    UIView *firstResponder = [self getFirstResponder];
    UIView *previousInputField = firstResponder;
    NSArray *sortedInputFields = getAssociatedObjectForKey(_currentRootView, kInputHelperRootViewSortedInputFieldArray);
    if (![firstResponder isEqual:[sortedInputFields firstObject]]) {
        previousInputField = [sortedInputFields objectAtIndex:[sortedInputFields indexOfObject:firstResponder] - 1];
        [previousInputField becomeFirstResponder];
    }

    [self updateButtonEnabledStateForInputField:previousInputField];
}

- (void)didClickButtonNext
{
    UIView *firstResponder = [self getFirstResponder];
    UIView *nextInputField = firstResponder;
    NSArray *sortedInputFields = getAssociatedObjectForKey(_currentRootView, kInputHelperRootViewSortedInputFieldArray);
    if (![firstResponder isEqual:[sortedInputFields lastObject]]) {
        nextInputField = [sortedInputFields objectAtIndex:[sortedInputFields indexOfObject:firstResponder] + 1];
        [nextInputField becomeFirstResponder];
    }

    [self updateButtonEnabledStateForInputField:nextInputField];
}

- (void)didClickButtonDone
{

    [[self getFirstResponder] resignFirstResponder];

    CGRect frame = _currentRootView.frame;
    frame.origin.y = [getAssociatedObjectForKey(_currentRootView, kInputHelperRootViewOriginalOriginY) floatValue];
    [UIView animateWithDuration:0.3f animations:^{
        _currentRootView.frame = frame;
    }];

    InputHelperDoneBlock doneBlock = getAssociatedObjectForKey(self.currentRootView, kInputHelperDoneBlock);
    if (doneBlock) {
        //callback what??
        doneBlock(nil);
    }

}

- (void)updateButtonEnabledStateForInputField:(UIView *)inputField
{
    if (inputField) {
        NSInteger dismissType = [getAssociatedObjectForKey(_currentRootView, kInputHelperDismissType) integerValue];

        UIToolbar *toolBar = dismissType == InputHelperDismissTypeCleanMaskView ? _toolBarForCleanMaskView : _toolBar;
        UIBarButtonItem *previousBarItem = (UIBarButtonItem *)[[toolBar items] objectAtIndex:0];
        UIBarButtonItem *nextBarItem = (UIBarButtonItem *)[[toolBar items] objectAtIndex:1];
       NSArray *sortedInputFields = getAssociatedObjectForKey(_currentRootView, kInputHelperRootViewSortedInputFieldArray);
        [previousBarItem setEnabled:[inputField isEqual:[sortedInputFields firstObject]] ? NO : YES];
        [nextBarItem setEnabled:[inputField isEqual:[sortedInputFields lastObject]] ? NO : YES];
        [self animatedMoveRootViewForInputField:inputField];
    }

}

- (void)animatedMoveRootViewForInputField:(UIView *)inputField
{

    CGPoint windowPoint = [inputField.superview convertPoint:inputField.frame.origin toView:[[UIApplication sharedApplication]keyWindow]];
    CGFloat topY = 74.0f;
    CGFloat buttomY = [[UIScreen mainScreen]applicationFrame].size.height - _keyboardSize.height - 80;

    CGRect frame = _currentRootView.frame;
    if (windowPoint.y < topY ) {

        frame.origin.y +=  (1 + (int)((topY - windowPoint.y) / _perMoveDistanceForInputField)) * _perMoveDistanceForInputField;
        if (frame.origin.y > 0) {
            frame.origin.y = 0;
        }

    } else if (windowPoint.y > buttomY) {

        frame.origin.y -= ((1 + (int)((windowPoint.y - buttomY) / _perMoveDistanceForInputField)) * _perMoveDistanceForInputField);
    }

    [UIView animateWithDuration:0.3f animations:^{
        _currentRootView.frame = frame;
    }];
}

#pragma mark - Notification methods

- (void) keyboardWillShow:(NSNotification *) notif
{

    if (getAssociatedObjectForKey(_currentRootView, kInputHelperRootViewOriginalOriginY) == nil) {
        setAssociatedObjectForKey(_currentRootView, kInputHelperRootViewOriginalOriginY, @(_currentRootView.frame.origin.y));
    }

    NSString *str = getAssociatedObjectForKey(_currentRootView, kInputHelperTapGusture);

    BOOL hasAddGusture = NO;
    for(id gusture in _currentRootView.gestureRecognizers){
        if ([gusture isKindOfClass:[InputHelperTapGusture class]] && ((InputHelperTapGusture *)gusture).tag == tapTag) {
            hasAddGusture = YES;
            break;
        }
    }

    if ([str isEqualToString:kInputHelperTapGusture] && !hasAddGusture) {
        InputHelperTapGusture *tap = [[InputHelperTapGusture alloc]initWithTarget:self action:@selector(didClickButtonDone)];
        tap.tag = tapTag;
        [_currentRootView addGestureRecognizer:tap];
    }

    [self updateButtonEnabledStateForInputField:[self getFirstResponder]];
}

- (void) keyboardWillHide:(NSNotification *) notif
{

    NSString *str = getAssociatedObjectForKey(_currentRootView, kInputHelperTapGusture);

    if ([str isEqualToString:kInputHelperTapGusture]) {
        for(id gusture in _currentRootView.gestureRecognizers){
            if ([gusture isKindOfClass:[InputHelperTapGusture class]] && ((InputHelperTapGusture *)gusture).tag == tapTag) {
                [_currentRootView removeGestureRecognizer:gusture];
                break;
            }
        }
    }

}

- (void)updateInputFieldText:(NSNotification *)notif{
    [self checkInputField:notif.object];
}

#pragma mark - Validation

- (void)setKeyBoardType:(UIKeyboardType) keyboardType forInputField:(UIView *)inputField{
    if ([inputField isKindOfClass:[UITextField class]]) {
        ((UITextField *)inputField).keyboardType = keyboardType;
    } else if([inputField isKindOfClass:[UITextView class]]){
        ((UITextView *)inputField).keyboardType = keyboardType;
    } else if([inputField isKindOfClass:[UISearchBar class]]){
        ((UISearchBar *)inputField).keyboardType = keyboardType;
    }
}

- (NSString *)getTextForInputField:(UIView *)inputField{
    if ([inputField isKindOfClass:[UITextField class]]) {
        return ((UITextField *)inputField).text;
    } else if([inputField isKindOfClass:[UITextView class]]){
        return ((UITextView *)inputField).text;
    } else if([inputField isKindOfClass:[UISearchBar class]]){
        return ((UISearchBar *)inputField).text;
    }
    return @"";
}

- (void)setText:(NSString *)text forInputField:(UIView *)inputField{
    if ([inputField isKindOfClass:[UITextField class]]) {
        ((UITextField *)inputField).text = text;
    } else if([inputField isKindOfClass:[UITextView class]]){
        ((UITextView *)inputField).text = text;
    } else if([inputField isKindOfClass:[UISearchBar class]]){
        ((UISearchBar *)inputField).text = text;
    }
}

- (void)checkText:(NSString *)text forInputField:(UIView *)inputField validation:(NSString *)validation{

    NSInteger preLength = [getAssociatedObjectForKey(inputField, kInputHelperInputFiedlTextLength) integerValue];
    NSLog(@"current text %@ len %d,prelen %d",text,[text length],preLength);

    if (![self isTextAvailable:text forValidation:validation]) {
        [self setText:[text substringToIndex:MAX(MAX(preLength - 1, 0), text.length -1)] forInputField:inputField];
        setAssociatedObjectForKey(inputField, kInputHelperInputFiedlTextLength, @(preLength));
    } else {
        setAssociatedObjectForKey(inputField, kInputHelperInputFiedlTextLength, @(text.length));
    }

}

- (void)checkInputField:(UIView *)inputField{

    NSInteger type = [getAssociatedObjectForKey(inputField, kInputHelperValidationType) integerValue];

    //length limit
    NSInteger limitLength = [getAssociatedObjectForKey(inputField, kInputHelperTextLengthLimit) integerValue];
    if (limitLength) {
        NSString *text = [self getTextForInputField:inputField];
        if (text.length && text.length > limitLength) {
            [self setText:[text substringToIndex:limitLength]forInputField:inputField];
        }
    }

    NSString *text = [self getTextForInputField:inputField];

    if (text.length) {

        switch (type) {
            case ValidationTypeNone:
            {
                //do nothing
            }
                break;
            case ValidationTypeNoWhiteSpace:
            {
                [self setText:[text trimmedString] forInputField:inputField];
            }
                break;
            case ValidationTypeNumberInt:
            {
                [self checkText:text forInputField:inputField validation:INT_NUMBER_SET];
            }
                break;
            case ValidationTypeAlphabetAndNumber:
            {
                [self checkText:text forInputField:inputField validation:ALPHABET_NUMBER_SET];
            }
                break;
            case ValidationTypePhone:
            {
                [self checkText:text forInputField:inputField validation:PHONE_SET];
            }
                break;
            default:
            {
            }
                break;
        }

    }
}

- (BOOL)isTextAvailable:(NSString *)text  forValidation:(NSString *)validation {
    NSPredicate *regexPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",validation];
    return [regexPredicate evaluateWithObject:text];
}

@end

@implementation NSString (InputHelper)

- (NSString *)trimmedString {
    return [self stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

@end

源码下载:inputHelper

时间: 2024-11-10 13:43:29

iOS开发一行代码系列:一行搞定输入框优化的相关文章

“你的这个只要一行代码就能搞定”

帮舍友代写了一个程序,中期检查的时候和他一起去见老师.老师看了说我们的工作量太少.这个几分钟就搞定.最后他居然说:"这个工作量太少了,就调用一行代码的事,几分钟就可以搞定".去之前我知道这个临时做出来的东西,肯定没跟上进度.但好歹有几天的工作量吧.他居然说只要几分钟,一行调用代码.难道用http协议从网上获取天气数据,再解析xml格式的数据,再转换字符串编码,再根据天气选择要绘制的图片和文字,只需要一行代码?难道我不需要查资料,不需要设计界面吗?为了用mfc做出这个界面,我确实费了一番

iOS开发一行代码系列:一行搞定输入框

最近总结了下开发过程中常用的功能,发现有时候我在做重复性的劳动.于是决定把常用的功能抽出来,方便下次使用. 我的想法是:用最少的代码来解决问题.于是写了一些常用的工具类,名字就叫一行代码系列吧...好像挺挫的.. 大致内容有: 1.一行搞定输入框 2.一行搞定网络请求 3.一行搞定上下拉刷新(会自动判断是上拉还是下拉还是两者并存) 4.一行搞定数据库(最近还在写,功能已经基本实现) 5.一行搞定图片保存 6.一行搞定定位 7.一行搞定网络状况变化 8.一行搞定X(功能小集合) 一行搞定输入框 输

“你的这个仅仅要一行代码就能搞定”

帮舍友代写了一个程序,中期检查的时候和他一起去见老师.老师看了说我们的工作量太少.这个几分钟就搞定.最后他竟然说:"这个工作量太少了,就调用一行代码的事,几分钟就能够搞定".去之前我知道这个暂时做出来的东西,肯定没跟上进度.但好歹有几天的工作量吧.他竟然说仅仅要几分钟,一行调用代码.难道用http协议从网上获取天气数据,再解析xml格式的数据,再转换字符串编码,再依据天气选择要绘制的图片和文字,仅仅须要一行代码?难道我不须要查资料,不须要设计界面吗?为了用mfc做出这个界面,我确实费了

python实战===一行代码就能搞定的事情!

打印9*9乘法表: >>> print( '\n'.join([' '.join(['%s*%s=%-2s' % (y,x,x*y) for y in range(1,x+1)]) for x in range(1,10)])) 1*1=1 1*2=2 2*2=4 1*3=3 2*3=6 3*3=9 1*4=4 2*4=8 3*4=12 4*4=16 1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6

iOS开发一行代码系列:一行搞定数据库

原理 iOS 和 SQL的对应关系 Model类结构      =>    SQL表结构 Model实例       =>  SQL表中的一行 Model实例的属性   =>   SQL表中的一列 Model和Table的对应 @interface TestModel :NSObject @property (assign, nonatomic) NSInteger age; @property (assign, nonatomic) CGFloat height; @property

ios 8行代码教你搞定导航控制器全屏滑动返回效果

一.自定义导航控制器 目的:以后需要使用全屏滑动返回功能,就使用自己定义的导航控制器. 二.分析导航控制器侧滑功能 效果:导航控制器默认自带了侧滑功能,当用户在界面的左边滑动的时候,就会有侧滑功能. 系统自带的侧滑效果: 分析: 1.导航控制器的view自带了滑动手势,只不过手势的触发范围只能在左边. 2.当用户在界面左边拖动,就会触发滑动手势方法,并且有滑动返回功能,说明系统手势触发的方法已经实现了滑动返回功能. 3.为什么说系统手势触发的方法已经实现了滑动返回功能? 原因: 创建滑动手势对象

iOS开发——实用技术OC篇&amp;8行代码教你搞定导航控制器全屏滑动返回效果

8行代码教你搞定导航控制器全屏滑动返回效果 前言 此次文章,讲述的是导航控制器全屏滑动返回效果,而且代码量非常少,10行内搞定. 效果如图: 如果喜欢我的文章,可以关注我,也可以来小码哥,了解下我们的iOS培训课程.陆续还会有更新ing.... 一.自定义导航控制器 目的:以后需要使用全屏滑动返回功能,就使用自己定义的导航控制器. 二.分析导航控制器侧滑功能 效果:导航控制器默认自带了侧滑功能,当用户在界面的左边滑动的时候,就会有侧滑功能. 系统自带的侧滑效果: 分析: 1.导航控制器的view

iOS开发技巧(系列十七:使用Xcode DEBUG模式和RELEASE模式)

在开发过程中,我们经常需要用到NSLog输出一些信息,甚至有的开发过程,必须在控制台查看输出,有经验的程序员通过控制台输出就能知道整个数据交互的一个流程.但是一个发布的程序,里面带有太多的NSLog输出,肯定对于App性能有所影响,这时候我们可以使用一个宏定义来处理,在开发的时候使用DEBUG模式,在发布的时候使用RELEASE模式.这样,发布的App就不会在程序内部做大量的NSLog输出了. 简单的代码如下, #if defined(DEBUG)||defined(_DEBUG)     NS

iOS开发 纯代码创建UICollectionView

转:http://jingyan.baidu.com/article/eb9f7b6d8a81a5869364e8a6.html iOS开发 纯代码创建UICollectionView 习惯了使用xib和StoryBoard创建UICollectionView项目工程的伙伴,需要转换使用纯代码来实现,想避免碰更多的壁,就需要认真了解创建UICollectionView过程了.创建UICollectionView比创建UITableView更加复杂,初始化方式也是相对奇特.以下是使用纯代码创建UI