SwiftUI簡單使用

SwiftUI入門教程
SwiftUI寫一個簡單的頁面
上面github鏈接教程寫的很詳細(xì)辐啄,但有的api可能有點(diǎn)出入,最好還是clone項(xiàng)目,自己跑起來研究下。

廢話有點(diǎn)多,介意的直接看 正題三

寫在前面

這段時間公司業(yè)務(wù)不是很忙授嘀,我們一直處于新技術(shù)探究階段。前段時間學(xué)過flutter,總體來說還是很不錯姿染,不管是集成三方包,還是vscode新api學(xué)習(xí)成本,又或狀態(tài)管理和路由管理的三方框架(如GetX) 悬赏,使用起來都特別順手方便狡汉。之前因?yàn)闃I(yè)務(wù)需求,一直用的都是熟悉的oc闽颇,對SwiftUI也只是聽聽盾戴,沒有怎么入手研究過”啵可能對沒有接觸過的人尖啡,對SwiftUI來說聽的最多的詞 應(yīng)該就是聲明式語言,UI庫剩膘,一統(tǒng)蘋果所有終端設(shè)備的新框架庫等等衅斩。通過這兩天的學(xué)習(xí)接觸 SwiftUI確實(shí)是很棒。不啰嗦啦怠褐,進(jìn)入正題~

@[TOC]

一畏梆、簡潔高效的@State

二、好用的全局環(huán)境變量@EnvironmentObject

1奈懒、優(yōu)點(diǎn)

2奠涌、代碼使用

三、SwiftUI調(diào)用舊vc

1磷杏、創(chuàng)建wrapper并實(shí)現(xiàn)UIViewControllerRepresentable協(xié)議

2溜畅、SwiftUI中調(diào)用TestViewController

四、ViewController里調(diào)用SwiftUI頁面

一茴丰、簡潔高效的@State
在flutter中若改變某個值需更新界面的話达皿,需要setState,顯得很麻煩贿肩。但SwiftUI里面只要聲明一個@State變量就好峦椰,真的是太好用。例如下面代碼就是動態(tài)顯示slider滑動的值汰规,binding也很簡潔汤功,直接通過$加相應(yīng)的變量即可。這種binding在TextField真的是特別好用溜哮。oc那種delegate回調(diào)方式根本沒法比滔金。

import SwiftUI
import Combine

struct SliderPage : View {
    
    @State var rating = 0.5

    var body: some View {
        VStack {
            Text("Slider Value: \(self.rating)")
            Slider(value: $rating)
                .padding(30)
            
        }.navigationBarTitle(Text("Slider"))
    }
}

二、好用的全局環(huán)境變量@EnvironmentObject

1茂嗓、優(yōu)點(diǎn):整個app能全局共享該數(shù)據(jù)餐茵,且一旦數(shù)據(jù)更新,用到該數(shù)據(jù)的地方都會相應(yīng)的更新述吸。

2忿族、代碼使用

全局order變量

import SwiftUI

@main
struct iDineApp: App {
    @StateObject var order = Order()

    var body: some Scene {
        WindowGroup {
            MainView()
                .environmentObject(order)
        }
    }
}

存儲信息的Order 模型

import SwiftUI

class Order: ObservableObject {
    @Published var items = [MenuItem]()

    var total: Int {
        if items.count > 0 {
            return items.reduce(0) { $0 + $1.price }
        } else {
            return 0
        }
    }

    func add(item: MenuItem) {
        items.append(item)
    }

    func remove(item: MenuItem) {
        if let index = items.firstIndex(of: item) {
            items.remove(at: index)
        }
    }
}

使用全局Order

import SwiftUI

struct OrderView: View {
    @EnvironmentObject var order: Order

    var body: some View {
        NavigationView {
            List {
                Section {
                    ForEach(order.items) { item in
                        HStack {
                            Text(item.name)
                            Spacer()
                            Text("$\(item.price)")
                        }
                    }
                    .onDelete(perform: deleteItems)
                }

                Section {
                    NavigationLink(destination: CheckoutView()) {
                        Text("Place Order")
                    }
                }
                .disabled(order.items.isEmpty)
            }
            .navigationTitle("Order")
            .listStyle(InsetGroupedListStyle())
            .toolbar {
                EditButton()
            }
        }
    }

    func deleteItems(at offsets: IndexSet) {
        order.items.remove(atOffsets: offsets)
    }
}

以上代碼來自github上iDine項(xiàng)目。


三、SwiftUI調(diào)用舊vc
SwiftUI如何調(diào)用項(xiàng)目中原來就有的ViewController?
思路:創(chuàng)建一個wrapper道批,實(shí)現(xiàn)UIViewControllerRepresentable協(xié)議错英,做相應(yīng)的映射。例如隆豹,現(xiàn)在有個TestViewController椭岩,我們?nèi)绾卧赟wiftUI點(diǎn)擊某個link跳轉(zhuǎn)到該頁面。

1璃赡、創(chuàng)建wrapper并實(shí)現(xiàn)UIViewControllerRepresentable協(xié)議

import UIKit
import SwiftUI

// 這里只能用struct判哥,不能用class
struct BFOViewControllerWrapper<T : UIViewController>: UIViewControllerRepresentable {
    typealias UIViewControllerType = T

        func makeUIViewController(context: UIViewControllerRepresentableContext<BFOViewControllerWrapper>) -> BFOViewControllerWrapper.UIViewControllerType {
          return BFOViewControllerWrapper.UIViewControllerType()

        }

        func updateUIViewController(_ uiViewController: BFOViewControllerWrapper.UIViewControllerType, context: UIViewControllerRepresentableContext<BFOViewControllerWrapper>) {
            //
        }
}

2、SwiftUI中調(diào)用TestViewController

NavigationLink(
                        destination: BFOViewControllerWrapper<TestViewController>()) {
                        Text("跳轉(zhuǎn)到TestViewController頁面")
                    }

細(xì)心的網(wǎng)友鉴吹,肯定注意到了上面的一個亮點(diǎn)姨伟,對 就是泛型的使用。這樣使用雖然調(diào)用的時候感覺寫的字母多了點(diǎn)豆励,復(fù)雜了點(diǎn)夺荒,但BFOViewControllerWrapper卻可以統(tǒng)一重復(fù)的使用,不但功能清晰良蒸,后續(xù)維護(hù)也很高效技扼。


四、ViewController里調(diào)用SwiftUI頁面
將SwiftUI頁面放到一個UIHostingController里面嫩痰,之后再正常跳轉(zhuǎn)剿吻。如下某個vc點(diǎn)擊按鈕跳轉(zhuǎn)到一個SwfitUI頁面

import UIKit
import SwiftUI

class TestViewController: UIViewController {
    lazy var lb: UILabel = {
        let lb = UILabel(frame: CGRect(x: 50, y: 100, width: 200, height: 50));
        lb.text = "我是UIViewController的文案"
        lb.textColor = .red
        lb.font = UIFont.systemFont(ofSize: 14)
        return lb
    }()
    
    lazy var btn: UIButton = {
        let btn = UIButton(frame: CGRect(x: 50, y: 200, width: 200, height: 50))
        btn.setTitle("點(diǎn)我展示SwiftUI頁面", for: .normal)
        btn.setTitleColor(.blue, for: .normal)
        btn.setTitleShadowColor(.red, for: .normal)
        btn.backgroundColor = .green
        btn.titleLabel?.font = UIFont.systemFont(ofSize: 14)
        btn.layer.cornerRadius = 10
        btn.layer.masksToBounds = true
        btn.addTarget(self, action: #selector(clickBtn(button:)), for: .touchUpInside)
        return btn
    }()
    // 點(diǎn)擊按鈕跳轉(zhuǎn)到SwiftUI頁面
    @objc func clickBtn(button: UIButton){
        print("you click btn")
        if #available(iOS 13, *) {
            let testSwiftUIView = UIHostingController(rootView: TextPage())
            navigationController?.pushViewController(testSwiftUIView, animated: true)
        }
    }
    override func viewDidLoad() {
        super.viewDidLoad()

        view.addSubview(lb);
        view.addSubview(btn)
    }

}

附:Swift高階函數(shù)map,filter串纺,reduce簡單使用
map用于映射丽旅,可將一個列表轉(zhuǎn)化成另一個列表,例如下面將數(shù)字列表轉(zhuǎn)成字符串列表

//$0代表數(shù)組的元素
let array = [1, 2, 3, 4, 5 , 6, 7]
let result = array.map {
  String($0)
}

filter 用于過濾纺棺,可以對數(shù)組中的元素按照某種規(guī)則進(jìn)行過濾榄笙,例如下面輸出大于5的元素

let array = [1, 2, 3, 4, 5 , 6, 7]
let result = array.filter {
          $0 > 5
}
print("result: \(result)");

reduce用于計算或合并

//計算數(shù)組array元素的和
//在這里$0和$1的意義不同,$0代表元素計算后的結(jié)果祷蝌,$1代表元素
//10代表初始化值茅撞,在這里可以理解為 $0初始值 = 10
let result3 = array.reduce(10){  
  $0 + $1
}

合并

let result4 = array.reduce(""){$0 + "\($1)"}// 轉(zhuǎn)換為字符串并拼接
print("result4:",result4);

參考鏈接,感謝分享??

end

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末巨朦,一起剝皮案震驚了整個濱河市米丘,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌糊啡,老刑警劉巖拄查,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異棚蓄,居然都是意外死亡靶累,警方通過查閱死者的電腦和手機(jī)腺毫,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進(jìn)店門癣疟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來挣柬,“玉大人,你說我怎么就攤上這事睛挚⌒盎祝” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵扎狱,是天一觀的道長侧到。 經(jīng)常有香客問我,道長淤击,這世上最難降的妖魔是什么匠抗? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮污抬,結(jié)果婚禮上汞贸,老公的妹妹穿的比我還像新娘。我一直安慰自己印机,他們只是感情好矢腻,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著射赛,像睡著了一般多柑。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上楣责,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天竣灌,我揣著相機(jī)與錄音,去河邊找鬼秆麸。 笑死初嘹,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蛔屹。 我是一名探鬼主播削樊,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼兔毒!你這毒婦竟也來了漫贞?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤育叁,失蹤者是張志新(化名)和其女友劉穎迅脐,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體豪嗽,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谴蔑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年豌骏,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片隐锭。...
    茶點(diǎn)故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡窃躲,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出钦睡,到底是詐尸還是另有隱情蒂窒,我是刑警寧澤,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布荞怒,位于F島的核電站洒琢,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏褐桌。R本人自食惡果不足惜衰抑,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望荧嵌。 院中可真熱鬧呛踊,春花似錦、人聲如沸完丽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽逻族。三九已至蜻底,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間聘鳞,已是汗流浹背薄辅。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留抠璃,地道東北人站楚。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像搏嗡,于是被迫代替她去往敵國和親窿春。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評論 2 359

推薦閱讀更多精彩內(nèi)容