即使表格比视图大,TableViewController 也不会闪烁滚动指示器

问题描述 投票:0回答:5

我在 TableViewController 上遇到了一个奇怪的问题。 在文档中它说 tableViewController 还处理该方法 -flashScrollIndicators 当表格“超大”时尊重可见区域。

我的应用程序由加载在选项卡控制器中的 3 个导航控制器组成。每个导航控制器都有一个表视图控制器的子类作为根视图控制器。 每个“模型”都是从 plist 文件填充的,该文件将其内容加载到 -viewDIdLoad 中的数组中,然后将所有内容传递到表中。所有内容均以编程方式加载,无需 IB。

我在我的应用程序中发现,当它加载第一个视图(一个以表视图控制器为根的导航控制器)时,即使单元格数量足够大,滚动条也不会闪烁。 如果我选择另一个选项卡,则加载另一个导航控制器(以 t.v.c. 作为根)滚动条不会再次显示。当我按下与加载的第一个导航控制器相对应的选项卡时,滚动条会闪烁。

所以我尝试以编程方式使其闪烁,但没办法,代码看起来很简单:

[self.tableView flashScrollIndicators];

我试着把它几乎放在任何地方。首先在 -viewDidLoad 中(按照文档中的建议),然后在 viewDidAppear 和 -viewWillAppear 中。 还尝试使用该代码 tring 来投射 t.v.c 的视图。作为表格视图。

[((UITableView*)self.view) flashScrollIndicators];

..没有结果。

我已经开始查看Apple示例,我发现在Apple的表格视图自定义示例(具有不同时间的示例)中,滚动条也不在那里闪烁。 在 SIM 和设备上进行了测试。

是一个错误吗?是否有正确的方法以编程方式显示它? 有人能帮我吗? 问候, 安德里亚

iphone sdk scrollbar tableview indicator
5个回答
41
投票

或更简洁地说:

- (void)viewDidAppear:(BOOL)animated {
  [super viewDidAppear:animated];
  [self.tableView performSelector:@selector(flashScrollIndicators) withObject:nil afterDelay:0];
}

12
投票

我也遇到了完全相同的问题。我最终通过在

viewDidAppear:
方法中放置一个延迟选择器来解决这个问题。奇怪的是,我可以将其设置为 0 秒,但它仍然工作正常。

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    [self performSelector:@selector(flashTableScrollIndicators) withObject:nil afterDelay:0.0];
}

- (void)flashTableScrollIndicators
{
    [self.tableView flashScrollIndicators];
}

3
投票

显示章节索引标题时不会显示。

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView; 

0
投票

我的解决方案是使用“dispatch_after”稍微延迟地发送“flashScrollIndicators()”消息:

let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(0.4 * Double(NSEC_PER_SEC)))

dispatch_after(delayTime, dispatch_get_main_queue(), 
{ () -> Void in 
    myScrollView.flashScrollIndicators() 
})

0
投票

可能的原因是,当你调用

UITableView
时,
.flashScrollIndicators()
还没有布局它的子视图,所以没有发生闪烁,没有内容可以滚动。这是正确且预期的行为。

只需在拨打

.layoutIfNeeded()
之前先拨打
UITableView
上的
.flashScrollIndicators()

TLDR 解决方案:

func reloadMyTableViewFlashingIndicators() {
    // assuming you have set your DataSource to load into the TableView
    // e.g. yourTableViewDataSource = tableData

    // Reload the rows and sections of the table view.
    yourTableViewController.reloadData()

    // now, lay out the subviews immediately, if layout updates are pending.
    // which they are due to calling .reloadData()
    // this instructs - Do not wait for the next layout update cycle.
    yourTableViewController.layoutIfNeeded()

    // Now it is known how much content the TableView's ScrollView has and will
    // flash the indicators when there is content to scroll.
    yourTableViewController.flashScrollIndicators()
}

温馨提示:

记住,最初TableViewController是空的,所以TableView的ScrollView中没有内容,即滚动指示器没有闪烁。

当您从 ViewController 的生命周期函数

.reloadData()
.flashScrollIndicators()
中调用
viewDidAppear
viewWillAppear
时尤其如此。当执行这些功能时,ViewController 已完成布局最初为空的 TableView,即没有内容,没有闪烁的滚动指示器。

即使当您依次调用

.reloadData()
.flashScrollIndicators()
时 TableView 的数据源中有内容,您调用的范围也不会等待子视图布局(也不应该)。

例如:

func willNotFlashIndicators() {
    // assuming you have set your DataSource to load into the TableView
    // e.g. yourTableViewDataSource = tableData

    // Reload the rows and sections of the table view.
    yourTableViewController.reloadData()

    // iOS has not yet laid out the TableView's content.
    // layout updates are queued and will occur during the next layout engine update.
    // At this point the TableView's ScrollView's content layout is still empty,
    // i.e. no flashing of Scroll Indicators.
    // This is correct and expected behaviour.
    yourTableViewController.flashScrollIndicators()
}

Swift 并不假设您总是希望在调用

.reloadData()
时立即布局子视图,这是一件好事,因为它为开发人员提供了更多默认控制。掌握何时希望布局引擎立即对某些视图及其子视图执行更新是关键。

祝您开发愉快!

© www.soinside.com 2019 - 2024. All rights reserved.