SwiftUI的注意點

Hi, 大家好盯腌,我是姜友華。這兩天在適應(yīng)SwiftUI渊跋,SwiftUI較Swift UIKit在構(gòu)建APP有較大的改變腊嗡。在這里着倾,我將其中的注意點記錄下來。

通常我在學(xué)習(xí)新的界面類開發(fā)框架時燕少,回從以下幾個方面著手:頁面的構(gòu)建卡者、頁面的跳轉(zhuǎn)、狀態(tài)的改變客们、數(shù)據(jù)的傳遞及數(shù)據(jù)的持久化崇决。SwiftUI較Swift UIKit在數(shù)據(jù)的傳遞與數(shù)據(jù)的持久化沒有變化,所以這里只說說:頁面的構(gòu)建底挫、頁面的跳轉(zhuǎn)恒傻、數(shù)據(jù)的傳遞。

官網(wǎng)里有有史以來最好的教程建邓,還有最好的說明

一盈厘、頁面的構(gòu)建。

  1. View:
  • Text官边、
  • Images
  • Buttons
  • Controls
  • Value Selectors
  • Value Indicators
    ...

2.Layout

  • Stack
  • Grids
  • Containers
  • Scroll Views
  • List
  • Tables
  • Spacers and Dividers
    ...

二沸手、頁面的跳轉(zhuǎn)

  1. 判斷渲染
if isShow {
    MyView()
}
  1. Present
struct ContentView: View {
    @State private var showingSheet = false

    var body: some View {
        Button("Show Sheet") {
            showingSheet.toggle()
        }
        .sheet(isPresented: $showingSheet) {
            backFunc()
        } content: {
            MyView()
        }
    }
}
  1. Navigation
  • NavigationLink、NavigationView
NavigationView {
    List {
        NavigationLink("Purple", destination: ColorDetail(color: .purple))
        NavigationLink("Pink", destination: ColorDetail(color: .pink))
        NavigationLink("Orange", destination: ColorDetail(color: .orange))
    }
    .navigationTitle("Colors")

    Text("Select a Color") // A placeholder to show before selection.
}

struct ColorDetail: View {
    var color: Color

    var body: some View {
        color
            .frame(width: 200, height: 200)
            .navigationTitle(color.description.capitalized)
    }
}
  1. TabBar
TabView {
    Text("The First Tab")
        .badge(10)
        .tabItem {
            Image(systemName: "1.square.fill")
            Text("First")
        }
    Text("Another Tab")
        .tabItem {
            Image(systemName: "2.square.fill")
            Text("Second")
        }
    Text("The Last Tab")
        .tabItem {
            Image(systemName: "3.square.fill")
            Text("Third")
        }
}
.font(.headline)

三注簿、狀態(tài)的改變

  1. @State契吉、@Binding, struct诡渴;@StateObject捐晶、@Binding Object、@ObservableObject妄辩、@EnvironmentObject惑灵,class。
  • @State
@State private var isVisible = true
......
if isVisible == true {
    Text("Hello") // Only rendered when isVisible is true.
}
  • @Binding 作用于父子視圖恩袱。
// 子視圖
struct PlayButton: View {
    @Binding var isPlaying: Bool

    var body: some View {
        Button(action: {
            self.isPlaying.toggle()
        }) {
            Image(systemName: isPlaying ? "pause.circle" : "play.circle")
        }
    }
}

// 父視圖
struct PlayerView: View {
    var episode: Episode
    @State private var isPlaying: Bool = false

    var body: some View {
        VStack {
            Text(episode.title)
            Text(episode.showTitle)
            PlayButton(isPlaying: $isPlaying)
        }
    }
}
  • @ObservableObject 即KVO模式泣棋。
class Contact: ObservableObject {
    @Published var name: String
    @Published var age: Int

    init(name: String, age: Int) {
        self.name = name
        self.age = age
    }

    func haveBirthday() -> Int {
        age += 1
        return age
    }
}

let john = Contact(name: "John Appleseed", age: 24)
cancellable = john.objectWillChange
    .sink { _ in
        print("\(john.age) will change")
}
print(john.haveBirthday())
// Prints "24 will change"
// Prints "25"

objectWillChange是ObservableObject協(xié)議的方法。

  • EnvironmentObject
class User: ObservableObject {
      @Publish var name: String
      @Publish var age: Int
}

struct EditView: View {
    @EnvironmentObject var user: User

    var body: some View {
        TextField("Name", text: $user.name)
    }
}

struct DisplayView: View {
    @EnvironmentObject var user: User

    var body: some View {
        Text(user.name)
    }
}

struct ContentView: View {
    let user = User(name: "Jiang", age)

    var body: some View {
        VStack {
            EditView()
            DisplayView()\
        }.environmentObject(user)
    }
}

2 @Environment畔塔、@ FocusState

  • @Environment
    獲取環(huán)境變量潭辈。
 @Environment(\.colorScheme) var colorScheme: ColorScheme
......
if colorScheme == .dark { // Checks the wrapped value.
    DarkContent()
} else {
    LightContent()
}
  • @FocusState
    becomefirstresponder
struct LoginForm {
    enum Field: Hashable {
        case username
        case password
    }

    @State private var username = ""
    @State private var password = ""
    @FocusState private var focusedField: Field?

    var body: some View {
        Form {
            TextField("Username", text: $username)
                .focused($focusedField, equals: .username)

            SecureField("Password", text: $password)
                .focused($focusedField, equals: .password)

            Button("Sign In") {
                if username.isEmpty {
                    focusedField = .username
                } else if password.isEmpty {
                    focusedField = .password
                } else {
                    handleLogin(username, password)
                }
            }
        }
    }
}

四、GeometryReader與Path

  1. GeometryReader
  • 獲取屏幕信息澈吨。
GeometryReader { geometry in
    HStack(spacing: 0) {
        Text("Left")
            .font(.largeTitle)
            .foregroundColor(.black)
            .frame(width: geometry.size.width * 0.33)
            .background(Color.yellow)
        Text("Right")
            .font(.largeTitle)
            .foregroundColor(.black)
            .frame(width: geometry.size.width * 0.67)
            .background(Color.orange)
    }
}
.frame(height: 50)
  1. GeometryReader與Path
var body: some View {
       GeometryReader{ geometry in
             Path{ path in 
                path.moveto()
                path.addLine()
            }
      }
}
  1. Shape
struct Triangle: Shape {
    func path(in rect: CGRect) -> Path {
        var path = Path()

        path.move(to: CGPoint(x: rect.midX, y: rect.minY))
        path.addLine(to: CGPoint(x: rect.minX, y: rect.maxY))
        path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))
        path.addLine(to: CGPoint(x: rect.midX, y: rect.minY))

        return path
    }
}

五把敢、SwiftUI與UIKit組件互用。

  1. UIKit用SwiftUI
  let swiftUIView = Text("Jiang youhua") 
  let viewCtrl = UIHostingController(rootView: swiftUIView)
  1. UIView轉(zhuǎn)SwiftUI
struct TextView: UIViewRepresentable {
    @Binding var text: NSMutableAttributedString

    func makeUIView(context: Context) -> UITextView {
        UITextView()
    }

    func updateUIView(_ uiView: UITextView, context: Context) {
        uiView.attributedText = text
    }

}
  1. UIViewController轉(zhuǎn)SwiftUI
struct PageViewController<Page: View>: UIViewControllerRepresentable {
    var pages: [Page]

    func makeCoordinator() -> Coordinator {
        Coordinator(self)
    }

    func makeUIViewController(context: Context) -> UIPageViewController {
        let pageViewController = UIPageViewController(
            transitionStyle: .scroll,
            navigationOrientation: .horizontal)

        return pageViewController
    }

    func updateUIViewController(_ pageViewController: UIPageViewController, context: Context) {
        pageViewController.setViewControllers(
            [context.coordinator.controllers[0]], direction: .forward, animated: true)
    }

    class Coordinator: NSObject, UIPageViewControllerDataSource {
        var parent: PageViewController
        var controllers = [UIViewController]()

        init(_ pageViewController: PageViewController) {
            parent = pageViewController
            controllers = parent.pages.map { UIHostingController(rootView: $0) }
        }

        func pageViewController(
            _ pageViewController: UIPageViewController,
            viewControllerBefore viewController: UIViewController) -> UIViewController?
        {
            guard let index = controllers.firstIndex(of: viewController) else {
                return nil
            }
            if index == 0 {
                return controllers.last
            }
            return controllers[index - 1]
        }

        func pageViewController(
            _ pageViewController: UIPageViewController,
            viewControllerAfter viewController: UIViewController) -> UIViewController?
        {
            guard let index = controllers.firstIndex(of: viewController) else {
                return nil
            }
            if index + 1 == controllers.count {
                return controllers.first
            }
            return controllers[index + 1]
        }
    }
}

好谅辣,我是姜友華修赞,今天就到這里,下次見。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末柏副,一起剝皮案震驚了整個濱河市勾邦,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌割择,老刑警劉巖眷篇,帶你破解...
    沈念sama閱讀 210,978評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異荔泳,居然都是意外死亡蕉饼,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評論 2 384
  • 文/潘曉璐 我一進店門玛歌,熙熙樓的掌柜王于貴愁眉苦臉地迎上來昧港,“玉大人,你說我怎么就攤上這事支子〈捶剩” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評論 0 345
  • 文/不壞的土叔 我叫張陵译荞,是天一觀的道長瓤的。 經(jīng)常有香客問我,道長吞歼,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,324評論 1 282
  • 正文 為了忘掉前任塔猾,我火速辦了婚禮篙骡,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘丈甸。我一直安慰自己糯俗,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,390評論 5 384
  • 文/花漫 我一把揭開白布睦擂。 她就那樣靜靜地躺著得湘,像睡著了一般。 火紅的嫁衣襯著肌膚如雪顿仇。 梳的紋絲不亂的頭發(fā)上淘正,一...
    開封第一講書人閱讀 49,741評論 1 289
  • 那天,我揣著相機與錄音臼闻,去河邊找鬼鸿吆。 笑死,一個胖子當(dāng)著我的面吹牛述呐,可吹牛的內(nèi)容都是我干的惩淳。 我是一名探鬼主播,決...
    沈念sama閱讀 38,892評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼乓搬,長吁一口氣:“原來是場噩夢啊……” “哼思犁!你這毒婦竟也來了代虾?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評論 0 266
  • 序言:老撾萬榮一對情侶失蹤激蹲,失蹤者是張志新(化名)和其女友劉穎褐着,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體托呕,經(jīng)...
    沈念sama閱讀 44,104評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡含蓉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,451評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了项郊。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片馅扣。...
    茶點故事閱讀 38,569評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖着降,靈堂內(nèi)的尸體忽然破棺而出差油,到底是詐尸還是另有隱情,我是刑警寧澤任洞,帶...
    沈念sama閱讀 34,254評論 4 328
  • 正文 年R本政府宣布蓄喇,位于F島的核電站,受9級特大地震影響交掏,放射性物質(zhì)發(fā)生泄漏妆偏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,834評論 3 312
  • 文/蒙蒙 一盅弛、第九天 我趴在偏房一處隱蔽的房頂上張望钱骂。 院中可真熱鬧,春花似錦挪鹏、人聲如沸见秽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽解取。三九已至,卻和暖如春返顺,著一層夾襖步出監(jiān)牢的瞬間禀苦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評論 1 264
  • 我被黑心中介騙來泰國打工创南, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留伦忠,地道東北人。 一個月前我還...
    沈念sama閱讀 46,260評論 2 360
  • 正文 我出身青樓稿辙,卻偏偏與公主長得像昆码,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,446評論 2 348

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

  • SwiftUI要求 iOS13.0+ 快捷鍵 control + option + 點擊:出現(xiàn)屬性編輯器 comm...
    余青松閱讀 6,238評論 1 11
  • 學(xué)習(xí)文章 文集:Hacking with iOS: SwiftUI Edition[https://www.jia...
    xmb閱讀 4,473評論 3 14
  • 最近抽空終于把官方SwiftUI Tutorials擼了一遍赋咽,網(wǎng)上已經(jīng)很多翻譯或者該Tutorials說明旧噪。 這...
    JerrySi閱讀 1,537評論 0 0
  • 原創(chuàng):有趣知識點摸索型文章創(chuàng)作不易,請珍惜脓匿,之后會持續(xù)更新淘钟,不斷完善個人比較喜歡做筆記和寫總結(jié),畢竟好記性不如爛筆...
    時光啊混蛋_97boy閱讀 3,777評論 1 11
  • SwiftUI簡介 SwiftUI是wwdc2019發(fā)布的一個新的UI框架陪毡,通過聲明和修改視圖來布局UI和創(chuàng)建流暢...
    iridescentzc閱讀 2,113評論 1 1