Skip to content
  • Home
  • Code
  • iOS & Swift
  • Combine
  • RxSwift
  • SwiftUI
  • Flutter & Dart
  • Tutorials
  • Art
  • Blog
Fx Studio
  • Home
  • Code
  • iOS & Swift
  • Combine
  • RxSwift
  • SwiftUI
  • Flutter & Dart
  • Tutorials
  • Art
  • Blog
Written by chuotfx on May 24, 2021

Image View trong 10 phút – SwiftUI Notes #26

SwiftUI

Contents

  • Chuẩn bị
  • Image View
  • 1. Display Image
    • 1.1. Assets
    • 1.2. SF Symbols
  • 2. Change size
    • 2.1. Resize-able
    • 2.2. Tiled resizing
    • 2.3. Scale
    • 2.4. Frame
  • 3. Full screen & Safe area
    • 3.1. Full screen
    • 3.2. Safe area
  • 4. Image as a backgrounds
  • 5. Make color
    • 5.1. cornerRadius
    • 5.2. overlay
    • 5.3. background
    • 5.4. clipShape
    • 5.5. foregroundColor
  • Tạm kết

Chào mừng bạn đến với Fx Studio và hành trình của series SwiftUI Notes bất tận này. Bài viết này sẽ tập trung vào một đối tượng View cơ bản mà có mặt ở hầu hết các nền tảng. Đó là Image View (hay gọi là Image) trong SwiftUI.

Nếu mọi thứ đã ổ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:

    • Làm quen với SwiftUI
    • Cơ bản về ứng dụng SwiftUI App

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.)

Image View

An image is worth a thousand words.

Image chính là cách mà bạn có thể truyền tải đi rất nhiều thông điệp bằng một cách đơn giản nhất. Vì vậy, trong giao diện bạn nên tận dụng chúng một cách tối đa nhất. Và Image cũng là một thành phần không thể nào thiếu được trong bất cứ thiết kế UI nào cho bất kì nền tảng nào.

Trong SwiftUI, đối tượng hiển thị cho một hình ảnh là Image. Chắc bạn cũng quá quen thuộc với nó rồi và như trước đây với iOS chúng ta có UIImageView vậy. Hình ảnh có thể lấy được từ nhiều nguồn. Ví dụ:

  • Các ảnh được lưu trữ thành tài nguyên trong Assets
  • Các đối tượng từ các nền tảng khác của Apple như NSImage và UIImage
  • Một ảnh dưới dạng bitmap được thể hiện bằng CGImage của Core Graphics
  • Những icon & ảnh hệ thống, trong bộ sưu tập SF Symbols
  • …

Và bây giờ, chúng ta sẽ bắt đầu tìm hiểu xem Image trong SwiftUI như thế nào và có gì đặc biệt nha.

1. Display Image

Mọi việc bắt đầu bằng hiển thị một ảnh. Chúng ta sẽ sử dùng 2 nguồn chính, đó là lưu trữ trong Assets và ảnh hệ thống. Các nguồn khác như từ một URL nào đó hay ảnh động thì chúng ta sẽ bàn ở một bài viết khác nha.

1.1. Assets

Trước tiên, bạn hãy tạo mới một file SwiftUI View, đặt tên gì cũng được. Chúng ta sẽ có code mặc định được tạo kèm với file đó. Bạn hãy thay Text bằng Image, theo ví dụ sau:

var body: some View {
    Image("cat")
}

Trong đó, mình sử dụng 1 ảnh được lưu trong file Assets.xcassets. Cú pháp của Image thì khá là đơn giản, tham số là String, tên của ảnh được lưu trong Assets.

Bạn bấm Resume và xem kết quả Preview nha!

Image View

 

Sử dụng hình mèo cho tăng tương tác thôi. Ahihi!

1.2. SF Symbols

Hình ảnh hay các icon trong hệ thống, thì được Apple cung cấp. Với việc bạn chỉ cần download thêm bộ sưu tập SF Symbol, thì bạn có trong tay hơn 1000 icon khác nhau các loại. Và đôi khi chúng ta gọi nó là ảnh hệ thống.

(Link download tại đây)

Bạn sẽ tiết kiệm đi rất nhiều thời gian cho việc thiết kế ứng dụng của mình, bằng cách tận dụng những icon này. Và ưu điểm của chúng nó là dưới dạng vector nên bạn có thể thoải mái về kích thước cho các icon này mà không sợ vỡ hình.

Bạn hãy tìm 1 cái tên trong đám icon đó, và sửa lại đoạn code trên như sau:

Image(systemName: "tornado")

Để hiển thị ảnh hệ thống, ta chọn hàm khởi tạo Image với tham số label là systemName là được. Xem thử nó hiển thị như thế nào.

Image View

Bạn sẽ thấy cái hình nhỏ xí xi ở chính giữa màn hình đó. Để cho nó to lên thì chúng ta sẽ đi qua phần tiếp theo.

2. Change size

Đây chính là điều khó chịu đầu tiên khi bạn sử dụng Image View trong SwiftUI. Đó chính là kích thước của Image. Bạn hãy xem lại ví dụ hình mèo dễ thương của mình.

Cái viền màu xanh là biểu thị cho kích thước thật của ảnh chúng ta. Nó khá là lớn so với màn hình điện thoại. Chúng ta sẽ fix nó ngay thôi.

2.1. Resize-able

Sai lầm thứ 2 nữa của chúng ta hay quên đi. Đó là

Tất cả chỉ là View

Với hình trên, nó không phải kích thước View là kích thước màn hình. Mà màn hình điện thoại đó chỉ là khung hình để xem mà thôi. Nó không liên quan gì tới kích thước của Image.

Sau khi đọc qua 2 sai lầm cơ bản. Thì công việc của bạn chỉ còn là biến:

Image từ không thể thay đổi kích thước thành có thể thay đổi được kích thước

Bạn chỉ cần thêm một modifier .resizable() vào sau Image là ổn.

Image("cat")
    .resizable()

Xem kết quả nào!

Với tính năng đó thì ảnh của bạn sẽ auto resize vừa với kích thước chứa của View.

2.2. Tiled resizing

Một trò khá là vui cho Image View đến từ SwiftUI. Bạn hãy tìm một ảnh với kích thước nhỏ, và dùng đoạn code sau để hiển thị chúng.

Image("star")
    .resizable(resizingMode: .tile)

Trong đó,

  • star là ảnh với kích thước 50x50px
  • Vẫn là việc resize nhưng với kích thước ảnh nhỏ hơn View chưa thì sẽ dùng chế độ lặp lại nó
  • Sử dụng tham số resizingMode: .tile để fill ngôi sao đó cho toàn bộ màn hình

Xem kết quả nào!

Image View

Khá là đẹp cho Image View phải không nào, bạn nào có ý tưởng làm các background cute thì chừ quá đơn giản rồi đó.

Ngoài ra, với Tiled resizing này còn có nhiều tham số nữa, bạn hãy tự khám phá thêm nha. Ví dụ như sau, để thay đổi index của ảnh sao cho đẹp nhất với từng vị trí xác định.

.resizable(
                capInsets: .init(
                    top: 30,
                    leading: 30,
                    bottom: 30,
                    trailing: 30
                ),
                resizingMode: .tile
        )

2.3. Scale

Bạn nhìn lại hình mèo dễ thương ở trên sau khi resize, bạn cũng cảm nhận ảnh bị bóp méo đi. Vậy muốn ảnh đẹp hơn thì chúng ta cũng phải chọn đúng chế độ khi scale ảnh. Và bạn có 2 chế độ cơ bản sau:

  • fit

Ta lại có 2 cách dùng với chế độ fit. Bạn tham khảo code sau:

Image("cat")
    .resizable()
    .aspectRatio(contentMode: .fit)

Hoặc

Image("cat")
    .resizable()
    .scaledToFit()

Xem kết quả mèo dễ thương nào!

  • fill

Với chế độ fill cũng tương tự, ta cũng có 2 cách để sử dụng chế độ này

Image("cat")
            .resizable()
            .aspectRatio(contentMode: .fit)

Hoặc

Image("cat")
    .resizable()
    .scaledToFill()

Xem kết quả mèo dễ thương nào!

Image View

Tuy nhiên, với modifier .aspectRatio bạn sẽ có nhiều khám phá hơn. Không chỉ là 2 chế độ đơn giản như vậy.

Ví dụ: ta sử dụng tỉ lệ scale cho 2 kích thước của ảnh như sau:

Image("cat")
    .resizable()
    .aspectRatio(0.7, contentMode: .fill)

Kết quả nè!

Khung hình màu xanh đã nhỏ đi khá nhiều rồi.

2.4. Frame

Nếu như tất cả vẫn chưa thỏa mãn được bạn và bạn vẫn muốn Image View có một kích thước xác định nào đó. Thì hãy sử dụng:

  • Modifier .frame để xác định kích thước
  • SwiftUI đủ thông minh để có thể tính toán các tham số kích thước, ngay khi bạn cung cấp không đầy đủ tham số truyền vào.
  • Xác định width hay height hay cả 2 đều được
  • Xác định kích thước min hay max cho 2 chiều

Tham khảo code ví dụ cho mèo dễ thương tiếp nha.

Image("cat")
    .resizable()
    .scaledToFit()
    .frame(width: 300)

Lúc này mèo dễ thương trông nhỏ nhắn xinh đẹp rồi!

3. Full screen & Safe area

3.1. Full screen

Tới đây, nhiều bạn cùng gặp chung một vấn đề là: “làm thế nào để ảnh full màn hình?”. Khi mà SwiftUI rất linh hoạt và có thể build được lên nhiều thiết bị. Do đó, việc xác định kích thước màn hình chính xác thì rất khó. Bên cạnh đó …

Chúng ta đã nói lời chia tay với AutoLayout rồi. Ahuhu!

Nhưng mà ông trời không tuyệt đường sống của ta bao giờ. Khi Apple cung cấp cho bạn một giá trị là .infinity để dùng làm đối số truyền vào cho các tham số width & height trong modifier .frame. Bạn thử xem đoạn code sau với mèo dễ thương nha.

Image("cat")
    .resizable()
    .frame(width: .infinity, height: .infinity)

Kết quả ra như sau nhoé!

3.2. Safe area

Mình đã cố tình sử dụng simulator là iPhone 12 để cho có phần tai thỏ. Và bạn cũng dễ dàng thấy được 2 khoảng trắng 2 đầu rồi.

Nguyên nhân chính là Safe area của các đời iPhone X. Đây là vùng an toàn để bạn thiết kế giao diện. Với AutoLayout bạn cũng phải kéo thả constraint và ràng buộc chúng với Safe area. Thì SwiftUI cũng như vậy.

Để giúp bạn thoả mãn 100%, thì chúng ta sẽ bỏ qua phần Safe area này, bạn chỉ cần thêm modifier .ignoresSafeArea() vào là mọi thứ ổn ngay.

Image("cat")
    .resizable()
    .ignoresSafeArea()
    .frame(width: .infinity, height: .infinity)

Ở trên, mình thêm vào đoạn code ví dụ mèo dễ thương. Kết quả sẽ như thế này nè!

Image View

Hài lòng mọi người chưa!

4. Image as a backgrounds

Một công dụng phải nói nhức nách nữa của Image chính là làm hình nền. Vì hầu như mọi developer đều đã sử dụng ảnh làm background cho View, Button, NavigationBar … Do đó, mình xin mạn phép đưa vào luôn bài viết này.

Ngoài ra, cũng giúp cho các bạn thấy được sự đa năng của SwiftUI như thế nào. Khi mà background nó cũng xem là một View. Bạn có thể làm mọi thứ với nó. Xem ví dụ code mèo dễ thương tiếp là được.

HStack {
    Text("Mèo dễ thương! Moa moa")
        .font(.largeTitle)
        .fontWeight(.heavy)
        .foregroundColor(Color.white)
    }
    .background(
        Image("cat")
            .resizable()
            .scaledToFill()
            .edgesIgnoringSafeArea(.all)
            .frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
            
    )

Trong đó:

  • Đối tượng chính là một Text
  • Tại modifier .background ta cung cấp cho nó là một Image
  • Tuỳ theo sở thích của bạn mà bạn tuỳ biến Image đó thành một Background đẹp cho Text

Bạn xem kết quả nhoé!

Image View

5. Make color

Chúng ta sang phần làm màu cho đối tượng Image nào. Lưu ý, đây chỉ là những modifier hay sử dụng mà thôi. Chứ không phải là tất cả nha. Mục đích là giúp bạn tham khảo một tí.

Chúng ta sẽ bắt đầu từ đoạn code này nha.

Image("cat")
    .resizable()
    .frame(width: 300, height: 300)

5.1. cornerRadius

Đây cũng là một trong các modifier phổ biến nhất. Bạn sử dụng .cornerRadius để bo tròn một View hay Image View. Code ví dụ như sau:

Image("cat")
    .resizable()
    .frame(width: 300, height: 300)
    .cornerRadius(30.0)

Xem kết quả nhoé!

Còn bạn muốn cho Image của bạn thành hình tròn thì sử dụng cứ truyền cho tham số của .cornerRadius với một nữa của width là đẹp ngay.

Image("cat")
    .resizable()
    .frame(width: 300, height: 300)
    .cornerRadius(150.0)

Xem tiếp kết quả mèo dễ thương nha!

5.2. overlay

Modifier .overlay thì bạn có thể thêm những nội dung lên trên đối tượng View. Và Image View cũng không ngoại lệ. Sẽ rất thú vị, SwiftUI khá linh hoạt phải không nào. Bạn có thể thêm bất cứ View nào vào cũng được.

Xem code ví dụ với việc sử dụng .overlay cho Image là một Text nha.

Image("cat")
    .resizable()
    .frame(width: 300, height: 300)
    .cornerRadius(30.0)
    .overlay(
        Text("Mèo dễ thương")
            .foregroundColor(Color.white)
            .padding([.bottom, .trailing], 10)
            .opacity(0.8),
             alignment: .bottomTrailing
    )

Trong đó

  • Content của .overlay chính là một Text
  • Cần thêm tham số alignment để xác định vị trí của overlay
  • .bottomTrailing sẽ là góc dưới bên phải của View
  • Các modifier khác bạn tự tìm hiểu nha, cũng không quá khó lắm

Bạn xem kết quả nhoé!

Image View

5.3. background

Modifier .background thì quá bình thường rồi. Bạn sẽ phủ màu hoặc cái gì đó làm hình nền cho Image. Nó có tác dụng khi ảnh của bạn trong suốt. Hoặc khi bạn load ảnh từ một URL nào nó, trong lúc chờ kết nối mạng …. cũng rất nhiều ứng dụng với modifier này.

Còn bây giờ, bạn xem qua code ví dụ với mèo dễ thương ở trên nha. Mình có thay đổi giá trị radius để bo tròn lớn hơn. Giúp bạn nhìn rõ đc background color.

Image("cat")
    .resizable()
    .frame(width: 300, height: 300)
    .cornerRadius(50.0)
    .overlay(
        Text("Mèo dễ thương")
            .foregroundColor(Color.white)
            .padding([.bottom, .trailing], 10)
            .opacity(0.8),
             alignment: .bottomTrailing
    )
    .background(Color.green)

Xem kết quả luôn nhoé!

5.4. clipShape

Modifier .clipShape này sẽ cắt Image của chúng ta theo 1 hình dạng nào đó mà ta cung cấp. Mình sẽ thực hiện với hình cắt là hình tròn cho Image ở trên. Xem ví dụ code nào.

Image("cat")
    .resizable()
    .frame(width: 300, height: 300)
    .cornerRadius(50.0)
    .overlay(
        Text("Mèo dễ thương")
            .foregroundColor(Color.white)
            .padding([.bottom, .trailing], 10)
            .opacity(0.8),
             alignment: .bottomTrailing
    )
    .background(Color.green)
    .clipShape(Circle())

Khá là đơn giản khi truyền tham số là một đối tượng Circle(). Xem kết quả nhoé!

5.5. foregroundColor

Cái này áp dụng cho các Image hệ thống nha. Nó như tintColor vậy. Bạn có thể xét màu của Image View giống như màu chữ của Text thông qua modifier .foregroundColor. Rất nhanh và rất tiện lợi!

Bạn xem ví dụ mới của mình như sau:

VStack {
    Image(systemName: "star")
        .resizable()
        .frame(width: 80.0, height: 80.0)
        .foregroundColor(.blue)
    
    Image(systemName: "star")
        .resizable()
        .frame(width: 80.0, height: 80.0)
        .foregroundColor(.green)
    
    Image(systemName: "star")
        .resizable()
        .frame(width: 80.0, height: 80.0)
        .foregroundColor(.red)
    
    Image(systemName: "star")
        .resizable()
        .frame(width: 80.0, height: 80.0)
        .foregroundColor(.orange)
    
    Image(systemName: "star")
        .resizable()
        .frame(width: 80.0, height: 80.0)
        .foregroundColor(.yellow)
}

Sử dụng Image hệ thống, với đầy đủ màu sắc khác nhau cho mỗi Image. Xem kết quá nhoé!

Image View

Tạm kết

Qua trên, mình đã trình bày những thứ cơ bản liên quan tới Image của SwiftUI. Và chúng chỉ mang tính chất cơ bản mà thôi. Quan trọng bạn cần nhớ đến modifier .resizable() là được. Vì tất cả các thao tác tới Image sẽ chính xác hơn khi Image có thể thay đổi được kích thước.

 

Okay! Tới đây, mình xin kết thúc bài viết về đối tượng Image 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.

  • Bạn có thể checkout code tại đây.
  • Bài viết tiếp theo tại đây.

Cảm ơn bạn đã đọc bài viết này!

FacebookTweetPinYummlyLinkedInPrintEmailShares0

Related Posts:

  • Reusable View - SwiftUI Notes #10
    Reusable View - SwiftUI Notes #10
  • Sử dụng Custom UIView vào SwiftUI Project - SwiftUI Notes #16
    Sử dụng Custom UIView vào SwiftUI Project - SwiftUI Notes…
  • Creating your UI - SwiftUI Notes #2
    Creating your UI - SwiftUI Notes #2
  • Text View trong 10 phút - SwiftUI Notes #25
    Text View trong 10 phút - SwiftUI Notes #25
Tags: SwiftUI, SwiftUI Notes
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

Your email address will not be published. Required fields are marked *

Donate – Buy me a coffee!

Fan page

Fx Studio

Tags

Actor Advanced Swift api AppDistribution Asynchronous autolayout basic ios tutorial blog callback ci/cd closure collectionview combine concurrency CoreData Core Location crashlytics darkmode dart dart basic dart tour Declarative decoding delegate deploy fabric fastlane firebase flavor flutter GCD iOS mapview MVVM optional protocol rxswift Swift Swift 5.5 SwiftUI SwiftUI Notes tableview testing TravisCI unittest

Recent Posts

  • Raw String trong 10 phút
  • Dispatch Semaphore trong 10 phút
  • Tổng kết năm 2022
  • KeyPath trong 10 phút – Swift
  • Make color App Flutter
  • Ứng dụng Flutter đầu tiên
  • Cài đặt Flutter SDK & Hello world
  • Coding Conventions – người hùng hay kẻ tội đồ?
  • Giới thiệu về Flutter
  • Tìm hiểu về ngôn ngữ lập trình Dart

You may also like:

  • Presenting an Alert - SwiftUI Notes #4
    Presenting an Alert - SwiftUI Notes #4
  • Reusable View - SwiftUI Notes #10
    Reusable View - SwiftUI Notes #10
  • Extracting subview - SwiftUI Notes #5
    Extracting subview - SwiftUI Notes #5
  • Tích hợp SwiftUI vào UIKit Project - SwiftUI Notes #13
    Tích hợp SwiftUI vào UIKit Project - SwiftUI Notes #13
  • SwiftUI App Life Cycle - SwiftUI Notes #6
    SwiftUI App Life Cycle - SwiftUI Notes #6

Archives

  • 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)

About me

Education, Mini Game, Digital Art & Life of coders
Contacts:
contacts@fxstudio.dev

Fx Studio

  • Home
  • About me
  • Contact us
  • Mail
  • Privacy Policy
  • Donate
  • Sitemap

Categories

  • Art (1)
  • Blog (22)
  • Code (4)
  • Combine (22)
  • Flutter & Dart (24)
  • iOS & Swift (86)
  • RxSwift (37)
  • SwiftUI (76)
  • Tutorials (70)

Newsletter

Stay up to date with our latest news and posts.
Loading

    Copyright © 2023 Fx Studio - All rights reserved.

    Share this ArticleLike this article? Email it to a friend!

    Email sent!