Contents
Đây là bài đầu tiên cho seri hướng dẫn học iOS cơ bản. Kiến thức đủ để cho bạn làm được một ứng dụng iOS đơn giản. Nếu bạn chưa biết về Ngôn ngữ lập trình Swift và Xcode thì có thể tham khảo:
Chuẩn bị
- MacOS 10.14.4
- Xcode 11.0
- Swift 5.1
View là gì?
Đây là một câu hỏi kinh điển, có thể bạn thấy nó đơn giản quá nên bỏ qua. Nhưng càng nắm được cơ bản thì chúng ta mới càng đi xa được.
- View là một hình chữ nhật, có toạ độ và kích thước
- Toạ độ & kích thước của View được gọi là frame
- Có thể nhận các sự kiện từ người dùng tác động vào
- Có sự phân cấp
- Một view thì có nằm trong supper view (view cha) của nó
- Một view có nhiều subview (view con)
- Khởi tạo một view thì có nhiều cách, cơ bản thì:
- Code chay
- Vẽ
- Kéo thả giao diện
- Với khái niệm trên thì ta có 1 view đặc biệt, đó làm UIWindow, mốt số điểm lưu ý như sau:
- Windows không hiển thị nội dung app, tuy nhiên nó cung cấp container cơ bản để chứa views.
- Views định nghĩa phần màn hình mà bạn muốn hiển thị nội dung, ví dụ như hình ảnh, text,…
- Mọi app đều có ít nhất 1 window và 1 view để hiển thị nội dung app.
Như vậy thì, trong iOS, windows và views có nhiệm vụ hiển thị nội dung của app lên màn hình.
Tóm lại:
View là một instance của class UIView (hoặc class con của nó) dùng để quản lý một vùng hình chữ nhật có toạ độ và kích thước trên màn hình của app. View có nhiệm vụ hiển thị nội dung, quản lý các sự kiện chạm của người dùng và quản lý layout của các subviews.
Thuộc tính cơ bản của View
- @property frame
- @property bounds
- @property center
- @property transform
- @property alpha
- @property backgroundColor
- @property contentStretch
Phần này thì không quan trọng lắm, bạn có thể tìm hiểu bằng cách thay đổi giá trị của chúng và quan sát.
Frame & Bounds
Đây là 2 thuộc tính cơ bản đầu tiên mà bạn phải phân biệt được.
- Kiểu dữ liệu
- Đều là
CGRect
- CGPoint : origin –> toạ độ
- CGSize : size –> kích thước
CGPoint
- CGFloat x
- CGFloat y
CGSize
- CGFloat width
- CGFloat height
- Đều là
- Tính chất
- Định nghĩa một vùng chữ nhật có toạ độ và kích thức
- Read-only
- Sự khác nhau
- Frame là đối với hệ toạ độ của
superview
chứa nó - Bounds là đối với hệ toạ độ riêng của nó
- Frame là đối với hệ toạ độ của
Ví dụ:
- bounds
- bounds.origin.x: 0
- bounds.origin.y: 0
- bounds.size.width: 100
- bounds.size.height: 100
- frame
- frame.origin.x: 25
- frame.origin.y: 25
- frame.size.width: 100
- frame.size.height: 100
Tạo giao diện bằng code
- Có nhiều cách tạo 1 view và bắt đầu bằng cách đầu tiên là code chay.
- Ta có quy trình
4 bước
cho việc tạo bất cứ 1 view nào (áp dụng rất nhiều về sau)
- Tham khảo đoạn code chay sau đây:
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) } }
- Phân tích
- Tạo đối tượng
UIImageView
- Xét thuộc tính
image
bằng 1 bức ảnh có tên làno_avatar
- Xác định frame và xét
frame
cho imageview addSubview
vào wiew của ViewController (đó là màn hình của bạn)
- Tạo đối tượng
Bắt sự kiện của View bằng code
- Một trong các sự kiện thì cơ bản nhất và đầu tiên là sự kiện của người dùng
- Một số loại sub-class của UIView đã cài đặt sẵn để có thể bắt được các sự kiện này. ví dụ:
- UIButton
- UISwitch
- UISlider
- …
- Để bắt được sự kiện này thì có 3 điểm quan trọng
target
: chỉ ra view nào bắt được sự kiệnselector
: function thực thi khi sự kiện được bắtstate
: trạng thái hay kiểu cử chỉ của người dùng thao tác lên view
- Tham khảo tiếp đoạn code ví dụ trên
import UIKit class ViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // add user avatar 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) // add user name let userName = UILabel(frame: CGRect(x: 50, y: 200, width: 100, height: 25)) userName.text = "Fx Studio" userName.backgroundColor = .lightGray userName.textAlignment = .center userName.textColor = .blue view.addSubview(userName) // add button let button = UIButton(frame: CGRect(x: 50, y: 100, width: 100, height: 225)) button.backgroundColor = .clear button.addTarget(self, action: #selector(tap), for: .touchDragInside) view.addSubview(button) } @objc func tap() { print("tap tap tap") } }
- Kết quả:
IBOutlet & IBAction
- Việc code tay sẽ rất tốn thời gian với các ứng dụng có giao diện phức tạp.
- Tiêu chí của Apple ngay từ lúc đưa ra iOS & Xcode là chủ trương kéo thả giao diện
- Các file giao diện sẽ có đuôi là
*.xib
- Nếu dùng storyboard thì sẽ là
*.storyboard
- Nếu dùng storyboard thì sẽ là
- Chúng thực chất là các file
xml
- Các thành phần giao diện sẽ được load từ xml thành các đối tượng cụ thể.
IBOutlet
- Khái niệm: Khai báo quyền sở hữu của ViewController với một hay nhiều phần tử trên giao diện (file *.xib)
- Các bước tạo IBOutlet
- Mở file *.xib hoặc *.storyboard và kéo thả các control cơ bản
-
- Thay đổi thuộc tính của control bên tab
inspectors
- Thay đổi thuộc tính của control bên tab
-
- Mở phần giao diện code bằng cách kích vào
Assistant
- Mở phần giao diện code bằng cách kích vào
-
- Kích chuột phải vào control và kéo thả vào phần code
-
- Đặt tên và bấm
connect
- Thay đổi thuộc tính bằng code
- Đặt tên và bấm
@IBOutlet weak var titleLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() //set title titleLabel.text = "Fx Studio" // .... }
- Bạn có thể dùng cách ngược lại
- Khai báo 1 IBOutlet với từ khoá IBOutlet
- Ví dụ: cho 1 UILabel
@IBOutlet weak var titleLabel: UILabel!
-
- Kéo thả vào control đang có trên file giao diện
Outlet Collection
- Dùng để liên kết và quản lý 1 số view tương tự nhau hoặc cùng chung thực hiện 1 chức năng hay hiện thị 1 nội dung cụ thể.
- Là 1 array kiểu dữ liệu tuỳ thuộc vào đối tượng View được liên kết tới.
- Đối tượng sử dụng
- Dùng cho các bài toán xử lý giao diện nhiều
- Dùng cho các bạn mới code hoặc không quen thao tác với UI bằng code
IBAction
- Khái niệm: Phương thức bên trong ViewController nhằm nhận sự kiện của người dùng khi tác động lên giao diện
- Cách tạo cũng tương tự như IBOutlet, nhưng đối với các control có sẵn việc bắt sự kiện người dùng
- UIButton
- UISwitch
- UISlider
- …
- Hoặc có thể làm ngược lại
- Viết function với từ khoá
@IBAction
- Và kéo thả vào control trong file giao diện
- Viết function với từ khoá
Tới đây thì bạn đã tìm hiểu xong cơ bản về View trong iOS. Việc 1 giao diện phức tạp đến đâu thì nó cũng được tạo thành từ nhiều View đơn giản hơn. Nên nắm được cơ bản thì sẽ làm được các phần phức tạp hơn. Chúc bạn thành công!
Tham khảo video demo IBOutlet & IBAction.
Tạm kết
- Biết được View là gì
- Frame & Bounds
- IBOutlet & IBAction
- Tạo giao diện bằng code & kéo thả
- Bắt sự kiện bằng code và kéo thả
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
- Phù thủy phiên dịch ý tưởng
- XML Delimiters – Mở khóa thế giới prompt phức tạp
- Instructions – Cung cấp hướng dẫn cho các Gen AI
- 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
You may also like:
Archives
- January 2025 (5)
- 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)