【发布时间】:2015-01-24 00:36:59
【问题描述】:
我的 iOS 应用正在使用大约 18 页的 UIPageViewcontroller。每个页面都有一个 UITableView 和 4 个动态单元格。每个单元格有大约 10 张不同的图像。
问题是每次我滑动 UIPageViewcontroller 以转到下一个/上一个页面时,都会有半秒的延迟,这让用户体验非常糟糕。
似乎在滑动后要显示的下一页的 UITableView 正在加载其所有重数据单元格,这导致了此延迟。
我已阅读可以使此加载异步,但我不知道如何执行此操作。
你们中有人知道如何避免这种延迟,以便顺利过渡到页面吗?
这是 UITableView 的一些代码:
#pragma mark - Table view data source
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// Return the number of rows in the section.
return 4;
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
if ([cellsStatus[indexPath.row] integerValue] == CLOSED_CELL)
return [GrintScoreTrackPlayerDynamicCell getHeightForCell];
else
return [GrintScoreTrackPlayerDynamicCell getFullHeightForCell];
}
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
if ([mainController respondsToSelector:@selector(tableViewDidScroll:)] &&
[mainController isKindOfClass:[GrintScoreTrackViewController class]])
{
[mainController tableViewDidScroll:scrollView];
}
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier;
GrintScoreTrackPlayerDynamicCell *cell, *cellOwner;
// Cell ID
CellIdentifier = @"GrintScoreTrackPlayerDynamicCell-ID";
// Creating the cell
cell = (GrintScoreTrackPlayerDynamicCell*)[self.tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Creating the cell owner
cellOwner = [[GrintScoreTrackPlayerDynamicCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
// Getting cell from Nib, if possible.
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"GrintScoreTrackPlayerDynamicCell" owner:cellOwner options:nil];
cell = [nib objectAtIndex:0];
}
// Filling cell with the corresponding user info
[cell fillCellWithContent];
// Changing appearance based on the new status
[self setStatusOfCell:cell withStatus:[cellsStatus[indexPath.row] integerValue]];
// Setting action for cell's "collapseButton" button
[cell.collapseButton addTarget:self action:@selector(changeCellStatus:) forControlEvents:UIControlEventTouchUpInside];
// Setting action for cell's "editScoresButton" button
[cell.editScoresButton addTarget:self action:@selector(editScoresButtonWasPressed:) forControlEvents:UIControlEventTouchUpInside];
// Setting action for cell's "pickerEnterButton" button
[cell.pickerEnterButton addTarget:self action:@selector(pickerEnterButtonWasPressed:) forControlEvents:UIControlEventTouchUpInside];
// Setting cell selection style
cell.selectionStyle = UITableViewCellSelectionStyleNone;
cell.layoutMargins = UIEdgeInsetsZero;
// Setting picker view delegate and data source.
[cell.pickerView setDelegate:self];
[cell.pickerView setDataSource:self];
return cell;
}
还有一些来自 GrintScoreTrackPlayerDynamicCell 单元格的代码:
- (void) fillCellWithContent
{
// Doing some processing fixes
[self postProcessCellContent];
}
- (void) postProcessCellContent
{
CGSize textSize;
CGFloat scoreLabelTextWidth, newHazzardLabelXValue, newPuttsLabelXValue, offset;
// Setting an offset for the hazzard and putts label. This offset represents the distance between the score label text and the hazzard and putts labels.
offset = 1;
// Getting the width of the text that's inside the Score Label.
textSize = [[self.scoreLabel text] sizeWithAttributes:@{NSFontAttributeName:[self.scoreLabel font]}];
scoreLabelTextWidth = textSize.width;
// Getting new x position value for the Hazzards Label.
newHazzardLabelXValue = self.scoreLabel.frame.origin.x +
(self.scoreLabel.frame.size.width - scoreLabelTextWidth) * 0.5 -
self.hazardsLabel.frame.size.width - offset;
// Setting the new x position value for the Hazzards label
[GrintUtils moveView:self.hazardsLabel inX:newHazzardLabelXValue andY:self.hazardsLabel.frame.origin.y];
// Getting new x position value for the Putts Label.
newPuttsLabelXValue = self.scoreLabel.frame.origin.x +
(self.scoreLabel.frame.size.width - scoreLabelTextWidth) * 0.5 +
scoreLabelTextWidth + offset;
// Setting the new x position value for the Putts label
[GrintUtils moveView:self.puttsLabel inX:newPuttsLabelXValue andY:self.puttsLabel.frame.origin.y];
}
这是一些关于我的 UIPageViewController 的代码,其中页面预加载在 pageContent 数组中:
#pragma mark - UIPageViewController Data Course
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerBeforeViewController:(UIViewController *)viewController
{
// Getting the previous of the next controller
int index;
index = currentPageBeingDisplayed - 1;
if (index < 0)
index = [pageContent count] - 1;
return pageContent[index];
}
- (UIViewController *)pageViewController:(UIPageViewController *)pageViewController viewControllerAfterViewController:(UIViewController *)viewController
{
// Getting the index of the next controller
int index;
index = currentPageBeingDisplayed + 1;
index = index % [pageContent count];
return pageContent[index];
}
Instruments Tool Counter 的屏幕截图专注于延迟:
单元格的最后 2 张图片(它有 2 个状态):
【问题讨论】:
-
您需要展示您的
fillCellWithContent方法。您应该做的另一件事是在pageViewController中预加载“下一个”视图控制器 - 这样它可能会在显示之前加载所有数据。同样在cellForRowAtIndexPath中获取数据并不理想——您应该预先获取viewDidLoad或类似中的数据 -
使用仪器!它会准确地告诉你“延迟”用在了哪里。
-
嗨@Paulw11,我刚刚编辑了代码以添加fillCellWithContent 方法...另一方面,我已经将UIPageViewController 的所有页面预加载到数组中。所以我只创建一次。我也刚刚添加了一些关于它的代码......我还没有从服务器获取任何数据。一切都是本地的。
-
@jmukel 你在开玩笑吗?你在没有任何帮助的情况下做得很好!出色的侦探工作。做得好。 - 那么,为了清楚起见,这些图像是如何进入细胞的?我没有看到任何这样做的代码;你是说它发生是因为图像在单元格定义的 .xib 中?
-
@jmoukel 这已经足够我提出建议的信息了 - 请参阅下面的答案。可能行不通,但我认为会的! :)
标签: ios objective-c xcode uitableview uipageviewcontroller