Contents
Chào bạn đến với Fx Studio. Chúng ta lại quay lại hành trình bất tận SwiftUI. Các bài viết trước thì bạn đã tìm hiểu về các UI Control cơ bản và kinh điển trong SwiftUI rồi. Bây giờ, chúng ta sẽ đi sang các UI Controls liên quan tới bố cục (layout). Đó là các Stack trong SwiftUI.
Nếu bạn chưa biết gì về Stack, thì mình đã có một bài viết các Stacks View. Bạn có thể đọc thêm tại đây. Và nếu mọi việc đã ổn rồi thì …
Bắt đầu thôi!
Chuẩn bị
Về mặt tool và version, các bạn tham khảo như sau:
-
- SwiftUI 2.0
- Xcode 12
Về mặt kiến thức, bạn cần biết trước các kiến thức cơ bản với SwiftUI & SwiftUI App. Tham khảo các bài viết sau, nếu bạn chưa đọc qua SwiftUI:
Về mặt demo, hầu như là demo đơn giản, vì tập trung vào từng View riêng lẻ. Do đó, bạn cũng không cần phải quá lo lắng và việc tạo mới project cũng không ảnh hưởng gì nhiều. Ngoài ra, bạn có thể checkout mã nguồn của các bài viết tại đây.
(Mặc định, mình xem như bạn đã biết về cách tạo project với SwiftUI & SwiftUI App rồi.)
1. HStack & VStack
1.1. Định nghĩa
Về định nghĩa các Stack, bạn hãy xem ở bài viết cơ bản này. Bây giờ, chúng ta sẽ chỉ nói về một số đặc điểm mới và kết hợp với Layout giữa chúng.
HStack & VStack tuy 2 đối tượng SwiftUI View khác nhau, nhưng về bản chất lại giống nhau. Khác nhau duy nhất ở chỗ hướng sắp xếp items trong chúng:
- HStack sắp xếp các items theo chiều ngang
- VStack sắp xếp các item theo chiều dọc
Với UIKit, chúng ta có người anh em UIStackView, nó cũng khá là tương tự với 2 Stack kia. Việc định hướng các items dựa theo thuộc tính axis
.
1.2. Khởi tạo
Ta hãy sử dụng các Stack này, mà ít khi khám phá xem nó có những gì. Hầu như ta chỉ đặt các View vào giữa 2 dấu { }
mà thôi. Bây giờ, ta xem hàm khởi tạo của chúng có gì.
// HStack init( alignment: VerticalAlignment = .center, spacing: CGFloat? = nil, @ViewBuilder content: () -> Content ) // VStack init( alignment: HorizontalAlignment = .center, spacing: CGFloat? = nil, @ViewBuilder content: () -> Content )
Trong đó:
content
chính là cái thứ mà bạn hay đặt đám View vào giữa 2 dấu{ }
. Kiểu của nó là@ViewBuilder
alignment
là căn chỉnh theo chiều ngang hay chiều dọc cho HStack hoặc VStack. Mặc định sẽ là.center
cho cả 2spacing
khoảng cách giữa các phần tử. Mặc định lànil
, Stack sẽ hiển thị khoảng cách dựa theo nền tảng. Muốn không có khoảng cách thì gán bằng0
1.3. alignment
Cũng là khá phong phú cho cách hiển thị với thuộc tính alignment
này. Với VStact, bạn có .center
, .leading
, .trailing
. Đối với HStack, sẽ phong phú hơn nhiều thêm một tí. Ngoài .center
, .top
và .bottom
thì có thêm:
firstTextBaseline
: Căn chỉnh các chế độ xem dựa trên chế độ xem đường cơ sở văn bản trên cùng.lastTextBaseline
: Căn chỉnh các chế độ xem dựa trên chế độ xem đường cơ sở dưới cùng của văn bản.
Hi vọng bạn tận dùng được tối đa sức mạnh của chúng trong việc bố cục các văn bản mà có sự khác nhau giữa các font chữ và kích thước font chữ ….
Ta xem qua một chút ví dụ cho nó có màu mè trực quan xí.
var body: some View { HStack(alignment: .top) { Text("Welcome to Fx Studio").font(.caption) Text("Welcome to Fx Studio").font(.title) Button(action: {}, label: { Text("OK").font(.body) }) } }
Xem qua kết quả của nó tí nha.
Để ý thật kĩ, bạn sẽ thấy điều kì diệu nhoé! Mặc dù ta để chế độ .top
, tuy nhiên phần tử View ở giữa lại cách mép trên 1 đoạn. Và các phần tử nhìn lồi lõm rất khó chịu phải không nào. Bạn chỉ cần thay đổi từ .top
thành .firstTextBaseline
.
var body: some View { HStack(alignment: .firstTextBaseline) { Text("Welcome to Fx Studio").font(.caption) Text("Welcome to Fx Studio").font(.title) Button(action: {}, label: { Text("OK").font(.body) }) } }
Xem kết quả nhoé!
Chúng nó đã ở cùng trên 1 dòng rồi. Mặc dù font chữ & size khác nhau. Đẹp rồi á!
2. ZStack
Với đối tượng ZStack này thì là đặc trưng riêng của SwiftUI. UIKit không có đối tượng tương tự như vậy. ZStack này có gì:
- Các View con được xếp chồng lên nhau
- View con đầu tiền sẽ ở dưới cùng
- Các View vào sau sẽ ở trên các View vào trước
.layoutPriority
sẽ không ảnh tới thứ tự ưu tiên của Layout
Về kích thước của ZStack sẽ được xác định dựa vào kích thước view con lớn nhất.
Về ứng dụng của Stack được dùng nhiều nhất cho việc xếp chồng các View lên với nhau. Bạn xem qua ví dụ sau nha.
ZStack (alignment: .bottom) { VStack(spacing: 0) { Rectangle() .frame(height: 90) .foregroundColor( Color(red: 84.0/255.0, green: 61.0/255.0, blue: 1).opacity(1.0)) Rectangle() .frame(height: 90) .foregroundColor( Color(red: 84.0/255.0, green: 32.0/255.0, blue: 46.0/255.0).opacity(1.0)) } Image("logo") .resizable() .frame(height: .infinity) .scaledToFit() .clipShape(Circle()) .padding() VStack { Spacer() Text("Welcome to") .font(.body) .foregroundColor(.white) Text("Fx Studio") .font(.largeTitle) .foregroundColor(.white) .fontWeight(.bold) .shadow(radius: 7) } .padding() } .frame(height: 180)
Trong ví dụ trên, ý đồ sẽ là:
- 2 View làm màu nền cho cả View lớn
- 1 Image sẽ là logo và xếp chồng lên 2 View nền
- 2 Text sẽ ở trên Image
Xem kết quả nhoé! Bạn hãy cố suy nghĩ cách hiển thị giữa các Stack ngay trong đầu mình và đối chiếu với kết quả xem có giống với ý đồ của mình hay không.
Chúng ta thực hiện đè lên nhau giữa Image logo và các Text.
3. Các containers khác
Trong SwiftUI, ngoài các nhóm View cơ bản (là View mà không chứa các View nào nữa) thì chúng ta có các View được gọi là Container (là View mà chứa được nhiều View).
Ở phần trên, bạn đã khám khá các Container là Stacks View. Tuy nhiên, vẫn còn nhiều loại khác mà bạn cảm thấy bất ngờ.
(Mình chỉ ví dụ vài loại cơ bản mà thôi.)
3.1. Button
Đối tượng này khác là đơn giản. Tuy nhiên, chúng ta dùng hàm khởi tạo như đoạn code ví dụ sau:
Button(action: {}, label: { HStack { Image(systemName: "checkmark") .font(.largeTitle) Text("OK") .font(.largeTitle) .fontWeight(.bold) } .kute() .padding() })
Trong đó, label
là một. ViewBuilder. Và bạn có thể thêm nhiều loại View vào đây. Nếu chúng nó là một. Stacks View thì lại có thể chứa thêm nhiều View con nữa. Đúng là khá thú vị phải không nào.
Xem kết quả nhoé!
3.2. Alert
Cũng tương tự như Button, với. Alert thì ta lại có nhiều tham số với kiểu dữ liệu là @ViewBuilder
. Do đó, đối tượng View này cũng chứa nhiều hơn một View. Nhưng nó không thực sự là một Stack View.
Ví dụ code thì đơn giản như sau:
VStack { // ...... } .alert(isPresented: $isAlert: { Alert(title: Text("Fx Studio"), message: Text("Hello world!"), dismissButton: .default(Text("Got it!")) ) })
Vẫn còn nhiều loại. Containers khác, tuy nhiên mình chỉ giới thiệu đại diện với 2 đối tượng là. Button &. Alert thôi. Các bạn từ từ khám phá sau nhoé.
Tạm kết
- Bài viết chỉ nhắc lại các kiến thức về các Stack.
- Giải thích thêm vào các tham số của mỗi loại.
- Giới thiệu thêm vài đối tượng Containers khác hoặc được xem là containers
Okay! Tới đây, mình xin kết thúc bài viết về đối tượng Stack & Container trong SwiftUI. 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!
Related Posts:
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
- SMART – Hướng dẫn dành tạo Prompt cho người mới bắt đầu
- Nhìn lại năm 2024
- CO-STAR – Công thức vàng để viết Prompt hiệu quả cho LLM
- Prompt Engineering trong 10 phút
- Một số ví dụ sử dụng Prompt cơ bản khi làm việc với AI
- Prompt trong 10 phút
- 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
You may also like:
Archives
- January 2025 (2)
- December 2024 (4)
- 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)