Tìm hiểu về Transform - thuộc tính của UIView với Swift 4

Core Animation là engine tạo ra các nội dung trực quan trên màn hình, và nó có nhiệm vụ làm điều đó càng nhanh càng tốt. Các nội dung được chia thành lớp (layer) riêng biệt và được lưu trữ trong một hệ thống được gọi là cây lớp (layer tree). Cây này hình thành nền tảng cho tất cả các đối tượng UIKit, và cho tất cả mọi thứ mà bạn nhìn thấy trên màn hình trong một ứng dụng iOS.

Trong iOS, tất cả các lớp giao diện đều được kế thừa từ lớp cơ sở chung UIView. UIView xử lý các sự kiện chạm và hỗ trợ các hàm vẽ dựa trên Core Graphics, các phép biến hình và các ảnh động.

UIView có thuộc tính transform có kiểu là CGAffineTransform cho phép xoay đối tượng, phóng to, thu nhỏ và dịch chuyển.CGAffineTransform là một ma trận 2 cột, 3 dòng có thể nhân với một vector 2D (CGPoint) để thay đổi giá trị của nó.

Phép nhân được thực hiện bằng cách nhân từng giá trị trong vector CGPoint mới. Với giá trị trong ma trận CGAffineTransform, kết quả cuối cùng sẽ tạo ra một CGPoint mới.

Core Graphics cung cấp các hàm cho phép biến đổi đối tượng:

CGAffineTransform(a: CGFloat, b: CGFloat, c: CGFloat, d: CGFloat, tx: CGFloat, ty: CGFloat)
CGAffineTransform(from: Decoder)throws
CGAffineTransform(rotationAngle: CGFloat)
CGAffineTransform(scaleX: CGFloat, y: CGFloat)
CGAffineTransform(translationX: CGFloat, y: CGFloat)

Chúng ta hãy thử bằng ví dụ đơn giản: khi currentAnimation có giá trị là 0, thì biến đổi khung hình nhìn gấp đôi kích thước thật của nó. Đoạn mã sẽ như sau:

switch self.currentAnimation {
case 0:
    self.imageView.transform = CGAffineTransform(scaleX: 2, y: 2)

default:
    break
}

Điều này sẽ sử dụng một trình khởi tạo cho CGAffineTransform lấy giá trị tỷ lệ X và Y là 2 tham số. Giá trị 1 được hiểu như "kích thước mặc định", vì vậy 2, 2 sẽ làm cho chế độ xem gấp đôi chiều rộng và chiều cao của hình ban đầu.

Chạy ứng dụng để thấy kích thước của hình thay đổi, sau lần đầu tiên, bạn có thể tiếp tục nhất START nhiều lần hơn nếu muốn, nhưng sẽ không có gì xảy ra vì lúc này, currentAnimation đã khác 0.

Trước:    Sau:      

 Tiếp theo, chúng ta sẽ sử dụng một biến đổi đặc biệt được gọi là CGAffineTransform.indentity. Điều này sẽ xóa mọi thay đổi trước đó và đặt lại mọi thứ về mặc định, và bây giờ đoạn mã của chúng ta sẽ như sau:

switch self.currentAnimation {
case 0:
    self.imageView.transform = CGAffineTransform(scaleX: 2, y: 2)

case 1:
    self.imageView.transform = CGAffineTransform.identity

default:
    break
}

Lúc này khi chạy chương trình, START lần đầu, kích thước của hình sẽ được tăng gấp 2 lần, START lần tiếp theo hình sẽ trở về kích thước ban đầu.

Chúng ta cùng xem thêm nhiều trường hợp khác:

case 2:
    self.imageView.transform = CGAffineTransform(translationX: 0, y: 100)

case 3:
    self.imageView.transform = CGAffineTransform.identity

Việc sử dụng CGAffineTransform(translationX: 0, y:100) sẽ làm cho hình của bạn dịch chuyển đến tọa độ (0, 100)  so với tọa độ ban đầu.

Chúng ta cũng có thể sử dụng CGAffineTransform để xoay chế độ xem, sử dụng trình khởi tạo rotationAngle, và chúng ta phải truyền vào một tham số, đó là góc radian bạn muốn xoay.

case 4:
    self.imageView.transform = CGAffineTransform(rotationAngle: CGFloat.pi)
case 5:
    self.imageView.transform = CGAffineTransform.identity

Có 3 lưu ý để sử dụng chức năng này:

- Bạn cần cung cấp giá trị trính bằng radian được chỉ định là CGFloat (nếu bạn nhập là 1.0 thì Swift tự hiểu đó là kiểu Float rồi nhé), nếu bạn muốn sử dụng một giá trị khác như pi, hãy sử dụng CGFloat.pi

- Core Animation sẽ luôn đi theo con đường ngắn nhất để làm cho vòng xoay hoạt động. Vì vậy, nếu đối tượng của bạn thẳng và xoay đến 90 độ, nó sẽ quay theo chiều kim đồng hồ. Nếu đối tượng của bạn thẳng và bạn xoay đến 270 độ thì nó sẽ xoay ngược chiều kim đồng hồ vì nó là vòng xoay ngắn nhất

- Một trường hợp nữa là nếu bạn cố xoay 360 độ, Core Animation sẽ tính toán vòng quay ngắn nhất là "đừng di chuyển, vì ta đang ở đó". Điều tương tự cũng xảy ra khi bạn cố xoay 540 độ thì bạn sẽ kết thúc chỉ với một vòng quay 1180 độ

Chúng ta còn có thể sử dụng CGAffineTransform để kéo ra các góc của khung hình theo 4 chiều để có thể tạo ra những khung hình đẹp mắt:

case 6:
    self.imageView.transform = CGAffineTransform(rotationAngle: CGFloat.pi)
case 7:
    self.imageView.transform = CGAffineTransform.identity

Trên đây chúng tôi có dẫn ra các chức năng khi sử dụng thuộc tính transform của UIView, các bạn cũng có thể kết hợp các phép biến đổi với nhau để có được khung hình ưa thích nhé

Bài viết được tham khảo tại đây

Các bạn có thể tìm hiểu nhiều hơn các bài viết về iOS tại blog của Techmaster, và các khóa học được xây dựng đáp ứng với xu thế công nghệ năm 2019

Techmaster có khóa học iOS Swift, React Native, Flutter ngắn hạn và dài hạn đảm bảo chất lượng đầu ra của học viên

Phát hiện và phòng ngừa quay trộm màn hình trong iOS 11 Phát hiện và phòng ngừa quay trộm màn hình trong iOS 11 Nguyễn Duy Khánh Blog Home Apple đưa ra công cụ Swift Playgrounds để giúp những người mới bắt đầu học lập trình Apple đưa ra công cụ Swift Playgrounds để giúp những người mới bắt đầu học lập trình Hồ Sỹ Hùng
Tào Quỳnh