![Creating UI](https://fxstudio.dev/wp-content/uploads/2022/04/feature_bg_creating_ui-1170x628.jpg)
Contents
Chào mừng bạn đến với Fx Studio. Chủ đề bài viết này là Creating UI trong iOS. Chủ đề xoay quanh các cách mà bạn tạo được giao diện cho ứng dụng của bạn. Bởi vì, giao diện là phần không thể thiếu được trong lập trình ứng dụng iOS. Và định hướng cho các bạn mới học iOS để có được một cái nhìn tổng quan nhất.
Còn nếu mọi việc đã ổn rồi, thì …
Bắt đầu thôi!
Chuẩn bị
Vì đây là một bài viết tổng hợp từ các bài viết cơ bản của iOS & Swift liên quan tới giao diện. Do đó, bạn cũng cần có một lượng kiến thức nhất định về lập trình iOS. Nếu bạn chưa biết gì về lập trình iOS, thì bạn hãy bắt đầu tìm hiểu theo series dưới đây.
Về mặt công cụ, bạn không cần chuẩn bị gì nhiều. Đơn giản là bạn có Xcode là đủ rồi. Ahihi!
Creating UI
Tạo giao diện (Creating UI) của ứng dụng là một công việc bắt buộc khi bạn phát triển một ứng dụng cho người dùng nói chung. Trừ các ứng dụng thiên về xử lý và chạy nền, thì giao diện của nó chính là console. Hiển nhiên, ứng dụng iOS thì không tránh được điều này.
User Interface (UI) là cái mà người dùng thấy đầu tiên. Nó phụ trách 2 nhiệm vụ chính trong ứng dụng:
- Hiển thị dữ liệu cho người dùng
- Nhận tương tác của người dùng
Ngoài ra, UI cũng quyết định việc người dùng có sử dụng ứng dụng của bạn lâu dài không. Vì
Một ứng dụng đẹp thì chưa chắc hay. Nhưng một ứng dụng hay thì phải đẹp.
Và cũng theo truyền thống lập trình từ thời cổ đại tới hiện đại, chúng ta sẽ chia ra trường phái. Đó là:
- Code chay
- Kéo thả
Chúng ta sẽ khám phá tiếp trong mỗi trường phái là có gì và nó phù hợp với công việc gì nhóe.
Code chay
Khi nhắc tới từ “Code chay” thì hầu hết mọi dev đều ngao ngán và tìm cách từ chối. Nhất là khi bạn là một dev thời hiện đại này. Nhưng mọi thứ vẫn đều bắt đầu từ công việc đơn giản này.
Với Code chay, mỗi thành phần (element) trong UI thì là một đối tượng (thuộc framework UIKit là chính). Các đối tượng này cần được tạo ra bằng các dòng code. Và bạn phải tuân theo một quy trình 4 bước như sau:
Ta có thể xem qua một ví dụ sau:
import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. let frame = CGRect(x: 50, y: 100, width: 100, height: 100) let userAvatar = UIImageView(image: UIImage(named: "no_avatar")) userAvatar.frame = frame userAvatar.contentMode = .scaleToFill view.addSubview(userAvatar) } }
Có nghĩa là bạn phải nhớ mọi thứ. Từ các thuộc tính UI tới việc xác định tọa độ và phân cấp trong UI. Ngoài ra, bạn còn phải xác định các ràng buộc với AutoLayout …v…v…
Khá là vất vả!
Nhưng ưu điểm của nó mang lại là:
- Tốc độ chương trình.
- Khá năng tái sử dụng UI rất cao
- Độ ổn định theo thời gian
Bạn có thể tìm hiểu thêm tại bài viết: Basic iOS tutorial : View
Drawing
Công việc nhàm chán tiếp theo nữa và bản chất của nó cũng thuộc việc việc Code chay. Đó là Drawing, hay tên thân thương là Vẽ.
Drawing là công việc bạn sử dụng các API liên quan tới đồ họa, để tạo ra được giao diện mong muốn. Như là: CoreGraphics … Bạn cần phân biết nó với Code chay truyền thống nhóe. Bạn sẽ dùng các hình vẽ cơ bản (hình tròn, vuông, elip, đường thẳng …) kết hợp với nhau để tạo nên các hình phức tạp hơn.
Chúng ta xem qua ví dụ đơn giản để vẽ một đường thẳng nhóe!
func drawLine(start: CGPoint, end: CGPoint) { // PATH let path = UIBezierPath() path.move(to: start) path.addLine(to: end) path.close() //LAYER let shapeLayer = CAShapeLayer() shapeLayer.strokeColor = UIColor.blue.cgColor shapeLayer.lineWidth = 1.0 shapeLayer.path = path.cgPath //ADD LAYER self.view.layer.addSublayer(shapeLayer) }
Về độ phức tạo, Drawing sẽ nhiều hơn rất nhiều. Tuy nhiên, nó phù hợp với các công việc tạo giao diện cần:
- Độ tỉ mĩ, cẩn thận
- Các giao diện mà UIKit không có
- Tương tác với các số liệu nhiều & phức tạp
Bạn có thể tìm hiểu thêm tại bài viết: Basic iOS tutorial : Drawing
Touch Event
Nhiều bạn sẽ bỏ qua phần Touch Event trong việc tạo giao diện. Nếu như vậy thì rất thiếu sót. Vì công việc xác định tương tác của người dùng sẽ ảnh hưởng trực tiếp tới giao diện. Giống như vật lý, khi 1 vật tác động vào một vật khác, thì vật đó mới biến đổi. Do đó, nếu bạn không tác động vào UI thì nó như một bức ảnh tĩnh mà thôi.
Bạn sẽ có các cách sau để xác định sự kiện người dùng trên UI.
- IBAction
- Sử dụng với các đối tượng trong UIKit
- Touch Event
- Đây là các functions mặc định với tất cả các đối tượng trong UIKit
- Gesture Recognizer
- Giúp bạn tùy chỉnh các sự kiện phức tạp (scale, swipe, zoom …) và sử dụng với các đối tượng UIKit & Graphics
Và bạn còn có thể làm nhiều thứ nữa với các sự kiện người dùng này. Bạn có thể xem qua ví dụ sau với việc di chuyển một UIImageView nhóe.
import UIKit class BalllViewController: UIViewController { @IBOutlet weak var ball: UIImageView! override func viewDidLoad() { super.viewDidLoad() } override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { if let touch = touches.first { if touch.view == ball { let location = touch.location(in: view) ball.center = location } } } }
Bạn có thể tìm hiểu thêm tại bài viết: Basic iOS tutorial : Touch Event
Interface Builder
Okay! Đây chính xác là những gì các bạn dev mong đợi. Đó chính là “kéo thả giao diện”. Đơn giản là vì đó chính xác những gì mà các bạn newbiew sẽ tiếp cận đầu tiên trong hành trình khám phá lập trình iOS.
Về Interface Builder, Xcode cung cấp cho bạn rất nhiều UI Control cơ bản. Ví dụ: Button, Label, ImageView … Công việc của bạn đơn giản là:
Kéo & Thả
Chúng sẽ được lưu trữ tại các file *.nib
. Đó là một dạng format xml
, Xcode sẽ đọc qua đoạn mã trong *.xib
và tự tạo nên các đối tượng giao diện tương ứng. Ví dụ: các Button sẽ thành UIButton.
Ưu điểm lớn nhất là lập trình viên sẽ không cần quản lý tất cả các đối tượng có trong *.nib
đó. Nếu bạn thực sự muốn sử dụng đối tượng UI nào hay lấy sự kiện người trên đối tượng UI nào, thì sử dụng
IBOutlet & IBAction
Tiếp theo, Interface Builder sẽ giúp bạn kết nối phần giao diện trực quan kia với các class code, thông qua các Class & File’s owner.
Bạn có thể tìm hiểu thêm tại đây.
Custom View
Có một điều mà bạn sẽ gặp phải, là thiết kế giao diện luôn phức tạp hơn khi so với các đối tượng UI cơ bản mà Xcode cung cấp.
Kẻ thù chính là các dev là các designer.
Do đó, bạn không thể nào áp dụng 100% các giao diện cơ bản để làm giao diện ứng dụng được. Nhưng có một điều khác mà bạn cần ghi nhớ …
Các giao diện phức tạp đều tạo nên từ các giao diện cơ bản.
Công việc Creating UI lúc này, sẽ là việc bạn kết hợp các UI cơ bản như thế nào mà thôi. Xem sơ đồ sau về các con đường tạo giao diện cho 1 Custom view
Ví dụ, code cho việc kết hợp bằng Code chay như sau, để tạo nên một đối tượng UI mới.
import UIKit class MyView: UIView { override init(frame: CGRect) { super.init(frame: frame) backgroundColor = .blue // add user avatar let userAvatar = UIImageView(image: UIImage(named: "no_avatar")) userAvatar.frame = CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height*4/5) userAvatar.contentMode = .scaleAspectFit self.addSubview(userAvatar) // add user name let userName = UILabel(frame: CGRect(x: 0, y: frame.size.height*4/5, width: frame.size.width, height: frame.size.height/5)) userName.text = "Fx Studio" userName.backgroundColor = .lightGray userName.textAlignment = .center userName.textColor = .blue self.addSubview(userName) // add button let button = UIButton(frame: CGRect(x: 0, y: 0, width: frame.size.width, height: frame.size.height)) button.backgroundColor = .clear self.addSubview(button) } required init?(coder: NSCoder) { fatalError("init(coder:) has not been implemented") } }
Bạn sẽ phải sử dụng nhiều kiến thức kết hợp để tạo nên giao diện mới. Sau đó, bạn cần xác định các sự kiện người dùng cho Custom View của bạn. Và bạn có các mối quan hệ liên quan như sau:
Có như vậy, thì bạn mới tạo được một Custom View đầy đủ. Tóm lại, công việc này bao gồm:
- Tạo UI có thể sử dụng code chay & kéo thả
- Tạo sự kiện để xác định tương tác với người dùng
Bạn có thể tìm hiểu thêm tại bài viết: Basic iOS tutorial : Custom View
Bố cục giao diện
Khi báo kéo thả quá nhiều UI Control, hoặc tạo ra quá nhiều các đối tượng giao diện … thì dẫn tới sự phức tạp của giao diện. Điều này làm sự kiểm soát giao diện thật sự vất vả. Do đó, điều tiếp theo bạn làm là tái cấu trúc và bố trí lại giao diện. Chúng ta sẽ dựa vào 2 yếu tố sau:
- SuperView (view cha)
- SubView (các view con)
Ví dụ, với một giao diện cơ bản như trên, thì công việc của bạn sẽ khá vất vả nếu không chia nhóm và phân cấp chúng ra. Cách bạn sẽ làm thì như sau:
- Tất cả sẽ cho vào 1 ScrollView vì chúng có kích thước hơn hơn màn hình.
- Chia thành 3 nhóm chính
- Info (avatar, name, date, descriptions …)
- Follow (các button follow & report)
- Photos (các image)
- Tại mỗi nhóm chính, bạn cố gắng bố cục tiếp các đối tượng trong nó.
Bạn sẽ dễ quản lý các UI khi có sự thay đổi về thiết kế thông qua các View cha lớn. Và bạn có thể tái sử dụng được code khi tạo các nhóm View giống nhau trên cùng một màn hình.
Công việc này sẽ dựa trên kĩ năng quan sát và phân tích của bạn. Hãy luyện tập nó nhiều và bạn sẽ học được cách bố cục hiệu quả nhất.
AutoLayout
Trong Creating UI của iOS thì không thể thiếu AutoLayout. Về định nghĩa:
Auto Layout là hệ thống các ràng buộc (constraint) giữa các thành phần giao diện của chúng ta. Để với một giao diện có thể hiển thị đúng với thiết kế trên các thiết bị có kích thước màn hình khác nhau thì auto layout sẽ hỗ trợ việc đó.
Tại sao nên dùng AutoLayout ?
- Lập trình đơn giản
- Dễ dàng bảo trì ứng dụng
- Đặc biệt rút ngắn được thời gian viết code khi ứng dụng của bạn chạy trên nhiều thiết bị có kích thước màn hình khác nhau
- Áp dụng được cho nhiều nền tảng khác nhau trong hệ sinh thái của Apple
- …
Mình thích thì mình xài thôi.
Với AutoLayout là cả một bầu trời kiến thức và cũng sẽ lấy đi của bạn biết bao nhiêu nước mắt nữa. Bạn có thể kết hợp AutoLayout cho cả 2 phương pháp thiết kế giao diện (code chay & kéo thả).
Bạn có thể tìm hiểu thêm tại bài viết: Basic iOS tutorial : Giới thiệu Auto Layout
StackView
Nếu bạn không có năng khiếu về AutoLayout và cũng chán Code chay. Có rất nhiều vấn đề gặp phải, như:
- Khó khăn khi tạo giao diện bằng
code
chay:- Tính toán
frame
cho phù hợp - Custom view tốn thời gian
- Testing phải build đi build nhiều lần
- Tính toán
- Khó khăn khi tạo giao diện bằng
Auto Layout
:- Khó, khó và khó
Contraints
cũng rất phức tạp- Debugs không ra
- Đôi lúc không hiểu vì sao kéo thả lại được
- Giao diện càng phức tạp thì Auto Layout lại khá là nặng
Thì giải pháp tiếp theo cho bạn trong việc thiết kế & bố cục View trong giao diện là
StackView
StackView thiên về giúp cho bạn phân chia và bố cục các View cha lớn trong cùng một màn hình. Làm giảm đi độ phức tạp của giao diện. Quan trong, nó cung cấp cho bạn nhiều công cụ giúp bạn có thể tùy chỉnh nhanh các View con trong đó. Ví dụ như: chia đều, cách đều khoảng cách, tự động fill …
Bạn có thể tìm hiểu thêm tại bài viết: Basic iOS tutorial : Stack View
Storyboard
Với sự tiến hóa của Apple lại giúp dev càng lười thêm. Và như vậy Storyboard ra đời. Ahihi!
Bảng phân cảnh (Storyboard) là một tính năng thú vị được giới thiệu lần đầu tiên trong iOS 5, giúp tiết kiệm thời gian xây dựng giao diện người dùng cho ứng dụng của bạn. Storyboard cho phép bạn tạo prototype và thiết kế nhiều viewcontroller cho nhiều view trong một file và cũng cho phép bạn tạo chuyển tiếp giữa các viewcontroller.
Không chỉ thiết kế các đối tượng View, mà bạn có thể thiết kế các screen flow từ việc kết hợp các ViewController lại với nhau. Giúp cho công việc Creating UI trở nên trực quan hơn nữa. Nhìn vào file Storyboard, bạn biết được chương trình sẽ hiển thị như thế nào.
Để làm việc với Storyboard được tốt nhất, bạn cần nắm qua 2 điểm lý thuyết cơ bản của nó như sau:
Tuy nhiên, điểm hạn chế của Storyboard lại rất nhiều. Lớn nhất là bạn cần có một máy macOS đủ mạnh để load các file Storyboard. Do đó, nó cũng phù hợp với một số kiểu dự án mà thôi. Bạn cũng nên cân nhắc khi muốn áp dụng nó vào dự án của bạn nhóe!
Tạm kết
Bài viết giới thiệu lại một vòng các vấn đề từ đơn giản tới phức tạp khi bạn tiến hành Creating UI trong iOS. Nói chung là bạn sẽ có 2 phương pháp chính.
- Code chay
- Tạo giao diện bằng code, sử dụng các đối tượng từ UIKit cơ bản
- Vẽ với các API từ CoreGraphis hay các thư viện đồ họa khác
- Kéo thả
- Sử dụng các UI Control vào các file
*.xib
- Dùng Storyboard để thiết kế các screen flow
- Sử dụng các UI Control vào các file
Bên cạnh đó, bạn cần sử dụng thêm các kĩ năng để biến hóa giao diện tốt hơn.
- Custom View (code chay & kéo thả) để tạo các giao diện phức tạp
- Touch Events để quản lý sự kiện người dùng
- Bố cục giao diện để phân cấp các View
- AutoLayout giúp cho thiết kế các View phù hợp với nhiều thiết bị khác nhau
- StackView giúp bố cục đơn giản hơn
Okay! Tới đây, mình xin kết thúc bài viết về Creating UI trong iOS . 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
- 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
- Lập trình hướng giao thức (POP) với Swift
You may also like:
Archives
- 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)