はじめに
生徒管理システムはC言語で実装された同様のシステムと機能要件が類似しており、追加・削除・更新・検索・ソート機能を実装する必要があります。この実装は比較的シンプルですが、入力制限の要件を通じて正規表現の基本的な理解を得ることができます。
認証画面
ログインおよび登録画面は他のプロジェクトと同様の構成であり、詳細な説明は省略します。
メイン画面
この画面はUITableViewとボタンから構成され、上部には3つのUILabelでタイトルが表示されます。全体的にシンプルな構造であるため、詳細説明は省略します。
データ追加機能
追加処理ではまず配列を走査し、既存の生徒データとの重複を確認します。同じクラス内で同名の生徒が存在しないようにクラス情報も検証対象とします。
- (void)handleAddition {
BOOL nameExists = NO;
BOOL classExists = NO;
BOOL invalidScore = NO;
NSString* studentName = self.nameInputField.text;
NSString* className = self.classInputField.text;
NSString* scoreText = self.scoreInputField.text;
for(int index = 0; index < self.studentNames.count; index++) {
if([studentName isEqualToString:self.studentNames[index]] &&
[className isEqualToString:self.classNames[index]]) {
nameExists = YES;
classExists = YES;
break;
}
if(scoreText.intValue < 0 || scoreText.intValue > 150) {
invalidScore = YES;
break;
}
}
if(studentName.length > 0 && className.length > 0 && scoreText.length > 0) {
self.nameInputField.text = nil;
self.classInputField.text = nil;
self.scoreInputField.text = nil;
if(nameExists && classExists) {
[self showAlertWithTitle:@"警告"
message:@"指定された生徒は既に登録済みです"
action:^{
[self dismissModal:YES completion:nil];
}];
} else if(invalidScore) {
[self showAlertWithTitle:@"警告"
message:@"有効なスコアを入力してください"
action:^{
// エラー処理
}];
} else {
[self.studentNames addObject:studentName];
[self.classNames addObject:className];
[self.scores addObject:scoreText];
[self showAlertWithTitle:@"成功"
message:@"生徒情報を正常に登録しました"
action:^{
[self.delegate updateStudentData:self.studentNames
classes:self.classNames
scores:self.scores];
[self dismissModal:YES completion:nil];
}];
}
} else {
[self showAlertWithTitle:@"エラー"
message:@"すべてのフィールドに入力してください"
action:^{}];
}
}
データ削除機能
削除処理では対象生徒を配列から検索し、見つかった場合にその要素を削除します。生徒名だけでなくクラス情報も同時に削除することで、データの整合性を維持します。
BOOL foundStudent = NO;
BOOL classMatched = NO;
NSString* targetName = self.searchNameField.text;
NSString* targetClass = self.searchClassField.text;
int removalIndex = 0;
for(int idx = 0; idx < self.studentNames.count; idx++) {
if([targetName isEqualToString:self.studentNames[idx]] &&
[targetClass isEqualToString:self.classNames[idx]]) {
foundStudent = YES;
classMatched = YES;
removalIndex = idx;
break;
}
}
if(targetName.length > 0 && targetClass.length > 0) {
if(foundStudent && classMatched) {
[self.studentNames removeObjectAtIndex:removalIndex];
[self.classNames removeObjectAtIndex:removalIndex];
[self.scores removeObjectAtIndex:removalIndex];
[self showAlertWithTitle:@"完了"
message:@"生徒情報を削除しました"
action:^{
[self.delegate removeStudentData:self.studentNames
classes:self.classNames
scores:self.scores];
[self dismissModal:YES completion:nil];
}];
} else {
[self showAlertWithTitle:@"情報"
message:@"該当する生徒が見つかりません"
action:^{
self.searchNameField.text = @"";
self.searchClassField.text = @"";
}];
}
} else {
[self showAlertWithTitle:@"エラー"
message:@"必要な情報を入力してください"
action:^{
self.searchNameField.text = @"";
self.searchClassField.text = @"";
}];
}
データ検索橜能
検索機能は入力された名前に基づいて配列全体を検索し、一致した結果を新しい配列に格納してテーブルビューに表示します。
- (void)performSearch {
BOOL matchFound = NO;
self.foundNames = [NSMutableArray array];
self.foundClasses = [NSMutableArray array];
self.foundScores = [NSMutableArray array];
NSString* searchQuery = self.queryField.text;
int currentIndex = 0;
for(int idx = 0; idx < self.studentNames.count; idx++) {
if([searchQuery isEqualToString:self.studentNames[idx]]) {
matchFound = YES;
currentIndex = idx;
[self.foundNames addObject:self.studentNames[idx]];
[self.foundClasses addObject:self.classNames[idx]];
[self.foundScores addObject:self.scores[idx]];
}
}
if(searchQuery.length == 0) {
[self showAlertWithTitle:@"注意"
message:@"検索キーワードを入力してください"
action:^{}];
}
if(matchFound) {
[self showAlertWithTitle:@"結果"
message:@"生徒情報を検索しました"
action:^{
[self configureResultsTable];
}];
} else {
[self showAlertWithTitle:@"情報"
message:@"該当する生徒がいません"
action:^{
self.resultsTableView.hidden = YES;
self.queryField.text = @"";
}];
}
}
- (void)configureResultsTable {
self.resultsTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 100,
[UIScreen mainScreen].bounds.size.width,
300)
style:UITableViewStylePlain];
self.resultsTableView.delegate = self;
self.resultsTableView.dataSource = self;
self.resultsTableView.hidden = NO;
[self.view addSubview:self.resultsTableView];
[self.resultsTableView registerClass:[ResultCell class]
forCellReuseIdentifier:@"resultCell"];
}
情報更新機能
情報変更機能ではまず対象生徒を特定し、クラスとスコアを更新します。ただし、変更後のクラス情報が重複しないように確認が必要です。
- (void)updateStudentInfo {
NSString* currentName = self.currentNameField.text;
NSString* currentClass = self.currentClassField.text;
NSString* newClass = self.newClassField.text;
NSString* newScore = self.newScoreField.text;
BOOL studentLocated = NO;
BOOL classMatched = NO;
int updatePosition = 0;
for(int idx = 0; idx < self.studentNames.count; idx++) {
if([currentName isEqualToString:self.studentNames[idx]] &&
[currentClass isEqualToString:self.classNames[idx]]) {
studentLocated = YES;
classMatched = YES;
updatePosition = idx;
break;
}
}
for(int idx = 0; idx < self.studentNames.count; idx++) {
if([currentName isEqualToString:self.studentNames[idx]] &&
[newClass isEqualToString:self.classNames[idx]]) {
[self showAlertWithTitle:@"警告"
message:@"指定のクラスに同じ生徒が既に存在します"
action:^{
return;
}];
}
}
if(currentName.length > 0 && currentClass.length > 0 &&
newClass.length > 0 && newScore.length > 0) {
if(newScore.intValue < 0 || newScore.intValue > 150) {
[self showAlertWithTitle:@"エラー"
message:@"有効なスコアを入力してください"
action:^{}];
}
if(studentLocated && classMatched) {
[self.classNames replaceObjectAtIndex:updatePosition withObject:newClass];
[self.scores replaceObjectAtIndex:updatePosition withObject:newScore];
[self showAlertWithTitle:@"成功"
message:@"情報を更新しました"
action:^{
[self.delegate refreshStudentData:self.studentNames
classes:self.classNames
scores:self.scores];
[self dismissModal:YES completion:nil];
}];
} else {
[self showAlertWithTitle:@"情報"
message:@"生徒が見つかりませんでした"
action:^{}];
}
} else {
[self showAlertWithTitle:@"エラー"
message:@"すべてのフィールドを入力してください"
action:^{
self.resetInputFields;
}];
}
}
データソート機能
ソート処理にはバブルソートアルゴリズムを使用しています。実装はシンプルです。
for(int outer = 0; outer < self.studentNames.count; outer++) {
for(int inner = 0; inner < self.studentNames.count - outer - 1; inner++) {
if([self.scores[inner] intValue] > [self.scores[inner + 1] intValue]) {
NSString* tempName = self.studentNames[inner];
NSString* tempClass = self.classNames[inner];
NSString* tempScore = self.scores[inner];
self.studentNames[inner] = self.studentNames[inner + 1];
self.classNames[inner] = self.classNames[inner + 1];
self.scores[inner] = self.scores[inner + 1];
self.studentNames[inner + 1] = tempName;
self.classNames[inner + 1] = tempClass;
self.scores[inner + 1] = tempScore;
}
}
}