【问题标题】:Moving iOS app to using Storyboards while retaining some views programmatically移动 iOS 应用程序以使用 Storyboards,同时以编程方式保留一些视图
【发布时间】:2012-07-06 03:02:47
【问题描述】:

我正在尝试将我现有的项目转换为使用 Storyboards,以便我可以直观地布置我的视图。我仍然需要以编程方式将一些视图加载到其他视图中。

(附带说明 .. 我曾经在 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];
    }

那么在我尝试将日期添加到这些子视图之前,如何确保 gridView 中的 drawRect 已添加所有子视图?

【问题讨论】:

    标签: ios5 uiview xcode-storyboard


    【解决方案1】:

    布局阶段在渲染阶段之前完成。如果您在drawRect 中创建子视图,那么您已经做错了。对于您覆盖的 UIView 子类,所有“最后时刻”布局都应在 -layoutSubviews: 中完成。

    当添加到表格视图单元格时,您应该将子视图添加到 cell.contentView 而不是直接添加到 cell.view。请参阅Table View Programming Guide 段落仔细查看 Table-View Cells 了解表格视图单元格的解剖结构。

    此外,您不应依赖数组中子视图的顺序。相反,您应该标记您的子视图 (cellView.tag = d),因为从 nibstoryboard 加载时,子视图的顺序在视图层次结构中无法保证。您可以通过调用cell.contentView.viewWithTag:tag 来获取子视图。

    为什么不在- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 中设置日期,这是在表格视图单元格中设置 UI 元素值的最常见位置。

    【讨论】:

    • 我可能不应该使用“单元格”作为视图名称,因为我认为它会产生误导,因为它不在表格中。我试图为包含日历上每个日期的“正方形”起一个名字,结果我想出了“单元格”。
    • 啊,我明白了。但我强烈建议不要在 drawRect 中进行布局,并建议您使用标签来访问子视图,而不是依赖于视图层次结构中的特定顺序。 Apple 已多次强调这一点。
    • 我不确定视图布局是否应该进入 drawRect 所以感谢您引导我远离它。从视图中添加子视图的最佳位置在哪里? -layoutSubviews?
    • 我实际上最终将位移动以创建日历“正方形”上一级并将 [self addSubview:cellView] 更改为 [gridView addSubview:cellView] 这似乎有助于...时刻
    • 不用担心大量 cmets :) 是的,layoutSubviews 绝对是您在 UIView 子类中执行随时间变化的部分布局的地方。在 init 中创建子视图是常见的模式,但在 layoutSubviews 中设置框架。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多