Перемещение приложения iOS на использование Storybaords с программным сохранением некоторых представлений
Я пытаюсь преобразовать свой существующий проект в использование раскадровок, чтобы я мог визуально изложить свои взгляды. Мне все еще нужно загрузить некоторые виды программно в другие представления.
(в качестве примечания. Я привык программировать на Flash ActionScript, и я довольно новичок в программировании на iOS и взял только учебник для Objective-C, поэтому у меня есть некоторые огромные "дыры", через которые я пытаюсь пройти),
Мой макет примерно такой:
Календарь имеет подпредставление для создания своих ячеек - 'gridView'. Первоначально у меня было это представление, созданное программно, которое, в свою очередь, добавило свои собственные подпредставления для ячеек календаря (квадраты, которые показывают дату). Я успешно добавил gridView в раскадровку, и он отображает ячейки календаря (которые программно добавляются gridView). Я успешно смог отобразить правильные даты в календаре, которые я сейчас разбил, используя раскадровки, и пытаюсь решить, нужно ли мне вернуться к созданию gridView программно или действительно я могу делать то, что хочу в Раскадровка.
Так вот, где я застрял:
В моем gridView я использую Draw Rect для создания всех подпредставлений ячеек:
// lay down the individual cells to build the calendar
// 7 days across x 6 weeks down
const CGSize gCellSize = {self.frame.size.width/7, (self.frame.size.height-20)/6};
for(int w=0;w<6;w++) //6 weeks in the calendar
{
for(int d=0;d<7;d++) //7 days in a week
{
// ------------------ setting up the CELLVIEW ----------------------//
CGRect calendarCellRect=CGRectMake(d*gCellSize.width,w*gCellSize.height+20, gCellSize.width, gCellSize.height);
CalendarCellView *cellView=[[CalendarCellView alloc] initWithFrame:calendarCellRect];
[self addSubview:cellView];
}
}
так вот в чем моя проблема: когда я создал все программно, gridView был загружен как подпредставление к родительскому представлению, а cellViews были размечены просто отлично. После загрузки gridView родительское представление продолжит работу с методом (displayDates - внутри gridView), который перебирает эти подпредставления и добавляет соответствующую дату в каждый cellView.
но теперь, когда я добавил gridView в раскадровку, мне нужно убедиться, что его подвиды ячеек загружены, прежде чем я смогу вызвать метод displayDates.
-(void)displayDates:(NSArray *)selectedMonthDates previousMonthVisibleDates:(NSArray *)previousMonthDates followingMonthVisibleDates:(NSArray *)followingMonthVisibleDates
{
int cellNum=0;
NSArray *displayDates[]={previousMonthDates,selectedMonthDates,followingMonthVisibleDates};
for (int i=0; i<3; i++)
{
for (NSDate *d in displayDates[i])
{
CalendarCellView *cell=[self.subviews objectAtIndex:cellNum];
[cell resetState]; //initialize all properties within the CellView
cell.date=d; // set the cell's date property to be equal to the respective date collected from the displayDate array
cellNum++;
}
}
[self setNeedsDisplay];
}
Итак, как мне убедиться, что drawRect в gridView добавил все подпредставления, прежде чем я приду и попытаюсь добавить даты в эти подпредставления?
1 ответ
Фаза макета выполняется до фазы рендеринга. Если вы создаете подпредставления в drawRect
Вы уже делаете это неправильно. Все макеты "в последний момент" должны быть сделаны в -layoutSubviews:
для UIView
подкласс, который вы переопределяете.
При добавлении в ячейку табличного представления вы должны добавить свои подпредставления в cell.contentView
не для cell.view
непосредственно. См. Параграф A Руководства по программированию табличного представления. Более детальный взгляд на ячейки табличного представления для анатомии ячейки табличного представления.
Кроме того, вы не должны полагаться на порядок подпредставлений в массиве. Вместо этого вы должны пометить свои подпредставления (cellView.tag = d
), поскольку порядок подпредставлений не гарантируется в иерархии представлений при загрузке из пера или раскадровки. Вы можете получить подвид, позвонив cell.contentView.viewWithTag:tag
,
И почему бы не установить даты в - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
который является наиболее распространенным местом для установки значений элементов пользовательского интерфейса в ячейке табличного представления.