Contents
Chào bạn đến với Fx Studio. Cuộc hành trình của chúng ta với SwiftUI vẫn tiếp tục với series SwiftUI Notes này. Chủ đề bài viết sẽ hướng dẫn cơ bản việc sử dụng biến Environment trong project.
Đây là loạt bài viết trong phần 2 của series SwiftUI Notes. Các bài viết tập trung vào việc giải thích các điểm lý thuyết của SwiftUI App & Declarative App. Và dành cho các bạn chưa đọc các chủ đề Declarative App thì hãy xem các link dưới đây:
Còn nếu mọi việc đã ổn rồi, thì …
Bắt đầu thôi!
Chuẩn bị
Các giá trị của môi trường sẽ ảnh hưởng tới toàn bộ ứng dụng của bạn về mặt hiển thị. Ví dụ như: accessibility, locale, calendar & color scheme … Và bạn có thể thử và kiểm tra hiển thị theo từng giá trị ở màn hình Preview. Từ đó mình có thể dễ dàng tìm và debug hoặc thiết kế một cách nhanh chóng.
Về chi tiết về phần này thì chúng ta sẽ có một bài viết cụ thể hơn. Sau đây, mình sẽ đi qua nhanh các vấn đề để bạn có thể xử lý với Environment values. Còn với demo cho bài viết này, bạn cần chuẩn bị như sau:
-
- Xcode 12
- Swift 5.4
- SwiftUI 2.0
Về demo bài viết, chúng ta sử dụng một project mới & với giao diện đơn giản nhất có thể. Bạn có thể checkout code tại đây:
-
- Toàn bộ repo: https://github.com/fx-studio/swiftui-notes
1. Thay đổi ở Preview
Bắt đầu, chúng ta hãy tạo mới một Project SwiftUI. Bạn sẽ học cách sử dụng biến môi trường vào Preview Struct. Công việc này giúp bạn có thể test nhanh được project với việc thay đổi các giá trị môi trường của thiết bị.
Công việc này sẽ tiết kiệm thời gian testing cho project rất nhiều.
Okay! Bạn hãy mở file ContentView.
import SwiftUI struct ContentView: View { var body: some View { Text("Hello, world!") .padding() } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
Bạn đã biết, chúng ta có 2 phần tách biệt:
- ContentView : để hiển thị nội dung
- Preview: để hiển thị bản xem trước của ContentView
Thay vì phải build project và thay đổi giá trị biến môi trường của thiết bị. Bạn có thể nhanh chóng cài đặt từng loại biến môi trường. Chúng ta sẽ lấy ví dụ với dark
& light
mode trong iOS.
Tại Preview, bạn thêm đoạn code sau vào.
struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() .environment(\.colorScheme, .light) } }
Mọi việc chưa có biến đổi gì hết. Bạn đổi nhẹ từ .light
sang .dark
thì sẽ thấy chữ Hello, world!
biến mất. Thực chất lúc này thì màu chữ của nó trùng với màu background.
Bạn hãy thử nghiệm và đây là cách thay đổi giá trị của môi trường. Với nó bạn không tốn thời gian build lại ứng dụng. Rất nhanh và tiện lợi.
Bạn có thể xem thêm các
key path
của các Environment Values tại đây.
2. Sử dụng biến môi trường
Việc quan trọng, ta sẽ phải dùng được biến môi trường vào trong code. Chứ không phải đơn giản thay đổi từ Preview Struct. Chúng ta sẽ tiếp tục thực hiện việc sử dụng cụ thể một biến môi trường vào trong code theo ví dụ dưới đây.
Ta có màu của nội dung Text đã tự động thay đổi theo giá trị biến môi trường. Vì đơn giản, nó sử dụng màu sắc mặc định của hệ thống. Khi hệ thông có sự thay đổi thì nó sẽ bị ảnh hưởng theo. Tiếp theo, chúng ta sẽ làm màu nền của Text thay đổi theo chế độ màu sắc sáng/tối.
Muốn thực hiện việc này, ta cần phải khai báo thêm một thuộc tính là biến môi trường. Bạn thêm dòng code sau vào ContentView.
@Environment(\.colorScheme) var colorScheme: ColorScheme
Trong đó:
@Environment
là một wrapper properties đại diện cho biến môi trường.\.colorScheme
là key path để trỏ tới cái chúng ta cần lấy. Đó là hệ màu theo chế độ theme.
Cái tên của property wrapper cũng đã mang nhiều ý nghĩa, property wrapper là vỏ bọc của property. Về cơ bản, property wrapper là một cấu trúc dữ liệu, nó sẽ đóng gói property, và bổ xung thêm một vài chức năng cho property đó.
Property wrapper có thể là dạng struct, class hoặc enum. Trước Swift 5.1, Swift đã có nhiều builtin wrappers như lazy, @NSCopying, và SwiftUI cũng có nhiều builtin wrappers như @State, @Binding,… Từ Swift 5.1 trở đi, chúng ta có thể viết thêm các custom property wrapper để phục vụ mục đích của mình
Bạn tiến hành chỉnh sửa Text một lần nữa với việc thay đổi background
của nó như sau:
Text("Hello, world!")
.background(colorScheme == .dark ? Color(.black) : Color(.white))
.padding()
Bấm Command + Option + P để cho Canvas load nhanh hơn. Và tận hưởng kết quả nào!
3. Local environment
SwiftUI cũng hỗ trợ cho chúng ta việc thay đổi hay cài đặt lại với từ giá trị biến môi trường cho một View cụ thể nào đó. Nó sẽ không bị ảnh hường từ các giá trị biến môi trường của thiết bị.
Đây là điểm linh hoạt của SwiftUI.
3.1. Cho từng element
Tại ContentView, bạn tiến hành thêm 1 VStack và thêm một Text nữa. Bạn xem đoạn code sau:
var body: some View { VStack { Text("Hello, world!") .background(colorScheme == .dark ? Color(.black) : Color(.white)) .padding() Text("Hello again!") .padding() .environment(\.colorScheme, .light) } }
Trong đó, bạn chú ý tới dòng code .environment(\.colorScheme, .light)
. Với dòng code này, đối tượng Text mới của chúng ta sẽ hiển thị theo giá trị môi trường của riêng nó.
Bấm Resume nhẹ của Canvas và xem kết quả tiếp theo nào.
Với cách này, bạn đủ sức sáng tạo với SwiftUI mà không sợ bất cứ gì từ thiết bị ảnh hưởng tới.
3.2. On top element
Vì các view trong SwiftUI có sự bố cụ và phân cấp. Do đó, thay vì thay đổi nhiều biến môi trường cho nhiều element trong 1 block giao diện. Bạn có thể thay đổi với element lớn nhất. Sau đó, tất cả các thành phần giao diện con của nó đều bị ảnh hưởng.
Ví dụ, bạn thay đổi biến môi trường của VStack để nó ảnh hưởng toàn bộ các Text con ở trong. Bạn tiến hành tuỳ chỉnh thêm đoạn code ở trên như sau:
VStack { ... } .environment(\.colorScheme, .light)
Xem tiếp kết quả như thế nào!
Giải thích:
background
được cài đặt theo giá trị biến môi trường từ Preview. Nên nó có màu đen.- Màu của Text đầu tiên thì vẫn sử dụng màu mặc định. Nên với giá trị từ VStack là
.light
thì nó sẽ hiển thị màu đen.
Bạn thay đổi lại biến Environment .colorScheme
của VStack thành .dark
nha. Chuẩn bị cho ví dụ cuối cùng.
3.3. Cài đặt biến môi trường
Cuối cùng trong việc tìm hiểu về Environment, là bạn có thể thay đổi từng giá trị đặt biệt của đối tượng View. Chúng sẽ ảnh hưởng tới hiển thị của toàn bộ các View con trong đó. Ví dụ, ta hãy thay đổi giá trị Font thay vì dùng font mặc định trong ví dụ trên.
VStack { ... } .environment(\.colorScheme, .dark) .font(Font.subheadline.lowercaseSmallCaps().weight(.light))
Bấm Resume để xem kết quả nào!
Bạn hoàn toàn có thể chỉ định một giá trị cụ thể, như Font để nó áp dụng hiển thị cho toàn bộ các View con. Hoặc chỉ định cho từng view vẫn được. Và với chế độ màu theo dark mode
hay light mode
thì cũng có thể xét riêng. Bạn hãy thay lại với phương thức .colorScheme(.dark)
.
Okay! Gì bạn xem lại toàn bộ code của phần biến môi trường này để có cái nhìn tổng quả nhất.
import SwiftUI struct ContentView: View { @Environment(\.colorScheme) var colorScheme: ColorScheme var body: some View { VStack { Text("Hello, world!") .background(colorScheme == .dark ? Color(.black) : Color(.white)) .padding() Text("Hello again!") .padding() .environment(\.colorScheme, .light) } .colorScheme(.dark) .font(Font.subheadline.lowercaseSmallCaps().weight(.light)) } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() .environment(\.colorScheme, .dark) } }
Tạm kết
- Thay đổi biến môi trường ở Preview để ảnh hưởng toàn bộ View.
- Lấy giá trị biến môi trường để tạo thành một property. Nhằm cài đặt giao diện phù hợp & linh hoạt hơn.
- Xét giá trị biến môi trường
- Cho từng View
- Từng loại thuộc tính
- Ảnh hưởng toàn bộ các View con
Okay! Tới đây, mình xin kết thúc bài viết này. Và nếu có gì thắc mắc hay góp ý cho mình thì bạn có thể để lại bình luận hoặc gởi email theo trang Contact.
Cảm ơn bạn đã đọc bài viết này!
Written by chuotfx
Hãy ngồi xuống, uống miếng bánh và ăn miếng trà. Chúng ta cùng nhau đàm đạo về đời, về code nhóe!
Leave a Reply Cancel reply
Fan page
Tags
Recent Posts
- Charles Proxy – Phần 1 : Giới thiệu, cài đặt và cấu hình
- Complete Concurrency với Swift 6
- 300 Bài code thiếu nhi bằng Python – Ebook
- Builder Pattern trong 10 phút
- Observer Pattern trong 10 phút
- Memento Pattern trong 10 phút
- Strategy Pattern trong 10 phút
- Automatic Reference Counting (ARC) trong 10 phút
- Autoresizing Masks trong 10 phút
- Regular Expression (Regex) trong Swift
You may also like:
Archives
- September 2024 (1)
- July 2024 (1)
- June 2024 (1)
- May 2024 (4)
- April 2024 (2)
- March 2024 (5)
- January 2024 (4)
- February 2023 (1)
- January 2023 (2)
- November 2022 (2)
- October 2022 (1)
- September 2022 (5)
- August 2022 (6)
- July 2022 (7)
- June 2022 (8)
- May 2022 (5)
- April 2022 (1)
- March 2022 (3)
- February 2022 (5)
- January 2022 (4)
- December 2021 (6)
- November 2021 (8)
- October 2021 (8)
- September 2021 (8)
- August 2021 (8)
- July 2021 (9)
- June 2021 (8)
- May 2021 (7)
- April 2021 (11)
- March 2021 (12)
- February 2021 (3)
- January 2021 (3)
- December 2020 (3)
- November 2020 (9)
- October 2020 (7)
- September 2020 (17)
- August 2020 (1)
- July 2020 (3)
- June 2020 (1)
- May 2020 (2)
- April 2020 (3)
- March 2020 (20)
- February 2020 (5)
- January 2020 (2)
- December 2019 (12)
- November 2019 (12)
- October 2019 (19)
- September 2019 (17)
- August 2019 (10)