前回「その5」で紹介、および私なりに解説したのが、P216の第13章のチャレンジ問題。本書を次の第14章へと読み進めていくと、やっぱり”このままじゃいかんなぁ”という気になってきます。本書P217にもあるとおり、”Preference=環境設定”パネルの設定は既にオープンされているウィンドウには働かず、設定以降新たにオープンされるウィンドウにしか適用されません。チャレンジ問題で環境設定を初期値に戻すリセットボタンを設置した訳ですが、このリセットボタンも同様に、リセット後新たに開いたウィンドウは初期値に戻されてても、既にオープンしているウィンドウはリセットされずそのままの状態です。実際にこういう動作をするアプリって結構見かけますが、どうでしょう。そんでもって、これはまさしく第14章の”通知=Notificationの使用”が解決する内容ですので、私なりに修正してみました。
先ずリセットボタンが押されたという通知に名前を付けるため、”PrefernceController.h”ファイル内で、以下の赤文字のグローバル変数を新規に宣言します。宣言する場所は、”@interface”の直前にしています。変数なので、名前の付け方は適当ですよ。
extern NSString * const BNRTableBgColorKey;
extern NSString * const BNREmptyDocKey;
extern NSString * const BNRColorChangedNotification;
extern NSString * const BNRColorResetNotification;
extern NSString * const BNREmptyDocKey;
extern NSString * const BNRColorChangedNotification;
extern NSString * const BNRColorResetNotification;
続いて"PreferenceController.m"ファイルで、以下のとおりグローバル変数(赤字)を実装します。これまた実装する場所は、”@implementation PreferenceController”の直前にしました。
NSString * const BNRTableBgColorKey = @"Table Background Color";
NSString * const BNREmptyDocKey = @"Empty Document Flag";
NSString * const BNRColorChangedNotification = @"BNRColorChanged";
NSString * const BNRColorResetNotification = @"BNRColorReset";
NSString * const BNREmptyDocKey = @"Empty Document Flag";
NSString * const BNRColorChangedNotification = @"BNRColorChanged";
NSString * const BNRColorResetNotification = @"BNRColorReset";
次に、”PreferenceController.m”の”-(IBAction)resetPreference:(id)sender”メソッドに、以下のように赤字の部分を追記します。このアクションメソッドは環境設定パネルのリセットボタンの動作内容を決めます。追加した部分は、リセットボタンが押されたことを既にオープンしている複数のウィンドウにポスト(公表)するものです。ここでバックグラウンドカラーの初期値を得るのため、あの変数この変数と試してみたのですが上手くいかず、結局一度リセットさせた”colorWell”から初期値を得ることにしました。どうも腑に落ちない部分です。
- (IBAction)resetPreference:(id)sender {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObjectForKey:BNRTableBgColorKey];
[defaults removeObjectForKey:BNREmptyDocKey];
[colorWell setColor:[self tableBgColor]];
[checkbox setState:[self emptyDoc]];
NSColor *color = [colorWell color];
NSData *colorAsData = [NSKeyedArchiver archivedDataWithRootObject:color];
[[NSUserDefaults standardUserDefaults] setObject:colorAsData forKey:@"defaultColor"];
NSDictionary *defaultValues = [NSDictionary dictionaryWithObject:color forKey:@"defaultColor"];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc postNotificationName:BNRColorResetNotification object:self userInfo:defaultValues];
}
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults removeObjectForKey:BNRTableBgColorKey];
[defaults removeObjectForKey:BNREmptyDocKey];
[colorWell setColor:[self tableBgColor]];
[checkbox setState:[self emptyDoc]];
NSColor *color = [colorWell color];
NSData *colorAsData = [NSKeyedArchiver archivedDataWithRootObject:color];
[[NSUserDefaults standardUserDefaults] setObject:colorAsData forKey:@"defaultColor"];
NSDictionary *defaultValues = [NSDictionary dictionaryWithObject:color forKey:@"defaultColor"];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc postNotificationName:BNRColorResetNotification object:self userInfo:defaultValues];
}
さらに、リセットボタンが押されたという通知のポストを監視するオブザーバを、各ウィンドウの動作内容を定めている”MyDocumnt.m”ファイル内の”- (id)init”メソッドに追加しました。”BNRColorResetNotification”という名前の通知がポストされたら、”@selector()”で指示された”resetColorChange:”メソッドが呼び出されるしくみです。
NSNotificationCenter *nc2 = [NSNotificationCenter defaultCenter];
[nc2 addObserver:self
selector:@selector(resetColorChange:) name:BNRColorResetNotification object:nil];
[nc2 addObserver:self
selector:@selector(resetColorChange:) name:BNRColorResetNotification object:nil];
最後に”MyDocument.m”ファイル内に、”resetColorChange:”メソッドを実装すればOKです。
- (void)resetColorChange:(NSNotification *)note {
NSColor *color = [[note userInfo] objectForKey:@"defaultColor"];
[tableView setBackgroundColor:color];
NSLog(@"reset color is %d",color);
}
NSColor *color = [[note userInfo] objectForKey:@"defaultColor"];
[tableView setBackgroundColor:color];
NSLog(@"reset color is %d",color);
}
なんとか第13章のチャレンジ問題を、私なりに修正した次第です。まっ、こういう時間と労力のかかる趣味も、GWならではとういうことでご勘弁ください。
0 件のコメント:
コメントを投稿