Чтение онлайн

ЖАНРЫ

Программирование на Objective-C 2.0
Шрифт:

Первая программа iPhone в этой главе начиналась с шаблона проекта типа Window-Based. Наша небольшая работа, связанная с пользовательским интерфейсом (Ш), была выполнена непосредственно в контроллере приложения (с помошью класса AppDelegate). Такой подход не рекомендуется для разработки приложений с насыщенным пользовательским интерфейсом. Класс AppDelegate обычно используется только для обработки изменений, относящихся к состоянию самого приложения, например, к окончанию запуска приложения или к его завершению.

Рис. 21.21 Ввод операции

Контроллер представлений (view controller), реализованный с помощью класса UlViewController, подходит именно для действий, относящихся к Ш, таких как отображение текста, реагирование на нажатие кнопки или вывод другого представления на экране iPhone.

Разработку

второго примера программы мы начнем с создания нового проекта. На этот раз в окне New Project мы выберем тип View-Based Application и назовем новый проект Fraction_Calculator.

Рис. 21.22. Результат умножения двух дробей

При создании проекта вы увидите, что на этот раз используются два шаблона классов. FractionCalculatorAppDelegate.il и Fraction_CalсuIatorАрpDelegate.m определяют для нашего проекта класс контроллера приложения, a Fraction CalculatorViewController.h и Fraction CalculatorViewController.m определяют класс контроллера представлений. Как говорилось выше, вся наша работа будет выполнена именно во втором классе.

Начнем с класса контроллера приложения. Он содержит две переменные экземпляра: одну для ссылки на окно iPhone и вторую — для контроллера представлений. Обе переменные заданы вХсобе. Вам не потребуется вносить никакие изменения в .h-файл и .m-файл контроллера приложения.

Файл секции interface Fraction_CalculatorApp Delegate показан в программе 21.2.

Программа 21.2. Interface-файл Fraction_CalculatorAppDelegate.h #import <UIKit/UIKit.h> @class Fraction_CalculatorViewController; @interface FractionCalculatorAppDelegate : NSObject <UIApplicationDelegate> { IBOutlet UlWindow *window; IBOutlet Fraction CalculatorViewController *viewController; } @property (nonatomic, retain) UlWindow *window; @property (nonatomic, retain) Fraction_CalculatorViewController *viewController; @end

Переменная экземпляра UlWindow window предназначена для той же цели, что и в первой программе: она представляет окно iPhone. Переменная экземпляра Fraction_CalculatorViewController используется для контроллера представлений, который будет управлять всем взаимодействием с пользователем и выводом на дисплей. В файле секции implementation для этого класса мы реализуем всю работу, связанную с этими задачами.

В программе 21.2 показан implementation-файл для класса контроллера приложения. Как говорилось выше, мы не будем делать никакой работы в этом файле (в отличие от программы 21.1); вся работа передается контроллеру представлений. Таким образом, этот файл показан так, как он генерируется Xcode при создании нового проекта.

Программа 21.2. Implementation-файл Fraction_CalculatorAppDelegate.m #import "FractionCalculatorAppDelegate.h" #import "Fraction CalculatorViewController.h" @implementation Fraction_CalculatorAppDelegate @synthesize window; @synthesize viewController; -(void)applicationDidFinishLaunching:(UIApplication *(application ( // Место переопределения для настройки после запуска приложения [window addSubview:viewController.view]; [window makeKeyAndVisible]; -(void)dealloc { [viewController release]; [super deallocj; @end Определение контроллера представлений

Теперь мы напишем код для класса контроллера представлений Fraction CalculatorViewController. Начнем с файла секции interface. Он показан в про грамме 21.2.

Программа 21.2. Interface-файл Fraction_CalculatorViewController.h #import <UIKit/UIKit.h> #import "Calculator.h" @interface Fraction_CalculatorViewController : UlViewController { UlLabel *display; char op; int currentNumber; NSMutableString *displaystring; BOOL firstOperand, isNumerator; Calculator *myCalculator; } @property {nonatomic, retain) IBOutlet UlLabel *display; @property (nonatomic, retain) NSMutableString *displaystring; -(void) processDigit: (int) digit; -(void) processOp: (char) op; -(void) storeFracPart; // Числовые клавиши -(IBAction) clickDigit; (id) sender; // Клавиши арифметических операций -(IBAction) clickPlus: (id) sender; -(IBAction) clickMinus: (id) sender; -(IBAction) clickMultiply: (id) sender; -(IBAction) clickDivide: (id) sender; // Другие клавиши -(IBAction) clickOver: (id) sender; -(IBAction) clickEquals: (id) sender; -(IBAction) clickClear: (id) sender; @end

У нас имеются служебные переменные для создания дробей (currentNumber, firstOperand и isNumerator) и для создания выводимой строки (displayString). Объект типа Calculator (myCalculator) выполняет конкретные вычисления между двумя дробями. Мы выполним привязку метода с именем clickDigit: для обработки нажатий цифровых клавиш 0-9. И, наконец, мы определяем методы для хранения операции, которая должна быть

выполнена (clickPlus:, clickMinus:, clickMultiply:, clickDivide:), выполняя сами вычисления при нажатии клавиши = (clickEquals:), сброс текущей операции (clickClear:) и отделение числителя от знаменателя при нажатии клавиши Over (clickOver:). Несколько методов (processDigit:, processOp: и StoreFracPart) определяются для этих задач как вспомогательные средства.

В программе 21.2 показан файл секции implementation для этого класса контроллера.

Программа 21.2. Implementation-файл Fraction_CalculatorViewController.m #import «Fraction_CalculatorViewController.h» @implementation FractionCalculatorViewController @synthesize display, displayString; -(void) viewDidLoad { // Место переопределения для настройки после запуска приложения firstOperand = YES; isNumerator = YES; self.displayString = [NSMutableString stringWithCapacify: 40]; myCalculator = [[Calculator alloc] init]; -(void) processDigit: (int) digit { currentNumber = currentNumber * 10 + digit; [displayString appendString: [NSString stringWithFormat: <a>"%i\ digit]]; [display setText: displayString]; -(IBAction) clickDigit:(id)sender { int digit = [sender tag]; [self processDigit: dig it]; } -{void) processOp: (char) theOp { NSString *opStr; op = theOp; switch (theOp) { case opStr = + "; break; case opStr = -"; break; case *': opStr = <@" ? "; break; case opStr = break; } [self storeFracPart]; firstOperand = NO; isNumerator = YES; [displaystring appendString: opStr); [display setText: displaystring]; -(void) storeFracPart { if (firstOperand) { if (isNumerator) { myCalculator.operandl.numerator = currentNumber; myCalculator.operandl .denominator = 1; // e g. 3*4/5 = ) else myCalculator.operandl.denominator = currentNumber; } else if (isNumerator) { myCalculator.operand2.numerator = currentNumber; myCalculator.operand2.denominator = 1; // e.g. 3/2*4 = } else { myCalculator.operand2.denominator = currentNumber; firstOperand = YES; } currentNumber = 0; } -(IBAction) clickOver: (id) sender { [self storeFracPart]; isNumerator = NO; [displaystring appendString: @"/"]; [display setText: displaystring]; } // Клавиши арифметических операций -(IBAction) clickPlus: (id) sender { [self processOp: } -(IBAction) clickMinus: (id) sender { [self processOp: } -(IBAction) clickMultiply: (id) sender { [self processOp: } -(IBAction) clickDivide: (id) sender { [self processOp: У]; ) // Другие клавиши -(IBAction) clickEquals: (id) sender { [self storeFracPart]; [myCalculator performOperation: op]; [displaystring appendString: = "]; [displaystring appendString: [myCalculator.accumulator convertToString]]; [display setText: displayString]; currentNumber = 0; isNumerator = YES; firstOperand = YES; [displayString setString: (§>""]; } -(IBAction) clickClear: (id) sender { isNumerator = YES; firstOperand = YES; currentNumber = 0; [myCalculator clear]; [displayString setString: @'"]; [display setText: displayString]; -(void)dealloc { [myCalculator dealloc]; [super dealloc]; } @end

Окно калькулятора пока содержит только одну метку, как в предыдущем приложении, и мы по-прежнему называем се display. По мерс того, как пользователь вводит число пифра за цифрой, мы должны формировать это число. Переменная currentNumber содержит накапливаемое число, а BOOL-переменные firstOperand и isNumerator следят за тем, какой операнд введен (первый или второй), и что представляет этот операнд — числитель или знаменатель.

При нажатии числовой клавиши идентифицирующая информация будет передаваться методу clickDigit:, чтобы указать, какая числовая клавиша была нажата. Для этого атрибуту клавиши с именем tag (с помощью средства Inspector в Interface Builder) присваивается соответствующее значение каждой числовой клавиши. В данном случае нам нужно присвоить tag соответствующую цифру. Например, для клавиши с меткой 0 tag будет присвоено значение 0, для клавиши с меткой 1 — значение 1, и т.д. При последующей отправке сообщения tag параметру sender, который передается методу clickDigit:, мы считываем значение тега клавиши. Это происходит в методе clickDigit:, как показано ниже. -(IBAction) clickDigit:(id)sender { int digit = [sender tag]; [self processDigitrdigit]; }

В программе 21.2 намного больше клавиш, чем в первом приложении. Наиболее сложной частью в implementation-файле контроллера представлений является формирование и отображение дробей. Как говорилось выше, при нажатии числовой клавиши от 0 до 9 выполняется action-метод clickDigit:. Этот метод вызывает метод processDigit:, который помещает цифру в конец числа, формируемого в переменной currentNumber. Этот метод также добавляет цифру в текущую строку отображения, которая поддерживается в переменной displaystring, и обновляет отображение. -(void) processDigit: (int) digit ( currentNumber = currentNumber * 10 + digit; [displaystring appendString: [NSString stringWithFormat: @"%i", digit]]; [display setText: displaystring];}

Поделиться с друзьями: