2

さまざまなエンティティと属性を持つコア データ Mac アプリがあります...これらの属性の 1 つが NSButton チェック ボックスにバインドされています...

ここに私の問題があります:ボタンをマウスでクリックすると、その状態が変化するのを見ることができます(たとえば、チェックされていない状態からチェックされている状態に変化します)。バインドされた属性の状態はデータコアに保存されます。アプリを再度開くと、ボタンはまだチェックされています...

しかし ...

このボタンの状態をプログラムで変更すると、その状態が変化するのを確認できます (同じ例で、チェックされていない状態からチェックされている状態に変化します)。ただし、バインドされた属性の状態はデータコアに保存されず、閉じて再アプリを開くと、ボタンはチェックされていない状態に戻ります!

何か案は ?

編集

では、説明を試みます (下手な英語で申し訳ありません) …</p>

Adherents と呼ばれるこのエンティティのいくつかの値を使用して、いくつかの操作と検証を行う必要があります (たとえば、date1> date2 の場合、checkbox1 がオンになり、checkbox2 がオンの場合、日付の比較に関係なく、checkbox1 がオンになります) …</p>

最初に、「NSManagedObject サブクラス ファイル Adherents.m」で、このエンティティの値を使用してこれらの操作を行うソリューションを指摘しました。

- (void)awakeFromFetch{

 [super awakeFromFetch];


    // Controle de la cotisation
    aujourdhui = [NSDate date];
    finCotisation = [NSDate dateWithString:[dateCotisation description]];
    controle = [aujourdhui compare:finCotisation];
   if(controle == NSOrderedAscending)
   {
       self.cotisation = [NSNumber numberWithBool:1];
   }
    else if(controle == NSOrderedDescending)
    {
       if ([self.membreHonneur boolValue] == 0)
       {
            self.cotisation = [NSNumber numberWithBool:0];
        }
      else if ([self.membreHonneur boolValue] == 1)
       {
            self.cotisation = [NSNumber numberWithBool:1];
       }
    }
}

そのように、操作はアプリの起動時にのみ発生します。これは良いことですが、十分ではありません…「途中で」(ユーザーが NSDatePicker を介して日付を入力または変更した直後) 実行するには、私が見つけた最良の解決策は、日付ピッカーはユーザーによって編集されています... AppDelegate.mファイルでしかできないようです(Adherents.hで「IBOutlet NSDatePicker *champDate;」を宣言しようとしましたが、アウトレットをチェックボックスに接続できませんでしたInterface Builder で …)、そこからエンティティ値にアクセスして操作することもできないようです (「self.cotisation」は、AppDelegate.m で使用すると不明なプロパティをもたらし、それを宣言する方法を見つけることができませんでしたAppDelegate.h で正しく)。

したがって、私の解決策は、AppDelegate でこれらの操作を行い、NSDatePicker の値を比較し、NSButton チェックボックスの状態に基づいて操作することです…

- (void)awakeFromNib {

    [champDate setTarget:self];
    [champDate setAction:@selector(checkDate:)];

}

-(void)checkDate:(id)object {
   finCotisation = [NSDate dateWithNaturalLanguageString:[champDate stringValue]];
   aujourdhui = [NSDate date];
   NSComparisonResult controle = [aujourdhui compare:finCotisation];
    if(controle == NSOrderedAscending){
        [bouttonCotisation setState:TRUE];
    }
    else if(controle == NSOrderedDescending){
        [bouttonCotisation setState:FALSE];
   }
}

しかし、そのように振る舞うと、バインディングは失敗します…したがって、NSDatePicker を監視し、AppDelegate.m でプログラムによってチェックボックスの状態を変更する必要があります。すべてが束縛されているときはナンセンスです^^

4

1 に答える 1

3

私はあなたの問題の詳細を理解しているかどうかはわかりませんが、これだけ集めました:

  • データモデルオブジェクトの外部から見ると、次のプロパティがあります
    • 2つの日付値
    • ブール値
    • 他の3つの値に応じて異なる値を持つ必要がある2番目のブール値
  • メソッドの依存値のみを更新するawakeFromFetchため、実行時にデータが変更されても更新されないため、AppDelegateのチェックボックスを手動で変更します。

このアプローチには2つの問題があります。

  1. バインディングを使用する場合は、UI要素のセッターを直接呼び出すのではなく、UIを更新するためにモデルデータのみを変更する必要があります。
  2. 他のプロパティに完全に依存しているプロパティがある場合は、それを個別に保存しないでください(キャッシュの理由を除いて、それはより複雑になります)。その場で計算するだけです。

モデルクラスは次のようになっていると思います。

@interface
@property (strong) NSDate *date1;
@property (strong) NSDate *date2;
@property (assign BOOL someBool;
@end

ここで、同じ方法でヘッダーファイルに依存プロパティを追加することを宣言します。

// readonly because it cannot be changed directly, only the values it depends on can be changed
@property (assign, readonly) BOOL dependentBool;

ただし、このプロパティでは、@implementationにゲッターを実装します。

-(BOOL)dependentBool
{
    if (NSOrderedAscending = [self.date1 compare:self.date2])
        return YES;

    if (self.someBool)
        return YES;

    return NO;
}

このように、誰かがdependentBoolプロパティをチェックするたびに、正しい結果が返されます。これで、チェックボックスをdependentBoolにバインドできます。ただし、値のいずれかを変更した場合、値が変更されたことを認識しないため、チェックボックスに依存しますが更新されません。これを修正するには、モデルクラスの実装に次のメソッドを追加します。

+(NSSet *)keyPathsForValuesAffectingDependentBool
{
    return [NSSet setWithArray:@[@"date1", @"date2", @"someBool"]];
}

これは、dependentBoolプロパティを監視しているすべての人に(このプロパティにバインドされているときにチェックボックスが行うように)、これらのキーパスに依存しているため、これらのキーパスも監視する必要があることを通知します。

date1このようにして、たとえばの値を変更するだけで、それにバインドされたビューdependentBoolがそれに応じて変更されます。

注:これを正しく機能させるには、インスタンス変数を直接変更するのではなく、セッター([myModelObject setDate1:date]またはmyModelObject.date1 = dateまたは)を使用してプロパティの値を変更する必要があります( )。self.date1 = date_date1 = date

この例をニーズに合わせて調整できることを願っています。

于 2013-01-08T11:56:27.030 に答える