Objective c -setNeedsDisplay未被调用以刷新drawRect

Objective c -setNeedsDisplay未被调用以刷新drawRect,objective-c,ios,uiview,uikit,Objective C,Ios,Uiview,Uikit,我有两个方法可以从-drawRect: - (void)drawRect:(CGRect)rect { if(drawScheduleFlag) { [self drawSchedule]; drawScheduleFlag = false; } else [self drawGrid]; } -drawGrid在初始化时被调用。另一个方法(-drawSchedule)是从主线程上的代码调用的: - (void) ca

我有两个方法可以从
-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的类提供代码。它基本上是在第一次调用-drawRect时绘制日程网格。一旦用户选择了一天,就应该使UIView无效,以便在网格上绘制实际的日程安排

以下是附表h的代码: 以下是附表m的代码: 以下是控制器的代码:
请注意,这两个pastebin都将在24小时内从6月28日太平洋标准时间下午5:38过期。重复我在评论中所说的,您遇到的问题是,在执行
drawRect
调用之前,您的
UIView
子类对象被释放,这意味着持有该对象引用的任何对象,在这种情况下,您的控制器在您打算释放它之前就释放了它,这是使用ARC有时会出现的一个小问题

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

@property (weak, nonatomic) IBOutlet Schedule *scheduleView;
并合成:

@synthesize scheduleView = _scheduleView;
在控制器的
dealloc
方法中:

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

在我之前所说的基础上,我不确定您想做什么,但是看看您的代码,您正在创建视图,当通知被调用时,它正在被释放,因为没有人持有对它的引用。按照我所说的操作,control+单击,从控制器拖动到interface builder中的视图,并将其连接起来,它将保留对它的引用,并且您将只创建一个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;

}
如果未使用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中开发所需的大部分知识。

您确保没有调用它吗?你确定只打过一次电话吗?设置断点。可能会调用它,但之后会直接再次调用,然后转到
drawGrid
,这可能会再次删除计划。短语“-drawGrid在初始化时被调用”听起来令人生疑…我认为您需要提供更多的代码和上下文。另外,此时您的视图是否处于视图层次结构中?在主线程上调用
-setNeedsDisplay:
的代码是否存在?如果不是,那就是你的问题。嗨,理查德。。。是的,它在主线程上(使用-NSLog(@“main thread?%d”,[NSThread isMainThread]),返回1)没有声明任何内容。。。这可能就是问题所在,是吗?这是控制器的代码:这是CalendarView.h的代码,它是上层UIView的类。我看它有你所指的东西;我需要做一些类似的事情来安排吗?是的,很有可能,你没有任何关于你的观点的参考,所以它只是失去了记忆,按照我在回答中所说的方式来声明,并让我知道它是如何进行的。记住在Interface Builder中连接它,或者在控制器中实例化它,并在上面的“我的帖子”中引用CalendarView.h指定它。我明天做这个,因为该吃晚饭了。谢谢你抽出时间。太平洋时间早上7点后找我的帖子。。。再次感谢…没问题,希望它真的是这样,它解决了你的问题:)看到了你实例化Schedule视图的那一行,它开始存在,然后在那里被取消引用,像我说的那样拿着一个指向它的指针,或者当你实例化你的控制器时创建的,拿着一个对它的引用,然后调用它的方法,因为对于每个通知,您都在创建一个新的计划对象。我讨厌要求太多。。。但是你能给我指一个文档,里面解释了如何创建指针并保持它吗?(我对objective-c这门课程比较陌生,有点困惑)。