Lời mở đầu
Có thể các bạn đã biết progress view của Apple nó khá là đơn giản và ýt thuộc tính để chúng ta có thể sử dụng cũng như thay đổi để phù hợp với thiết kế. Trong dự án gần đây mình đã có cơ hội để động vào nó. Trong thời gian đầu mình tự mày mò thì progress bar không hỗ trợ việc như vậy. Vì vậy mình viết bài này để chia sẻ về cách mình đã custom lại progress này. Hi vọng nó giúp các bạn gặp khó khăn với việc custom lại progress bar.
Vấn đề cần giải quyết: Làm thế nào để bo tròn góc của progress bar
Đây là progress view mình cần đạt được:
Đây là progress bar mặc đinh của apple:
Phân tích
Khi thử đọc tài liệu về UIProgressView. Không có thuộc tính nào giúp mình có thể đạt được điều mình muốn.
Để bo tròn cả progressview thì ta có thể dùng layer.cornerRadius, nhưng để bo tròn thằng progress chạy bên trong thì sao? Chúng ta cần tìm được cái view đó và bo nó lại.
Giải quyết bài toán
Bước 1: Chúng ta cần tạo constraint height cho progressView
Chúng ta có 2 cách để tăng height cho ProgressView:
1. Sử dụng Transform Scale: Nó sẽ làm cornerRadius chạy không đúng
2. Sử dụng constraint height: Nên chúng ta chon cách này
Tuy rằng chúng ta đã constraint height của nó bằng 16 nhưng thực tế height của progressView vẫn = 2. Vì vậy khi set cornerRadius chúng ta không thể sử dụng frame.height/2 được mặc dù đó là cách tốt nhất đối với các view khác.
Bước 2: Bo tròn góc cho trackView
progressBar.layer.cornerRadius = 8.0
progressBar.clipsToBounds = true
Bước 3: Bo tròn progressView
if let sublayers = progressBar.layer.sublayers, sublayers.count > 1 {
sublayers[1].cornerRadius = 8.0
}
progressBar.subviews[1].clipsToBounds = true
Nếu để ý kĩ các bạn sẽ thấy progress bar này gồm 2 view chồng lên nhau đó là Progress View và track view. Và theo thứ tự trong lập trình thì thằng đầu tiên là thằng nằm dưới có index = 0. Chúng ta nhìn thấy progress view vì nó nằm trên Track View -> nó có index = 1
Lưu ý: Nó chỉ đúng khi chúng ta không thêm subview, sublayer cho ProgressView. Vậy nên trong trường hợp này chúng ta sẽ ổn.
If let giúp chúng ta handle trường hợp crash app, khi các layer của progress bị remove. (nó thường k xảy ra, nhưng vì an toàn chúng ta nên thêm dòng này)
sublayers[1]: là layer của track view
subviews[1]: là trackView
Kết quả thu được thật mỹ mãn 😀
Ngoài ra các bạn có thể sử dụng image cho progress view cũng như trackView để có 1 progress đẹp hơn.
progressBar.progressImage = UIImage(named: "2697")
Các bạn có thể tải về file assets ở dưới:
Tổng kêt
Mình hi vọng bài viết dưới đây giúp các bạn hiểu rõ hơn về UIProgressView và dễ dàng hơn khi làm việc với nó.