1

我有两种从内部调用的方法-drawRect:

- (void)drawRect:(CGRect)rect  {

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

-drawGrid在初始化时调用。另一个方法 ( -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被调用?

更新:我已经休息了,所以我很肯定它没有被调用。原网格绘制一次;当用户点击日历日期时,会调用 -calendarTouched 并完全执行。drawScheduleFlag 设置为 true,并且 -[self setNeedsDisplay] 被调用,但 -drawRect 没有。似乎 UIView 没有失效(应该是 -setNeedsDisplay ),因此 -drawRect 没有被调用。

更新#2:我有一个用于 UIViewController 的 .xib,其中包含两 (2) 个 UIView。第一个 UIView 占据了 iPad 屏幕的 1/3,第二个 UIView 占据了屏幕底部的 2/3。每个 UIView 都有自己的特定类;顶部 UIView 显示日历并且工作正常,捕捉触摸并更改所选日期。

底部的 UIView 应该显示在顶部 UIView 中选择的日期的时间表。这就是问题所在。由于顶部 UIView 正在工作,我将放置底部 UIView 类的代码。它基本上在第一次调用 -drawRect 时绘制计划网格。一旦用户选择了一天,它应该使 UIView 无效以在网格上绘制实际的时间表。

这是 Schedule.h 的代码:http: //pastebin.com/NQpj0i07这是 Schedule.m 的代码:http: //pastebin.com/YBbE8y0T 这是控制器的代码: http://pastebin。 com/nDqBCivj 请注意,从太平洋标准时间 6 月 28 日下午 5:38 起,两个 pastebin 都将在 24 小时内到期

4

1 回答 1

2

重复我在评论中所说的话,您遇到的问题是您的UIView子类对象在drawRect调用执行之前被释放,这意味着持有对该对象的引用的任何东西,在这种情况下是您的控制器,在您之前释放它意思是,使用 ARC 有时会出现小问题。

在包含此视图的控制器代码中,您应该声明如下内容:

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

并合成:

@synthesize scheduleView = _scheduleView;

在控制器的dealloc方法中:

self.scheduleView = nil;

如果您使用的是故事板,而您似乎没有使用它,因为您为此制作了一个 .xib 文件,您应该正确连接它。如果不是简单地实例化它并分配它。

扩展我之前所说的内容,我不确定您要做什么,但看看您的代码,您正在创建视图,当通知被调用时,它会被释放,因为没有人是持有对它的引用。通过执行我所说的操作并单击从控制器拖动到界面构建器中的视图并将其连接起来,它将保留对它的引用,并且您只会创建 1 个 Schedule 对象。

之后,您必须修改代码以使用此 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;

}

如果您不使用界面生成器来设置所有内容,那么您拥有的另一个选项是您的以下内容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 回答