我有两种方法可以从-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。
UPDATE#2:我有一个带有两(2)个UIViews的UIViewController的.xib。第一个UIView占据了大约1/3的iPad屏幕,第二个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 请注意,两个pastebin都将在6月28日太平洋标准时间下午5点38分24小时后到期
答案 0 :(得分:2)
重复我在评论中所说的,你遇到的问题是你的UIView
子类对象在执行drawRect
调用之前被释放了,这意味着无论是什么持有对@property (weak, nonatomic) IBOutlet Schedule *scheduleView;
调用的引用对象,在这种情况下,你的控制器,在你的意思之前释放它,有时候会出现使用ARC的小问题。
在拥有此视图的控制器代码中,您应该声明这样的内容:
@synthesize scheduleView = _scheduleView;
并合成:
dealloc
在控制器的self.scheduleView = nil;
方法中:
- (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:¤tSelectDate length:sizeof(CFGregorianDate)];
[self.scheduleView calendarTouched:currentSelectDate];
}
return;
}
如果您正在使用故事板,因为您为此创建了.xib文件,而您似乎没有使用它,您应该正确连接它。如果不是简单地实例化并分配它。
扩展我之前所说的内容,我不确定你要做的是什么,但是看看你的代码,你会在通知被调用时短暂创建视图,然后它就会被解除分配没人提到它。通过执行我所说和控制的操作+单击从控制器拖动到界面构建器中的视图并将其挂起,它将保留对它的引用,并且您将只创建1个Schedule对象。
之后,您将不得不修改您的代码以使用此计划实例:
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 ];
}
中的以下内容:
{{1}}
作为最后一点,考虑到你是iOS开发的新手(就像我们一样)你可以去iTunes并在iTunes U上寻找斯坦福的iPad和iPhone开发课程(CS193P),它是完全免费的,它会教您在iOS中开发所需的大部分内容。