肇鑫的技术博客

业精于勤,荒于嬉

NavigationSplitView的一些奇技淫巧

Sidebar按钮隐藏起来的正确做法

使用

.toolbar(removing: .sidebarToggle)

可以隐藏侧边栏切换按钮。但是注意,这个不是放在作用在NavigationSplitView上面的。而不是作用在sidebar的视图上面。即必须按照如下的方式使用:

NavigationSplitView(columnVisibility: $columnVisibility) {
    sidebar
        .toolbar(removing: .sidebarToggle)
    } content: {
    content
    } detail: {
    detail
}

隐藏Sidebar的正确做法

NavigationSplitView是三栏的,但是如果你要使用两栏,则有两种方式。

使用sidebar

使用sidebar的好处是,sidebar可以隐藏,也可以显示。
使用sidebar+detail的方式。

不使用sidebar

如果你希望永远显示为两栏,不希望隐藏任何一个栏隐藏,那么使用此方式。

NavigationSplitView(columnVisibility: .constant(.doubleColumn)) {
    EmptyView()
        .toolbar(removing: .sidebarToggle)
    } content: {
    content
    } detail: {
    detail
}

这个的重点在于,通过sidebar设置隐藏了切换sidebar按钮。同时,选择两栏模式,默认不显示sidebar。这样sidebar就无法被调用出来了。并且一直是两栏。

配合Settings使用

在使用Settings时候,包含sidebar的NavigationSplitView的sidebar按钮会导致出现问题。因此,必须使用上面的第二种方式,隐藏sidebar,并且使用一直存在的两栏。

解决Xcode Cloud无法enable Swift Package包中的宏的问题

最近我在做应用适配iOS/macOS 26的特性。今天在Xcode Cloud打包的时候遇到打包失败的错误。

Macro “DefaultsMacrosDeclarations” from package “Defaults” must be enabled before it can be used.

这个问题是我应用所使用的第三方的库 “Defaults”在其内部使用了宏。这个宏在Xcode本地编译时,需要用户手动点击确认才能继续。但是Xcode Cloud中,没有点击确认的位置。因此,就无法完成打包应用的过程。

解决办法

通过运行脚本的方式,在克隆完文件夹之后,运行脚本,规避掉对于宏的验证。

#!/bin/sh 
defaults write com.apple.dt.Xcode IDESkipMacroFingerprintValidation -bool YES

必须在Xcode中的根部位置,创建一个新组,命名为ci_scripts,然后在这个组中创建ci_post_clone.sh,内容是上面的内容。

必须在Xcode的根部位置创建组,并且命名也不能错。

小插曲

我其实最开始是像GPT 4.1提出了这个问题。GPT 4.1的解答只对了一半。它提出了创建文件夹和脚本,文件夹是正确的,脚本名字是错误的。并且它也没有告诉需要在Xcode中创建组,而只是说在项目的根目录创建就可以。最后,它创建的脚本内容不完全正确。

之后我使用了Google搜索。Google搜索默认的AI总结的是正确的,但应该就是从stackoverflow里的答案总结的。我最后是看的SO里的回答,进行的总结。

另外,我建议你完整阅读下面的第一个引用。我使用了里面最为简便的方案。而非最安全的。也许你看了之后,会选择一条不同的手段。

引用文献

How do I trust a swift macro target for Xcode Cloud builds?

Writing custom build scripts

什么?AccentColor又闹幺蛾子了?

一年以前,我就踩过一次AccentColor的坑。没想到,一年之后我又掉进来了。

SwiftUI下,TextField诡异失去Focus下样式的问题

事情的起因是这样的。因为苹果的新系统发布了嘛。我不能免俗的也要改进我之前的应用,添加对于新系统特性的一些支持之类的。

但是我在修改代码后测试时发现,当使用ZStack模拟弹窗之后,弹窗后面的视图的颜色会出错。我一开始以为是ZStack的问题,于是将模拟弹窗改成了.fullScreenCover的方式。这个问题在当时看起来时解决了。但是今天我在使用中发现,这个问题又重新出现了。

于是我在Google上搜索了一下,没想到这还是一个SwiftUI长期存在的一个问题。

How do I stop the AccentColor from turning Gray when a sheet is being presented?

原来在SwiftUI中实际使用时。原本应该一致的Color.accentColor和Color("AccentColor")在实际使用中是不一致的。说得更具体些,就是Color.accentColor会使用应用设置和用户的系统设置。而Color("AccentColor")则是将AccentColor作为颜色资源从Asset文件夹直接读取。因此,虽然它的名字也叫"AccentColor",但是实际上它只是名字叫"AccentColor"的一个颜色,你改成别的名字,比如"MyAppColor"也是一样的。虽然这样会失去Color.accentColor一些独特的个性,但是能保证颜色的一致,即颜色不会莫名其妙的改变。

系统弹sheet的时候,Color.accentColor会改变的问题,应该就是sheet本身可能存在某种机制,将应用内设置的Color.accentColor从Asset文件夹设置的内容,改成了系统默认设置的内容。比如下图红色圈起来的部分,就是系统允许用户自定义用户AccentColor偏好的地方。

accent_color