现在的位置: 首页 > 综合 > 正文

ios 简单计算器

2013年11月26日 ⁄ 综合 ⁄ 共 12293字 ⁄ 字号 评论关闭

初学objective-c做点小练习,以下是一个简单的计算器。

主要涉及到NSMutableString,UILabel,UIButton和button按下的消息,按键之间的逻辑使用了一点状态模式来进行控制,看起来有点混乱。

//
//  AppDelegate.h
//  calc
//
//  Created by tujiaw on 13-11-17.
//  Copyright (c) 2013年 tujiaw. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface AppDelegate : UIResponder <UIApplicationDelegate>

@property (strong, nonatomic) UIWindow *window;

@end



@interface ButtonFactory : UIButton

+ (id) createCalcButton:(id)parent andRect:(CGRect)rect andTag:(NSInteger)tag andTitle:(NSString*)title andSel:(SEL)sel;

@end

//
//  AppDelegate.m
//  calc
//
//  Created by tujiaw on 13-11-17.
//  Copyright (c) 2013年 tujiaw. All rights reserved.
//

#import "AppDelegate.h"

@implementation AppDelegate
{
    UILabel *_inputHistroy;
    UILabel *_inputCurrent;
}

typedef enum SymbolTag {
    ADD = 10,
    SUBTRACT = 11,
    MULTIPLY = 12,
    DIVIDE = 13,
    DELETE = 14,
    EMPTY = 15,
    EQUAL = 16,
    PM = 17,
} SymbolTag;

typedef enum Status {
    START = 0x100,
    HISTROY = 0x101,
    COUNT = 0x102,
    RESULT = 0x103,
} Status;

Status g_status = START;
int g_result = 0;
BOOL g_lastIsSymbolClick = NO;

- (NSString*) getSymbolFromTag:(long)tag
{
    switch (tag)
    {
        case ADD:
            return @"+";
        case SUBTRACT:
            return @"-";
        case MULTIPLY:
            return @"*";
        case DIVIDE:
            return @"/";
    }
    return @"";
}

- (int) count:(int)val1 operator:(NSString*)oper andValue:(int)val2
{
    if ([oper isEqualToString:@"+"]) {
        return val1 + val2;
    } else if ([oper isEqualToString:@"-"]) {
        return val1 - val2;
    } else if ([oper isEqualToString:@"*"]) {
        return val1 * val2;
    } else if ([oper isEqualToString:@"/"]) {
        return val1 / val2;
    }
    return 0;
}

- (int) getOperCount:(NSString*)str
{
    int sum = 0;
    for (int i=0; i<str.length; i++) {
        unsigned char oper = [str characterAtIndex:i];
        if (oper=='+' || oper=='-' || oper=='*' || oper=='/') {
            ++sum;
        }
    }
    return sum;
}

- (void) deleteBtnClick
{
    if (g_lastIsSymbolClick) {
        return;
    }
    
    NSMutableString *strCurrent = [NSMutableString stringWithFormat:@"%@", _inputCurrent.text];
    long strLen = strCurrent.length;
    if (strLen > 2 || (strLen==2 && strCurrent.intValue > 0)) {
        _inputCurrent.text = [strCurrent substringToIndex:strCurrent.length-1];
    } else if (strLen == 1 || (strLen==2 && strCurrent.intValue < 0)) {
        _inputCurrent.text = @"0";
    }
}

- (void) emptyBtnClick
{
    g_status = START;
    _inputCurrent.text = @"0";
    _inputHistroy.text = @"";
}

- (void) pmBtnClick
{
    NSMutableString *strCurrent = [NSMutableString stringWithFormat:@"%@", _inputCurrent.text];
    if (strCurrent.length==0 || [strCurrent isEqualToString:@"0"]) {
        return;
    }
    
    unsigned char pm = [strCurrent characterAtIndex:0];
    if (pm == '-') {
        _inputCurrent.text = [strCurrent substringFromIndex:1];
    } else {
        [strCurrent insertString:@"-" atIndex:0];
        _inputCurrent.text = strCurrent;
    }
}

- (void) inputCurrentNumber:(long)tag
{
    if (tag >= 0 && tag <= 9) {
        g_lastIsSymbolClick = NO;
        NSMutableString *strCurrent = [NSMutableString stringWithFormat:@"%@", _inputCurrent.text];
        if (strCurrent.length > 0 && [strCurrent intValue] == 0) {
            if (tag == 0) {
                return;
            } else {
                [strCurrent setString:@""];
            }
        }
        [strCurrent appendString:[NSString stringWithFormat:@"%ld", tag]];
        _inputCurrent.text = strCurrent;
    }
}

- (void) updateHistroy:(long)tag
{
    if (tag >= ADD && tag <= DIVIDE) {
        NSMutableString *strHistroy = [NSMutableString stringWithFormat:@"%@", _inputHistroy.text];
        NSMutableString *strCurrent = [NSMutableString stringWithFormat:@"%@", _inputCurrent.text];
        [strHistroy appendString:strCurrent];
        [strHistroy appendString:[self getSymbolFromTag:tag]];
        _inputHistroy.text = strHistroy;
        g_lastIsSymbolClick = YES;
    }
}

// + - * / 符号键被连续点击两次,则只更新历史框中的符号,不进行其他操作
    #define SYMBOL_CLICKED_TWINS \
    do {  \
        if (g_lastIsSymbolClick) { \
            NSMutableString *strHistroy = [NSMutableString stringWithFormat:@"%@", _inputHistroy.text]; \
            if (strHistroy.length > 1) { \
                [strHistroy setString:[strHistroy substringToIndex:strHistroy.length-1]]; \
                [strHistroy appendString:[self getSymbolFromTag:tag]]; \
                _inputHistroy.text = strHistroy; \
            } \
            return; \
        } \
    } while(0)

- (void) start:(id)sender andTag:(long)tag
{
    static BOOL s_isFirstEntry = YES;
    if (s_isFirstEntry) {
        s_isFirstEntry = NO;
        _inputHistroy.text = @"";
        _inputCurrent.text = @"0";
    }
 
    NSMutableString *strCurrent = [NSMutableString stringWithFormat:@"%@", _inputCurrent.text];
    if (tag >=0 && tag <=9) {
        [self inputCurrentNumber:tag];
    } else if (tag >= ADD && tag <= DIVIDE) {
        SYMBOL_CLICKED_TWINS;
        g_status = HISTROY;
        g_result = [strCurrent intValue];
        [self updateHistroy:tag];
    } else if (DELETE == tag) {
        [self deleteBtnClick];
    } else if (EMPTY == tag) {
        [self emptyBtnClick];
    } else if (PM == tag) {
        [self pmBtnClick];
    }
}

- (void) histroy:(id)sender andTag:(long)tag
{
    static BOOL s_isFirstEntry = YES;
    NSMutableString *strHistroy = [NSMutableString stringWithFormat:@"%@", _inputHistroy.text];
    NSMutableString *strCurrent = [NSMutableString stringWithFormat:@"%@", _inputCurrent.text];
    if (tag >=0 && tag <=9) {
        if (s_isFirstEntry) {
            s_isFirstEntry = NO;
            _inputCurrent.text = @"";
        }
        [self inputCurrentNumber:tag];
    } else if (tag >= ADD && tag <= DIVIDE) {
        SYMBOL_CLICKED_TWINS;
        
        [self updateHistroy:tag];
        s_isFirstEntry = YES;
        
        
        if (strHistroy.length > 0) {
            NSString *strOperater = [strHistroy substringFromIndex:strHistroy.length-1];
            g_result = [self count:g_result operator:strOperater andValue:[strCurrent intValue]];
        }
        _inputCurrent.text = [NSString stringWithFormat:@"%d", g_result];
    } else if (DELETE == tag) {
        [self deleteBtnClick];
    } else if (EMPTY == tag) {
        [self emptyBtnClick];
    } else if (EQUAL == tag) {
        if (strHistroy.length > 0) {
            s_isFirstEntry = YES;
            g_status = START;
            NSString *oper = [strHistroy substringFromIndex:strHistroy.length-1];
            g_result = [self count:g_result operator:oper andValue:[strCurrent intValue]];
            _inputCurrent.text = [NSString stringWithFormat:@"%d", g_result];
            _inputHistroy.text = @"";
        }
    } else if (PM == tag) {
        [self pmBtnClick];
    }
}

- (void) count:(id)sender andTag:(long)tag
{
    NSMutableString *strHistroy = [NSMutableString stringWithFormat:@"%@", _inputHistroy.text];
    NSMutableString *strCurrent = [NSMutableString stringWithFormat:@"%@", _inputCurrent.text];
    
    if (tag >= ADD && tag <= DIVIDE) {
        NSString *strOperater = [strHistroy substringFromIndex:strHistroy.length-1];
        g_result = [self count:g_result operator:strOperater andValue:[strCurrent intValue]];
        _inputCurrent.text = [NSString stringWithFormat:@"%d", g_result];
        g_status = HISTROY;
    } else if (DELETE == tag) {
        [self deleteBtnClick];
    } else if (EMPTY == tag) {
        [self emptyBtnClick];
    } else if (PM == tag) {
        [self pmBtnClick];
    }
}

- (void) result:(id)sender andTag:(long)tag
{
    if (tag >=0 && tag <=9) {
        [self start:sender andTag:tag];
    } else if (tag >= ADD && tag <= DIVIDE) {
        [self histroy:sender andTag:tag];
    } else if (EMPTY == tag) {
        
    } else if (EQUAL == tag) {
        
    }
}

- (void) allBtnClick:(id) sender
{
    UIButton *btn = (UIButton*)sender;
    if (btn)
    {
        switch (g_status)
        {
            case START:
                [self start:sender andTag:btn.tag];
                break;
                
            case HISTROY:
                [self histroy:sender andTag:btn.tag];
                break;
                
            case COUNT:
                [self count:sender andTag:btn.tag];
                break;
                
            case RESULT:
                [self result:sender andTag:btn.tag];
                break;
        }
    }
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    
    CGRect frameRect = [[UIScreen mainScreen] applicationFrame];
    int xSpace = 10, ySpace = 10, btnNormalWidth = 60, btnNormalHeight = 35;
    
    int x = xSpace, y = frameRect.origin.y + ySpace;
    _inputHistroy = [[UILabel alloc] init];
    _inputHistroy.frame = CGRectMake(x, y, btnNormalWidth*3 + xSpace*2, btnNormalHeight);
    _inputHistroy.layer.cornerRadius = 10;
    _inputHistroy.layer.borderColor = [UIColor grayColor].CGColor;
    _inputHistroy.layer.borderWidth = 1.5;
    _inputHistroy.text = @"";
    [self.window addSubview:_inputHistroy];
    
    x = x + _inputHistroy.frame.size.width + xSpace;
    _inputCurrent = [[UILabel alloc] init];
    _inputCurrent.frame = CGRectMake(x, y, btnNormalWidth, btnNormalHeight);
    _inputCurrent.layer.cornerRadius = 10;
    _inputCurrent.layer.borderColor = [UIColor grayColor].CGColor;
    _inputCurrent.layer.borderWidth = 1.5;
    _inputCurrent.text = @"0";
    [self.window addSubview:_inputCurrent];
    
    x = xSpace;
    y = y + btnNormalHeight + ySpace;
    [ButtonFactory createCalcButton:self andRect:CGRectMake(x, y, btnNormalWidth, btnNormalHeight) andTag:7 andTitle:@"7" andSel:@selector(allBtnClick:)];
    
    x = x + btnNormalWidth + xSpace;
    [ButtonFactory createCalcButton:self andRect:CGRectMake(x, y, btnNormalWidth, btnNormalHeight) andTag:8 andTitle:@"8" andSel:@selector(allBtnClick:)];
    
    x = x + btnNormalWidth + xSpace;
    [ButtonFactory createCalcButton:self andRect:CGRectMake(x, y, btnNormalWidth, btnNormalHeight) andTag:9 andTitle:@"9" andSel:@selector(allBtnClick:)];
    
    x = x + btnNormalWidth + xSpace;
    [ButtonFactory createCalcButton:self andRect:CGRectMake(x, y, btnNormalWidth, btnNormalHeight) andTag:DIVIDE andTitle:@"/" andSel:@selector(allBtnClick:)];
    
    x = xSpace;
    y = y + btnNormalHeight + ySpace;
    [ButtonFactory createCalcButton:self andRect:CGRectMake(x, y, btnNormalWidth, btnNormalHeight) andTag:4 andTitle:@"4" andSel:@selector(allBtnClick:)];
    
    x = x + btnNormalWidth + xSpace;
    [ButtonFactory createCalcButton:self andRect:CGRectMake(x, y, btnNormalWidth, btnNormalHeight) andTag:5 andTitle:@"5" andSel:@selector(allBtnClick:)];
    
    x = x + btnNormalWidth + xSpace;
    [ButtonFactory createCalcButton:self andRect:CGRectMake(x, y, btnNormalWidth, btnNormalHeight) andTag:6 andTitle:@"6" andSel:@selector(allBtnClick:)];
    
    x = x + btnNormalWidth + xSpace;
    [ButtonFactory createCalcButton:self andRect:CGRectMake(x, y, btnNormalWidth, btnNormalHeight) andTag:MULTIPLY andTitle:@"*" andSel:@selector(allBtnClick:)];
    
    x = xSpace;
    y = y + btnNormalHeight + ySpace;
    [ButtonFactory createCalcButton:self andRect:CGRectMake(x, y, btnNormalWidth, btnNormalHeight) andTag:1 andTitle:@"1" andSel:@selector(allBtnClick:)];
    
    x = x + btnNormalWidth + xSpace;
    [ButtonFactory createCalcButton:self andRect:CGRectMake(x, y, btnNormalWidth, btnNormalHeight) andTag:2 andTitle:@"2" andSel:@selector(allBtnClick:)];
    
    x = x + btnNormalWidth + xSpace;
    [ButtonFactory createCalcButton:self andRect:CGRectMake(x, y, btnNormalWidth, btnNormalHeight) andTag:3 andTitle:@"3" andSel:@selector(allBtnClick:)];
    
    x = x + btnNormalWidth + xSpace;
    [ButtonFactory createCalcButton:self andRect:CGRectMake(x, y, btnNormalWidth, btnNormalHeight) andTag:SUBTRACT andTitle:@"-" andSel:@selector(allBtnClick:)];
    
    x = xSpace;
    y = y + btnNormalHeight + ySpace;
    [ButtonFactory createCalcButton:self andRect:CGRectMake(x, y, btnNormalWidth*2+xSpace, btnNormalHeight) andTag:0 andTitle:@"0" andSel:@selector(allBtnClick:)];
    
    x = x + btnNormalWidth*2 + xSpace*2;
    [ButtonFactory createCalcButton:self andRect:CGRectMake(x, y, btnNormalWidth, btnNormalHeight) andTag:PM andTitle:@"PM" andSel:@selector(allBtnClick:)];
    
    x = x + btnNormalWidth + xSpace;
    [ButtonFactory createCalcButton:self andRect:CGRectMake(x, y, btnNormalWidth, btnNormalHeight) andTag:ADD andTitle:@"+" andSel:@selector(allBtnClick:)];
    
    x = xSpace;
    y = y + btnNormalHeight + ySpace;
    [ButtonFactory createCalcButton:self andRect:CGRectMake(x, y, btnNormalWidth*2+xSpace, btnNormalHeight) andTag:DELETE andTitle:@"Backspace" andSel:@selector(allBtnClick:)];
    
    x = x + btnNormalWidth*2 + xSpace*2;
    [ButtonFactory createCalcButton:self andRect:CGRectMake(x, y, btnNormalWidth, btnNormalHeight) andTag:EMPTY andTitle:@"C" andSel:@selector(allBtnClick:)];
    
    x = x + btnNormalWidth + xSpace;
    [ButtonFactory createCalcButton:self andRect:CGRectMake(x, y, btnNormalWidth, btnNormalHeight) andTag:EQUAL andTitle:@"=" andSel:@selector(allBtnClick:)];
    
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
    // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
    // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}

@end


@implementation ButtonFactory

+ (id) createCalcButton:(id)parent andRect:(CGRect)rect andTag:(NSInteger)tag andTitle:(NSString*)title andSel:(SEL)sel
{
    UIButton *ret = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    ret.frame = rect;
    ret.tag = tag;
    ret.layer.cornerRadius = 10;
    ret.layer.borderColor = [UIColor grayColor].CGColor;
    ret.layer.borderWidth = 1.5;

    [ret setTitle:title forState:UIControlStateNormal];
    [ret addTarget:parent action:sel forControlEvents:UIControlEventTouchDown];
    AppDelegate *app = parent;
    [app.window addSubview:ret];
    return ret;
}

@end

【上篇】
【下篇】

抱歉!评论已关闭.