UISplitViewController - 用侧边栏切换图标替换后 V 形图标
Posted
技术标签:
【中文标题】UISplitViewController - 用侧边栏切换图标替换后 V 形图标【英文标题】:UISplitViewController - replace back-chevron icon with a sidebar toggle icon in portrait 【发布时间】:2022-01-12 19:38:51 【问题描述】:我正在开发一个使用 UISplitViewController
的 iPadOS 应用程序。到目前为止,我一直在使用旧 API 并手动处理所有内容(包括 displayModeButtonItem
)。现在我想迁移到更新的“列样式”API (super.init(style: .doubleColumn
)。我遇到了一些 UI 问题,但我设法通过一些变通方法解决了这些问题,但现在我在一个找不到任何解决方案的问题上被阻止:
我想利用ios14的UISplitViewController
的所有内置机制,所以我将presentsWithGesture
属性设置为true
。因此,我得到横向的侧边栏切换图标(这正是我想要的方式),但在纵向我得到一个带有“back”标题的“back-chevron icon”。有没有办法强制向两个方向显示侧边栏切换图标?
【问题讨论】:
大约 16 个月前(iPadOS 14 处于测试阶段)我尝试了类似的方法。似乎(至少)使用主要 和 辅助 VC 的 iPad 上的默认行为是在从横向旋转到纵向时“隐藏”或关闭 PrimaryVC。我的first 解决方法是标记事物并强制Primary 无论如何都保持可见。这让事情变得太复杂而无法维护,所以我朝着一个非常不同的方向前进——只有一个辅助(和紧凑)VC 并推出我自己的主。在您的情况下,这至少会在所有方向上为您提供相同的导航栏。我知道不是最佳的。 @dfd 实际上,我希望侧边栏以纵向关闭并在此方向上作为叠加层(而不是另一列)。我唯一的问题是纵向按钮的外观。在我的应用程序上下文中,对于应用程序用户来说,“back chevron”不太清楚。这可能对其他应用有意义,但对我的应用没有意义,所以我想在两个方向上都显示侧边栏按钮。 那么你可能需要做两件事。 (1) 确定 iPad 上的方向何时改变。不要忘记,当您的应用程序处于全屏状态时,它会始终显示常规尺寸类别,而当它处于分屏 - 多任务时 - 它可能使用紧凑型尺寸等级取决于屏幕尺寸、方向和您的应用使用的区域大小。 (2) 确定正在显示哪个导航栏 - 如果有的话,因为在显示 Compact VC 时 UISplitViewController 默认不提供。 IIRC,在显示主 VC 时,会显示两个导航栏。根据需要提供您自己的导航栏按钮。 @dfd 任何想法我应该如何提供导航栏按钮?我尝试这样设置:'self.viewController(for:secondary)?.navigationItem.leftBarButtonItem = UIBarButtonItem(...',但这根本没有效果。标准的后退按钮是可见的,但我的自定义按钮不是。 【参考方案1】:我设置了一个示例项目,但我没有得到你的行为。我想这是因为我们在设置 UISplitViewController
时做的事情不同。
首先,非常感谢 Matt Neuburg(@matt 在 SO 上)的两部分文章。 (part one here) 这为我的代码提供了一些重大更改。
基本上,我不再将UISplitViewController
设置为场景中的根视图。相反,我根本不碰SceneDelegate
,而是使用默认的ViewController
:
let primaryVC = PrimaryVC()
let secondaryVC = SecondaryVC()
let compactVC = CompactVC()
override func viewDidLoad()
super.viewDidLoad()
let split = UISplitViewController(style: .doubleColumn)
self.addChild(split)
self.view.addSubview(split.view)
split.view.frame = self.view.bounds
split.presentsWithGesture = true
split.preferredSplitBehavior = .tile
split.view.autoresizingMask = [.flexibleHeight, .flexibleWidth]
split.didMove(toParent: self)
split.setViewController(primaryVC, for: .primary)
split.setViewController(secondaryVC, for: .secondary)
split.setViewController(compactVC, for: .compact)
当我这样做时,我得到一个“sidebar.left”按钮,而 Chevron 没有“返回”按钮。我正在使用 Xcode 13.1,并在 iPadOS 14.0 和 15.1 的目标上进行了尝试。
如果您需要添加/替换条形按钮,我要做的是:
var barBtnSidebarLeft = UIBarButtonItem(image: UIImage(systemName:"sidebar.left"), style: .plain, target: self, action: #selector(leftSidebarTapped)) navigationItem.leftBarButtonItem = barBtnSidebarLeft
但请注意,如果您这样做,您将获得 两个 侧边栏按钮!关于栏按钮,还有一点需要注意 - 虽然UISplitViewController
默认为 Primary 和 Secondary 提供导航栏,但它不为 Compact。 (坦率地说,我不认为在紧凑的情况下拥有一个好习惯。)
最后,阅读我提供的链接。它真正开始使用UISplitViewControllerDelegate
来帮助您正确传递场景状态值。 (我更喜欢称它为场景状态而不是应用状态,因为 iPad 可以有多个应用窗口。)
编辑
最后一个想法。 IIRC 你可以这样做:
将presentsWithGesture
设置为`false
在两个视图控制器中随意放置您自己的条形按钮
手动(通过委托函数?)打开和关闭主视图控制器
【讨论】:
以上是关于UISplitViewController - 用侧边栏切换图标替换后 V 形图标的主要内容,如果未能解决你的问题,请参考以下文章
UISplitViewController - 双列样式不起作用
UISplitViewController - 并排或纵向叠加