在自定义控件中,如何实现如UISegmentedControl,UITabBar,UITableView或UICollectionView所示的粘性焦点选择? “粘性选择”是指在聚焦到容器中时自动将焦点转移到最后聚焦/选择的项目。
UISegmentedControl和其他人如何自己实现此功能?我尝试检查UISegmentedControl,但令我惊讶的是,它是一个大型可聚焦元素,而不是一组可聚焦段。考虑到它的体系结构,我无法找出UISegmentedControl如何在各段之间切换焦点。
到目前为止,我的解决方法是:
在屏幕级别,保持每个即时贴选项。例如,如果屏幕上有两个自定义的顶部菜单,则屏幕上会保留两个活动选择。覆盖shouldUpdateFocus以检测焦点更改到具有粘滞选择的容器/菜单中。返回false +调用setNeedsFocusUpdate并与重写preferredFocusEnvironments组合以将焦点重定向到粘性/选定的子视图。
我的解决方案有效,但是对于编写可重复使用的自定义UI并自动保持粘性选择不满意。 Apple能够制作多个这样的自定义UI,因此肯定缺少某些方法。
我发现了一种适用于可重用控件的方法:
围绕UIFocusGuide中的控件。然后,只需使用UIFocusGuide.preferredEnvironments确定当焦点移到容器时哪个子视图将获得焦点。
有个警告,如果容器的子视图填充了容器,则将命中子视图,而不是容器周围的焦点指南。总的来说,我有:
self.focusGuide = UIFocusGuide()
let focusGuideExpansion: CGFloat = 1
self.addLayoutGuide(focusGuide)
focusGuide.leadingAnchor.constraint(equalTo:self.leadingAnchor, constant:-focusGuideExpansion).isActive = true
focusGuide.trailingAnchor.constraint(equalTo:self.trailingAnchor, constant:focusGuideExpansion).isActive = true
focusGuide.topAnchor.constraint(equalTo:self.topAnchor, constant:-focusGuideExpansion).isActive = true
focusGuide.bottomAnchor.constraint(equalTo:self.bottomAnchor, constant:focusGuideExpansion).isActive = true
// default to focusing on the first subview
focusGuide.preferredFocusEnvironments = [subviews.first!]