Skip to content

Commit

Permalink
sidebar 样式和小组件内容更新
Browse files Browse the repository at this point in the history
  • Loading branch information
ming1016 committed May 11, 2024
1 parent 228bb1d commit d657cfc
Show file tree
Hide file tree
Showing 25 changed files with 879 additions and 128 deletions.
82 changes: 73 additions & 9 deletions SwiftPamphletApp.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

11 changes: 10 additions & 1 deletion SwiftPamphletApp/Guide/Bookmark/View/BookmarkListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ import SwiftData

struct BookmarkListView: View {
@Environment(\.modelContext) var modelContext
// @Binding var selectedBM: BookmarkModel?
@Query(BookmarkModel.all) var bms: [BookmarkModel]
// var bms: [BookmarkModel] = [BookmarkModel]() // 测试空数据用
@State private var limit: Int = 50
@State private var trigger = false
var body: some View {
Expand All @@ -37,5 +37,14 @@ struct BookmarkListView: View {
}
}
.listStyle(.sidebar)
.overlay {
if bms.isEmpty {
ContentUnavailableView {
Label("无书签", systemImage: "bookmark.slash")
} description: {
Text("请到手册中添加书签")
}
}
} // end overlay
}
}
30 changes: 23 additions & 7 deletions SwiftPamphletApp/Guide/View/GuideListView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ final class GuideListModel {
L(t: "Swift语法", icon: "swift", sub: [
L(t: "语法基础", sub: [
L(t: "变量"),
L(t: "打印"),
L(t: "注释"),
L(t: "可选"),
L(t: "打印", icon: "printer"),
L(t: "注释", icon: "number.square"),
L(t: "可选", icon: "exclamationmark.questionmark"),
L(t: "闭包"),
L(t: "函数"),
L(t: "访问控制"),
Expand Down Expand Up @@ -187,7 +187,10 @@ final class GuideListModel {
L(t: "SwiftUI对标的UIKit视图"),
]),
L(t: "图文组件",sub: [
L(t: "Text"),
L(t: "Text", sub: [
L(t: "Text"),
L(t: "Text-动态时间")
]),
L(t: "Link"),
L(t: "Label"),
L(t: "TextEditor"),
Expand Down Expand Up @@ -243,10 +246,23 @@ final class GuideListModel {
L(t: "SwiftData多线程"),
L(t: "SwiftData-版本迁移"),
L(t: "SwiftData-调试"),
L(t: "SwiftData-资料")
L(t: "SwiftData-资料", icon: "books.vertical")
]),
L(t: "Widget小部件", icon: "window.shade.open", sub: [
L(t: "Widget访问SwiftData")
L(t: "小组件", icon: "window.shade.open", sub: [
L(t: "小组件-StaticConfiguration",icon: "doc.plaintext"),
L(t: "小组件-AppIntentConfiguration"),
L(t: "小组件-配置选项",icon: "rectangle.portrait.bottomleft.inset.filled"),
L(t: "AppIntentTimelineProvider"),
L(t: "Widget View"),
L(t: "刷新小组件", icon: "arrow.clockwise.circle"),
L(t: "小组件动画", icon: "figure.disc.sports"),
L(t: "小组件-远程定时获取数据", icon: "cloud"),
L(t: "小组件-获取位置权限更新内容", icon: "location.fill.viewfinder"),
L(t: "支持多个小组件"),
L(t: "获取小组件形状"),
L(t: "小组件-Deep link"),
L(t: "小组件访问SwiftData"),
L(t: "小组件-参考资料", icon: "books.vertical"),
]),
L(t: "系统能力",icon: "apple.terminal",sub: [
L(t: "Swift-DocC", icon: "doc.append")
Expand Down
9 changes: 5 additions & 4 deletions SwiftPamphletApp/HomeUI/DataLink.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ struct DataLink: Identifiable {
let id = UUID()
let title: String
let imageName: String
var color: Color = Color.primary
var children: [DataLink]?

enum ShowType {
Expand Down Expand Up @@ -118,11 +119,11 @@ struct DataLink: Identifiable {
extension DataLink {
static var dataLinks = [
DataLink(title: "开发手册", imageName: "", children: [
DataLink(title: "书签", imageName: "p24"),
DataLink(title: "Apple技术", imageName: "p22")
DataLink(title: "书签", imageName: "p24", color: .mint),
DataLink(title: "Apple技术", imageName: "p22", color: .indigo)
]),
DataLink(title: "资料整理", imageName: "", children: [
DataLink(title: "全部资料", imageName: "p7"),
DataLink(title: "全部资料", imageName: "p7", color: .cyan),
DataLink(title: "未分类", imageName: "p6"),
DataLink(title: "收藏", imageName: "p11"),
DataLink(title: "归档", imageName: "p3")
Expand All @@ -132,7 +133,7 @@ extension DataLink {
var arr = DataLink.dataLinks
arr.append(
DataLink(title: "Github", imageName: "", children: [
DataLink(title: "开发/仓库", imageName: "p5"),
DataLink(title: "开发/仓库", imageName: "p5", color: .green),
]))
return arr
}
Expand Down
2 changes: 1 addition & 1 deletion SwiftPamphletApp/HomeUI/SidebarView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ struct SidebarView: View {
ForEach(isShowGithub ? DataLink.dataLinksWithGithub() : DataLink.dataLinks) { link in
Section {
OutlineGroup(link.children ?? [], children: \.children) { i in
SideBarLabel(title: i.title, imageName: i.imageName)
SideBarLabel(title: i.title, imageName: i.imageName, color: i.color)
.tag(i.title)
}
} header: {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@

逻辑更新时,不会触发 `body` 的重绘,只对使用了 Text Date 插值的 `Text`。 

倒计时

```swift
Text(Date().addingTimeInterval(60), style: .offset)
```

指定多长时间

```swift
// 多久后
let aimDate = Calendar.current.date(byAdding: DateComponents(minute: 10), to: Date())!

```

指定一个具体时间

```swift
// 具体时间
let aimDate = Calendar.current(DateComponents(year: 2024, month: 6, day: 11, hour: 20, minute: 10))!
```

Text 视图

```swift
// 多种表现样式
Text(aimDate, style: .relative)
Text(aimDate, style: .offset)
Text(aimDate, style: .timer)
Text(aimDate, style: .date)
Text(aimDate, style: .time)
```

两个时间间隔

```swift
let beginDate = Calendar.current.date(from: DateComponents(year: 2024, month: 6, day: 11, hour: 20, minute: 10))!
let endDate = Calendar.current.date(from: DateComponents(year: 2024, month: 6, day: 15, hour: 20, minute: 10))!

Text(beginDate ... endDate)
```
Original file line number Diff line number Diff line change
@@ -1,66 +1,28 @@
结果生成器(Result builders),通过传递序列创建新值,SwiftUI就是使用的结果生成器将多个视图生成一个视图

@dynamicCallable 动态可调用类型。通过实现 dynamicallyCall 方法来定义变参的处理。

```swift
@resultBuilder
struct RBS {
// 基本闭包支持
static func buildBlock(_ components: Int...) -> Int {
components.reduce(0) { partialResult, i in
partialResult + i
}
}
// 支持条件判断
static func buildEither(first component: Int) -> Int {
component
}
static func buildEither(second component: Int) -> Int {
component
@dynamicCallable
struct D {
// 带参数说明
func dynamicallyCall(withKeywordArguments args: KeyValuePairs<String, Int>) -> Int {
let firstArg = args.first?.value ?? 0
return firstArg * 2
}
// 支持循环
static func buildArray(_ components: [Int]) -> Int {
components.reduce(0) { partialResult, i in
partialResult + i

// 无参数说明
func dynamicallyCall(withArguments args: [String]) -> String {
var firstArg = ""
if args.count > 0 {
firstArg = args[0]
}
return "show \(firstArg)"
}
}

let a = RBS.buildBlock(
1,
2,
3
)
print(a) // 6

// 应用到函数中
@RBS func f1() -> Int {
1
2
3
}
print(f1()) // 6

// 设置了 buildEither 就可以在闭包中进行条件判断。
@RBS func f2(stopAtThree: Bool) -> Int {
1
2
3
if stopAtThree == true {
0
} else {
4
5
6
}
}
print(f2(stopAtThree: false)) // 21

// 设置了 buildArray 就可以在闭包内使用循环了
@RBS func f3() -> Int {
for i in 1...3 {
i * 2
}
}
print(f3()) // 12
let d = D()
let i = d(numberIs: 2)
print(i) // 4
let s = d("hi")
print(s) // show hi
```

[SE-0348 buildPartialBlock for result builders](https://github.com/apple/swift-evolution/blob/main/proposals/0348-buildpartialblock.md) 简化了实现复杂 result buiders 所需的重载。
Original file line number Diff line number Diff line change
@@ -1,27 +1,45 @@
@dynamicCallable 动态可调用类型。通过实现 dynamicallyCall 方法来定义变参的处理。

@dynamicMemberLookup 指示访问属性时调用一个已实现的处理动态查找的下标方法 subscript(dynamicMemeber:),通过指定属性字符串名返回值。使用方法如下:

```swift
@dynamicCallable
@dynamicMemberLookup
struct D {
// 带参数说明
func dynamicallyCall(withKeywordArguments args: KeyValuePairs<String, Int>) -> Int {
let firstArg = args.first?.value ?? 0
return firstArg * 2
// 找字符串
subscript(dynamicMember m: String) -> String {
let p = ["one": "first", "two": "second"]
return p[m, default: ""]
}
// 找整型
subscript(dynamicMember m: String) -> Int {
let p = ["one": 1, "two": 2]
return p[m, default: 0]
}

// 无参数说明
func dynamicallyCall(withArguments args: [String]) -> String {
var firstArg = ""
if args.count > 0 {
firstArg = args[0]
// 找闭包
subscript(dynamicMember m: String) -> (_ s: String) -> Void {
return {
print("show \($0)")
}
return "show \(firstArg)"
}
// 静态数组成员
var p = ["This is a member"]
// 动态数组成员
subscript(dynamicMember m: String) -> [String] {
return ["This is a dynamic member"]
}
}

let d = D()
let i = d(numberIs: 2)
print(i) // 4
let s = d("hi")
print(s) // show hi
let s1: String = d.one
print(s1) // first
let i1: Int = d.one
print(i1) // 1
d.show("something") // show something
print(d.p) // ["This is a member"]
let dynamicP:[String] = d.dp
print(dynamicP) // ["This is a dynamic member"]
```

类使用 @dynamicMemberLookup,继承的类也会自动加上 @dynamicMemberLookup。协议上定义 @dynamicMemberLookup,通过扩展可以默认实现 subscript(dynamicMember:) 方法。



Loading

0 comments on commit d657cfc

Please sign in to comment.