1

内部から呼び出される2つのメソッドがあります-drawRect:

- (void)drawRect:(CGRect)rect  {

    if(drawScheduleFlag) {
        [self drawSchedule];
        drawScheduleFlag = false;
    }
    else
        [self drawGrid];
}

-drawGrid初期化時に呼び出されます。もう1つのメソッド(-drawSchedule)は、メインスレッドにあるこのコードから呼び出されます。

- (void) calendarTouched: (CFGregorianDate) selectedDate  {

//    NSLog(@"calendarTouched - currentSelectDate: %d/%d/%d", selectedDate.month, selectedDate.day, selectedDate.year);
//    NSLog(@"Main thread? %d", [NSThread isMainThread]);

    //  get data from d/b for this date (date, staff name, cust name, time, length, services required)
    //------    stub    -------
    scheduledDate.year = 2012;
    scheduledDate.month = 6;
    scheduledDate.day = 20;
    staffName = @"Saori";
    custName = @"Brian";
    startTime.hour = 11;
    duration = 2;
    servicesReqd = @"Nails";

    drawScheduleFlag = true;
    [self setNeedsDisplay];

    return;
}

コードが実行されていることはわかっていますが、スケジュールを描くことはできません。なぜ呼び出されない-[self setNeedsDisplay]のですか?-drawRect

更新:私は休憩を入れたので、それが呼び出されていないことを確信しています。元のグリッドは1回描画されます。ユーザーがカレンダーの日付をタップすると、-calendarTouchedが呼び出され、完全に実行されます。drawScheduleFlagがtrueに設定され、-[self setNeedsDisplay]が呼び出されますが、-drawRectは呼び出されません。UIViewが無効化されていないようです(-setNeedsDisplayが行うことになっています)。したがって、-drawRectは呼び出されません。

更新#2:2つのUIViewを含むUIViewControllerの.xibがあります。最初のUIViewはiPad画面の約1/3を占め、2番目のUIViewは画面の下部2/3を占めます。各UIViewには、独自の特定のクラスがあります。上部のUIViewにはカレンダーが表示され、正しく機能しており、タッチをキャプチャして、選択した日付を変更します。

下部のUIViewは、上部のUIViewで選択された日付のスケジュールを表示することになっています。ここに問題があります。上部のUIViewが機能しているので、下部のUIViewのクラスのコードを配置します。基本的に、-drawRectが最初に呼び出されたときにスケジュールグリッドを描画します。ユーザーが1日を選択すると、UIViewを無効にして、グリッドに実際のスケジュールを描画することになっています。

これがSchedule.h のコードです:http: //pastebin.com/NQpj0i07これ がSchedule.m のコードです:http: //pastebin.com/YBbE8y0T これがコントローラーのコードです: http://pastebin。 com/nDqBCivj 両方のペーストビンは6月28日午後5時38分PSTから24時間で期限切れになることに注意してください

4

1 に答える 1

2

コメントで言ったことを繰り返しますが、問題はUIView、呼び出しが実行される前にサブクラスオブジェクトの割り当てが解除drawRectされることです。つまり、オブジェクトへの参照を保持しているもの、この場合はコントローラーが、オブジェクトを解放します。つまり、ARCの使用で発生することがある小さな問題です。

このビューを保持するコントローラーコードでは、次のように宣言する必要があります。

@property (weak, nonatomic) IBOutlet Schedule *scheduleView;

そして合成:

@synthesize scheduleView = _scheduleView;

そして、コントローラーのdealloc方法では:

self.scheduleView = nil;

このために.xibファイルを作成したために使用していないように見えるストーリーボードを使用している場合は、適切に接続する必要があります。単にインスタンス化して割り当てない場合。

前に言ったことを拡張すると、何をしようとしているのかわかりませんが、通知が呼び出されたときにビューを作成しているコードを見てみると、誰もいないために割り当てが解除されていますそれへの参照を保持します。私が言ったことを実行し、コントローラーからインターフェイスビルダーのビューにcontrol +クリックドラッグして接続すると、その参照が保持され、作成されるスケジュールオブジェクトは1つだけになります。

その後、Scheduleのこのインスタンスで機能するようにコードを変更する必要があります。

- (void) testNotification:(NSNotification *) notification  {

    //  was the calendar tapped?
    if ([[notification name] isEqualToString:@"calendarUpdated"])  {

        NSDictionary *passedData = notification.userInfo;  //  get passed data
        CFGregorianDate currentSelectDate;
        NSData *data = [passedData objectForKey:@"currentSelectDate"];
        [data getBytes:&currentSelectDate length:sizeof(CFGregorianDate)];

        [self.scheduleView calendarTouched:currentSelectDate];
    }

    return;

}

Interface Builderを使用してすべてを設定していない場合のその他のオプションは、次のとおりですviewDidLoad

- (void)viewDidLoad
{
    [super viewDidLoad];

    self.scheduleView = [[Schedule alloc] init];
    [self.view addSubView:self.scheduleView]; // Probably some extra code for positioning it where you want

    // notify me when calendar has been tapped and CFGregorianDate has been updated
    [[NSNotificationCenter defaultCenter] removeObserver:self];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(testNotification:) name:@"calendarUpdated" object:nil ];

}

最後に、iOS開発に慣れていないことを考えると(私たち全員がそうであったように)、iTunesにアクセスして、iTunes UでスタンフォードのiPadおよびiPhone開発コース(CS193P)を探すことができます。これは完全に無料で、ほとんどのことを教えてくれます。 iOSで開発するために知っておくべきこと。

于 2012-06-29T01:04:19.497 に答える