雪白西丘斯 wrote:
#4 4-1c 雨燕(恕刪)
老師請教一下,這個func
func animation<v>
< >是不是generic?
表示它可以丟Double或是Int?
https://developer.apple.com/documentation/swiftui/view/animation(_:value:)</v>
CUNNING wrote:
老師請教一下,這個funcfunc...(恕刪)
func animation<V>(
_ animation: Animation?,
value: V
) -> some View where V : Equatable
// Tested by Heman, 2022/07/05
// https://developer.apple.com/documentation/swiftui/view/animation(_:value:)
import PlaygroundSupport
import SwiftUI
struct 動畫測試: View {
@State var 透明度 = 1.0
@State var 水平位移 = 100.0
var body: some View {
Text("System Alert!")
.font(.title)
.foregroundColor(.red)
.opacity(透明度)
.offset(x: 水平位移, y: 0)
.animation(.easeIn.repeatForever(), value: 透明度)
.onAppear {
// 透明度 = 0.0
水平位移 = -100
}
}
}
PlaygroundPage.current.setLiveView(動畫測試())
func animation(_ animation: Animation?, value: any Equatable) -> some View
# | 副檔名 | 檔案格式名稱 | 用途說明 |
1 | .playground | Xcode Playground | 2014年隨Swift程式語言一起發布的功能,可在Xcode裡面快速測試一段Swift程式,是Swift Playgrounds 的前身。 |
2 | .playgroundbook | Swift Playground Book | 2016年將Xcode Playground擴展成為一個獨立App,就是我們現在用的Swift Playgrounds,增加了「電子書」功能,可將Swift程式與電子書內容包裹在一起,邊看邊學程式設計。 |
3 | .swiftpm | Swift Package Manager | 讓Swift程式模組化,方便導出或導入外部程式模組(稱為Package套件),以開發App軟體。2019年先整合到Xcode,2021年整合進Swift Playgrounds 4.0。 |
struct 某視圖預覽: PreviewProvider {
static var previews: some View {
某視圖()
}
}
struct 選擇照片: View {
@State var 圖片集: [UIImage] = []
@State var 開關 = true
var body: some View {
ZStack {
Color.black
if 圖片集.isEmpty {
Text("請選擇一張照片")
.font(.title)
} else {
Image(uiImage: 圖片集.first!)
.resizable()
.scaledToFit()
}
}
.sheet(isPresented: $開關) {
開啟相簿(result: $圖片集, popup: $開關, limit: 1)
}
.onTapGesture {
開關.toggle()
}
}
}
struct 相簿圖片輪播: View {
var body: some View {
ZStack(alignment: .trailing) {
Color.black
TimelineView(.animation) { 時間參數 in
畫布(更新: 時間參數.date)
}
VStack {
Group {
Button(
action: {
print("Save to Photo Library")
},
label: {
Image(systemName: "square.and.arrow.down.fill")
})
Button(
action: {
print("Update photos from the web")
},
label: {
Image(systemName: "arrow.clockwise.icloud.fill")
})
Button(
action: {
print("Open Photo Library")
}, label: {
Image(systemName: "photo.on.rectangle.angled")
})
}
.font(.title)
.foregroundColor(.white)
.shadow(color: .blue, radius: 40, x: 0, y: 0)
.padding()
}
}
}
}
Button(
action: {...},
label: {...})
guard let myURL = myURLComponent.url else { return }
URLSession.shared.dataTask(with: myURL) { 回傳資料, 回傳碼 , 錯誤碼 in
if let 解碼資料 = 回傳資料 {
do {
let 解碼結果 = try JSONDecoder().decode(搜尋結果.self, from: 解碼資料)
print(回傳碼 ?? "No response")
作品列表 = 解碼結果.data
} catch {
print("JSON解碼錯誤")
}
} else {
print(錯誤碼 ?? "No error")
}
}
if let myURL = myURLComponent.url {
let (內容, 回傳碼) = try await URLSession.shared.data(from: myURL)
print(回傳碼)
let 解碼結果 = try JSONDecoder().decode(搜尋結果.self, from: 內容)
return 解碼結果.data
}
func 搜尋作品列表(_ artist: String) async throws -> [搜尋品項] {
var myURLComponent = URLComponents()
myURLComponent.scheme = "https"
myURLComponent.host = "api.artic.edu"
myURLComponent.path = "/api/v1/artworks/search"
myURLComponent.query = "q=\(artist)&limit=20"
if let myURL = myURLComponent.url {
let (內容, 回傳碼) = try await URLSession.shared.data(from: myURL)
print(回傳碼)
let 解碼結果 = try JSONDecoder().decode(搜尋結果.self, from: 內容)
return 解碼結果.data
}
return []
}
Picker("芝加哥藝術博物館", selection: $搜尋字串) {
Text("畢卡索(Pablo Picasso)").tag("Pablo Picasso")
Text("莫內(Claude Monet)").tag("Claude Monet")
Text("梵谷(Vincent van Gogh)").tag("Vincent van Gogh")
Text("威廉透納(William Turner)").tag("William Turner")
Text("秀拉(Georges Seurat)").tag("Georges Seurat")
}
.onChange(of: 搜尋字串) { _ in
Task {
do {
作品列表 = try await 搜尋作品列表(搜尋字串)
} catch {
print("網路有問題:\(error)")
}
}
}
// 4-10a App-2: 芝加哥藝術博物館(https://api.artic.edu/docs/)
// Created (for 3-4a) by Heman, 2021/10/02
// Revised (for 4-10a) by Heman, 2022/07/16
import PlaygroundSupport
import SwiftUI
// Data model for JSONDecoder
struct 搜尋結果: Codable {
let pagination: 分頁資訊
let data: [搜尋品項]
}
struct 分頁資訊: Codable {
let total: Int
let limit: Int
let offset: Int
let total_pages: Int
let current_page: Int
}
struct 搜尋品項: Codable, Identifiable {
let api_link: URL?
let id: Int
let title: String
}
struct 展示作品: View {
@State var 搜尋字串 = "Vincent van Gogh"
@State var 作品列表: [搜尋品項] = []
func 搜尋作品列表(_ artist: String) async throws -> [搜尋品項]{
var myURLComponent = URLComponents()
myURLComponent.scheme = "https"
myURLComponent.host = "api.artic.edu"
myURLComponent.path = "/api/v1/artworks/search"
myURLComponent.query = "q=\(artist)&limit=20"
if let myURL = myURLComponent.url {
let (內容, 回傳碼) = try await URLSession.shared.data(from: myURL)
print(回傳碼)
let 解碼結果 = try JSONDecoder().decode(搜尋結果.self, from: 內容)
return 解碼結果.data
}
return []
}
var body: some View {
Picker("芝加哥藝術博物館", selection: $搜尋字串) {
Text("畢卡索(Pablo Picasso)").tag("Pablo Picasso")
Text("莫內(Claude Monet)").tag("Claude Monet")
Text("梵谷(Vincent van Gogh)").tag("Vincent van Gogh")
Text("威廉透納(William Turner)").tag("William Turner")
Text("秀拉(Georges Seurat)").tag("Georges Seurat")
}
.onChange(of: 搜尋字串) { _ in
Task {
do {
作品列表 = try await 搜尋作品列表(搜尋字串)
} catch {
print("網路有問題:\(error)")
}
}
}
List(作品列表) { 作品 in
Label(作品.title, systemImage: "rectangle.portrait")
.font(.title2)
.lineLimit(1)
}
.task {
do {
作品列表 = try await 搜尋作品列表(搜尋字串)
} catch {
print("網路有問題:\(error)")
}
}
}
}
PlaygroundPage.current.setLiveView(展示作品())
網路有問題:Error Domain=NSURLErrorDomain Code=-1003 "無法找到指定主機名稱的伺服器。" UserInfo={_kCFStreamErrorCodeKey=-72000, NSUnderlyingError=0x600000e09ad0 {Error Domain=kCFErrorDomainCFNetwork Code=-1003 "(null)" UserInfo={_NSURLErrorNWPathKey=satisfied (Path is satisfied), interface: en1, ipv4, dns, _kCFStreamErrorCodeKey=-72000, _kCFStreamErrorDomainKey=10}}, _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <ea431b3f-70a5-4f0e-b5ec-a031e211251a>.<1>, _NSURLErrorRelatedURLSessionTaskErrorKey=(
"LocalDataTask <ea431b3f-70a5-4f0e-b5ec-a031e211251a>.<1>"
), NSLocalizedDescription=無法找到指定主機名稱的伺服器。, NSErrorFailingURLStringKey=https://api.artic.edu/api/v1/artworks/search?q=Vincent%20van%20Gogh&limit=20, NSErrorFailingURLKey=https://api.artic.edu/api/v1/artworks/search?q=Vincent%20van%20Gogh&limit=20, _kCFStreamErrorDomainKey=10}</ea431b3f-70a5-4f0e-b5ec-a031e211251a></ea431b3f-70a5-4f0e-b5ec-a031e211251a>
.task {
do {
作品列表 = try await 搜尋作品列表(搜尋字串)
} catch {
print("網路有問題:\(error)")
}
}
1. App 傳輸安全性 | 11. 照片圖庫(僅限加入) |
2. App 追蹤透明度 | 12. 相機 |
3. Face ID | 13. 網路連線(macOS) |
4. 使用時的核心位置 | 14. 總是取用核心位置 |
5. 區域網路 | 15. 聯絡人 |
6. 媒體資料庫(音樂) | 16. 藍牙 |
7. 提醒事項 | 17. 行事曆 |
8. 核心動作 | 18. 語音辨識 |
9. 檔案取用(macOS) | 19. 鄰近互動 |
10. 照片圖庫 | 20. 麥克風 |
Picker("芝加哥藝術博物館", selection: $搜尋字串) {
Text("畢卡索(Pablo Picasso)").tag("Pablo Picasso")
Text("莫內(Claude Monet)").tag("Claude Monet")
Text("梵谷(Vincent van Gogh)").tag("Vincent van Gogh")
Text("威廉透納(William Turner)").tag("William Turner")
Text("秀拉(Georges Seurat)").tag("Georges Seurat")
}
struct 藝術家: Identifiable {
var id: String { 英文名 }
var 中文名: String
var 英文名: String
}
let 近代西洋畫家: [藝術家] = [
藝術家(中文名: "威廉透納", 英文名: "William Turner"),
藝術家(中文名: "康斯塔伯", 英文名: "John Constable"),
藝術家(中文名: "德拉克洛瓦", 英文名: "Eugene Delacroix"),
藝術家(中文名: "米勒", 英文名: "Jean Francois Millet"),
藝術家(中文名: "庫爾貝", 英文名: "Gustave Courbet"),
藝術家(中文名: "馬奈", 英文名: "Edouard Manet"),
藝術家(中文名: "雷諾瓦", 英文名: "Pierre-Auguste Renoir"),
藝術家(中文名: "莫內", 英文名: "Claude Monet"),
藝術家(中文名: "竇加", 英文名: "Edgar Degas"),
藝術家(中文名: "塞尚", 英文名: "Paul Cezanne"),
藝術家(中文名: "高更", 英文名: "Paul Gauguin"),
藝術家(中文名: "秀拉", 英文名: "Georges Seurat"),
藝術家(中文名: "梵谷", 英文名: "Vincent van Gogh"),
藝術家(中文名: "羅特列克", 英文名: "Toulouse Lautrec"),
藝術家(中文名: "慕夏", 英文名: "Alphonse Mucha"),
藝術家(中文名: "克林姆", 英文名: "Gustav Klimt"),
藝術家(中文名: "馬蒂斯", 英文名: "Henri Matisse"),
藝術家(中文名: "米羅", 英文名: "Joan Miro"),
藝術家(中文名: "孟克", 英文名: "Edvard Munch"),
藝術家(中文名: "康丁斯基", 英文名: "Wassily Kandinsky"),
藝術家(中文名: "畢卡索", 英文名: "Pablo Picasso"),
藝術家(中文名: "蒙德里安", 英文名: "Piet Mondrian"),
藝術家(中文名: "布拉克", 英文名: "Georges Braque"),
藝術家(中文名: "伍德", 英文名: "Grant Wood"),
藝術家(中文名: "馬格利特", 英文名: "Rene Magritte"),
藝術家(中文名: "達利", 英文名: "Salvador Dalí"),
藝術家(中文名: "安迪沃荷", 英文名: "Andy Warhol")
]
Picker("芝加哥藝術博物館", selection: $搜尋字串) {
ForEach(近代西洋畫家) { 畫家 in
Text("\(畫家.中文名)(\(畫家.英文名))")
}
}
/// 選擇西洋畫家,取得英文名
struct 畫家選單: View {
@Binding var name: String // 將區域變數(name)宣告為可綁定
var body: some View {
HStack {
Image(systemName: "list.bullet")
Picker("芝加哥藝術博物館", selection: $name) {
ForEach(近代西洋畫家) { 畫家 in
Text("\(畫家.中文名)(\(畫家.英文名))")
}
// .pickerStyle(.inline)
}
}
}
}
struct 測試_1: View {
@State var 搜尋字串 = "Vincent van Gogh"
var body: some View {
VStack {
畫家選單(name: $搜尋字串) //「搜尋字串」與 name 綁定為同一變數
Spacer()
Image(systemName: "person.crop.artframe")
.resizable()
.scaledToFit()
.frame(height: 200)
Text(搜尋字串)
.font(.largeTitle)
Spacer()
}
}
}
// 4-10(1) 芝加哥藝術博物館v2
// Created (for 4-10a) by Heman, 2022/07/20
import SwiftUI
// Data model for Picker
struct 藝術家: Identifiable {
var id: String { 英文名 }
var 中文名: String
var 英文名: String
}
let 近代西洋畫家: [藝術家] = [
藝術家(中文名: "威廉透納", 英文名: "William Turner"),
藝術家(中文名: "康斯塔伯", 英文名: "John Constable"),
藝術家(中文名: "德拉克洛瓦", 英文名: "Eugene Delacroix"),
藝術家(中文名: "米勒", 英文名: "Jean Francois Millet"),
藝術家(中文名: "庫爾貝", 英文名: "Gustave Courbet"),
藝術家(中文名: "馬奈", 英文名: "Edouard Manet"),
藝術家(中文名: "雷諾瓦", 英文名: "Pierre-Auguste Renoir"),
藝術家(中文名: "莫內", 英文名: "Claude Monet"),
藝術家(中文名: "竇加", 英文名: "Edgar Degas"),
藝術家(中文名: "塞尚", 英文名: "Paul Cezanne"),
藝術家(中文名: "高更", 英文名: "Paul Gauguin"),
藝術家(中文名: "秀拉", 英文名: "Georges Seurat"),
藝術家(中文名: "梵谷", 英文名: "Vincent van Gogh"),
藝術家(中文名: "羅特列克", 英文名: "Toulouse Lautrec"),
藝術家(中文名: "慕夏", 英文名: "Alphonse Mucha"),
藝術家(中文名: "克林姆", 英文名: "Gustav Klimt"),
藝術家(中文名: "馬蒂斯", 英文名: "Henri Matisse"),
藝術家(中文名: "米羅", 英文名: "Joan Miro"),
藝術家(中文名: "孟克", 英文名: "Edvard Munch"),
藝術家(中文名: "康丁斯基", 英文名: "Wassily Kandinsky"),
藝術家(中文名: "畢卡索", 英文名: "Pablo Picasso"),
藝術家(中文名: "蒙德里安", 英文名: "Piet Mondrian"),
藝術家(中文名: "布拉克", 英文名: "Georges Braque"),
藝術家(中文名: "伍德", 英文名: "Grant Wood"),
藝術家(中文名: "馬格利特", 英文名: "Rene Magritte"),
藝術家(中文名: "達利", 英文名: "Salvador Dalí"),
藝術家(中文名: "安迪沃荷", 英文名: "Andy Warhol")
]
/// 選擇西洋畫家,取得英文名
struct 畫家選單: View {
@Binding var name: String
var body: some View {
HStack {
Image(systemName: "list.bullet")
Picker("芝加哥藝術博物館", selection: $name) {
ForEach(近代西洋畫家) { 畫家 in
Text("\(畫家.中文名)(\(畫家.英文名))")
}
// .pickerStyle(.inline)
}
}
}
}
struct 測試_1: View {
@State var 搜尋字串 = "Vincent van Gogh"
var body: some View {
VStack {
畫家選單(name: $搜尋字串)
Spacer()
Image(systemName: "person.crop.artframe")
.resizable()
.scaledToFit()
.frame(height: 200)
Text(搜尋字串)
.font(.largeTitle)
Spacer()
}
}
}
struct 預覽_1: PreviewProvider {
static var previews: some View {
測試_1()
}
}