Tạo transition cho Hamburger Button trong Swift

77

Bài hướng dẫn này sẽ chỉ cách làm thế nào để chúng ta có thể tạo ra một diễn hoạt cho một Button sử dụng Core Graphics trong Swift từ Robert Böhnke.

Bạn sẽ để ý cách mà các stroke ở đỉnh và đáy của tạo thành một chữ X, trong khi stroke ở giữa tạo thành đường tròn bao quanh. Hiệu ứng này có thể được tái tạo bằng cách sử dụng CAShapeLayer, nhưng trước tiên chúng ta cần tạo 1 CGPath riêng cho 3 stroke này.

1 nét thẳng (stroke) có thể được tạo ra như thế này:

Tuy nhiên đối với stroke ở giữa, chúng ta có thể tạo nó bằng Sketch:

Sau đó chúng ta sẽ export ra như 1 file SVG và import nó vào PaintCode, PaintCode giúp chúng ta convert file này thành những đoạn code tạo bởi UIBezierPath. Sau đó chúng ta sẽ sử dụng những đoạn code này để tạo ra 1 đối tượng CGPath mong muốn:

 

Có thể 1 lib cho phép ta load thẳng 1 CGPath ngay từ file SVG, nhưng với 1 path ngắn như thế này, có nó ở trong đoạn code không phải là 1 vấn đề quá lớn.

Trong subclass của UIButton, chúng ta thêm vào 3 thuộc tính CAShapeLayer và thiết lập Path của chúng cho phù hợp:

 

Sau đó, chúng ta sẽ thiết lập kiểu của cả 3 path đó như thế này:

Để tính toán thuộc tính bound của chúng 1 cách chính xác nhất, chúng ta cần lấy size của stroke đó để tính toán. Rất may là CGPathCreateCopyByStrokingPath sẽ tạo ra được một path mà cái path này sẽ theo cái khung viền của cái stroke ban đầu, do đó mà bound của nó sẽ chứa đầy đủ nội dung của CAShapeLayer:

Những cái stroke sau đó sẽ xoay quanh hầu hết bên phải của các điểm, chúng ta phải thiết lập thuộc tính anchorPoint của chúng một cách phù hợp khi sắp xếp các layers:

Bây giờ, khi button thay đổi state, nó sẽ thực hiện chuyển động 3 cái stroke này tới những vị trí mới. Đối với stroke ở trên cùng, đầu tiên chúng ta sẽ di chuyển nó vào phía trong bằng 4 điểm để giữ nó ở chính giữa, sau đó ta sẽ xoay nó âm 45 độ để tạo thành 1 nét của chữ X:

Tương tự với stroke ở đáy.

Đối với stroke ở giữa sẽ hơi phức tạp hơn một chút. Để có được hiệu ứng mong muốn, chúng ta cần thực hiện animate riêng biệt cho 2 thuộc tính strokeStart và strokeEnd của CAShapeLayer.

Đầu tiên chúng ta phải tính toán chính xác các giá trị cho 2 thuộc tính này trong 2 trạng thái. Lưu ý rằng ngay cả trong trạng thái Hambuger (hình dạng của button), stroke cũng không bắt đầu ở điểm 0. Bằng cách có một path mở rộng một chút ở phía bên kia của cạnh trái stroke bên ngoài, chúng ta có thể có được những hiệu ứng dự kiến sẽ rất đẹp sau khi áp dụng timing function:

IDE Academy via maniacdev.com via Rorbert’blog