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

发布于 2024-09-10 15:08:34 字数 873 浏览 8 评论 0原文

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

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

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

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

[self.tableView flashScrollIndicators];

我试图把它几乎放在任何地方。首先在 -viewDidLoad 中(按照文档中的建议),然后在 viewDidAppear 和 -viewWillAppear 中。 还尝试使用该代码 tring 将 tvc 的视图转换为表视图。

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

..没有结果。

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

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

I've got a weird problem with a TableViewController.
In the doc it says that a tableViewController deals also with the method
-flashScrollIndicators when the table is "oversized" respect the visible area.

My app consists in 3 nav controller loaded in a tab controller. Each nav controller has as root view controller a subclass of a table view controller.
Each "model" is populated from a plist file, that loads its contents into an array in the -viewDIdLoad, later everything is passed to the table. Everything is loaded programmatically no IB.

I've found out in my app that when it loads the first view (a nav controller with a table view controller as root) the scroll bar isn't flashing even if the number of cell it's great enough.
If I choose another tab, that loads another nav controller (with a t.v.c. as root) scroll bar isn't shown again. When I press the tab corresponding to the first nav controller loaded the scrollbar flashes.

So I've tried to make it flash programmatically but no way, the code seems simple:

[self.tableView flashScrollIndicators];

I've tried to put it almost everywhere. First in the -viewDidLoad (As suggested in the doc), then in viewDidAppear and in -viewWillAppear.
Also tried use that code tring to cast the view of the t.v.c. as a table view.

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

..without result.

I've started looking at Apple sample and I've found that in Apple's table view custom sample (the one with different times) scroll bar doesn't flash also there.
Tested both on sim and device.

Is a bug?, is there a correct way to show it programmatically?
Can someone help me?
Regards,
Andrea

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

何处潇湘 2024-09-17 15:08:34

或者更简洁地说:

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

Or more concisely:

- (void)viewDidAppear:(BOOL)animated {
  [super viewDidAppear:animated];
  [self.tableView performSelector:@selector(flashScrollIndicators) withObject:nil afterDelay:0];
}
栖迟 2024-09-17 15:08:34

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

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

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

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

I had exactly the same problem. I got around it in the end by putting a delayed selector in the viewDidAppear: method. Weirdly, I can set it to 0 seconds and it still works fine.

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

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

- (void)flashTableScrollIndicators
{
    [self.tableView flashScrollIndicators];
}
蝶舞 2024-09-17 15:08:34

当您显示章节索引标题时,不会显示它。

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

It is not displayed when you show section index titles.

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView; 
水溶 2024-09-17 15:08:34

我的解决方案是使用“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() 
})

My solution was to send the "flashScrollIndicators()" message with a slight delay using "dispatch_after":

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() 
})
仅冇旳回忆 2024-09-17 15:08:34

可能的原因是,当您调用.flashScrollIndicators()时,UITableView尚未布置其子视图,因此不会发生闪烁,没有内容可以滚动。这是正确且预期的行为。

只需在调用 .flashScrollIndicators() 之前在 UITableView 上调用 .layoutIfNeeded() 即可。

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 的生命周期函数、viewDidAppear中调用 .reloadData().flashScrollIndicators() 时尤其如此。 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() 时立即布局子视图,这是一件好事,因为它为开发人员提供了更多默认控制。掌握何时希望布局引擎立即对某些视图及其子视图执行更新是关键。

快乐开发!

The likely cause is that the UITableView has not yet laid out its subviews when you are calling .flashScrollIndicators(), so no flashing occurs, there is no content to scroll. This is correct and expected behaviour.

Simply call .layoutIfNeeded() on the UITableView before you call .flashScrollIndicators().

TLDR Solution:

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()
}

Tips:

Remember, initially the TableViewController is empty so there is no content in the TableView's ScrollView, i.e. no flashing of Scroll Indicators.

This is especially true when you are calling .reloadData() or .flashScrollIndicators() from within a ViewController's lifecycle functions, viewDidAppear or viewWillAppear. When those functions are performed, the ViewController has completed laying out an initially empty TableView, i.e. no content, no flashing scroll indicators.

Even if you have content in your TableView's DataSource when you call .reloadData() followed by .flashScrollIndicators(), the scope you call that in does not wait for subviews to layout (nor should it).

for example:

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 does not assume you always want to layout subviews immediately when you call .reloadData(), which is a good thing, as it provides more default control to the developer for one. Mastering when you want the layout engine to perform updates on certain Views and it's subviews immediately is key.

Happy developing!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文