Tạo Semi Circular Progress cho iOS

Mở đầu Khi làm dự án cho công ty hoặc khách hàng, đôi lúc bạn sẽ nhận được yêu cầu tạo những giao diện liên quan tới hình vẽ, khối mà dùng hình ảnh thì khó mà dùng thư viện thì chẳng bõ, khi ấy chúng ta sẽ cần sử dụng tới những tính năng

Mở đầu

Khi làm dự án cho công ty hoặc khách hàng, đôi lúc bạn sẽ nhận được yêu cầu tạo những giao diện liên quan tới hình vẽ, khối mà dùng hình ảnh thì khó mà dùng thư viện thì chẳng bõ, khi ấy chúng ta sẽ cần sử dụng tới những tính năng cho phép vẽ custom lên UIView.

Trong bài lần này mình sẽ chia sẻ cách tạo 1 Progress theo dạng đường tròn khuyết (Semi Circular Progress) bằng CAShapeLayer.

Demo

Demo trên iOS

Thực hiện

Tạo Custom View

Tạo 1 project mới để demo, từ file dự án tạo 1 file kế thừa UIView ở đây mình đặt là SemiCircleView. Ta sẽ tiến hành dùng CAShapeLayer vẽ progress ở trên CustomView này

Ta sẽ cần 2 layer, 1 cho background màu xám ở dưới và 1 cho phần màu xanh thay đổi được nên ta sẽ tạo ra 2 ShapeLayer lần lượt là backgroundLayermainLayer

classSemiCircleView:UIView{privatevar backgroundLayer:CAShapeLayer?privatevar mainLayer:CAShapeLayer?}

Hàm cài đặt cho CustomView

Ta tạo hàm setup với tham số truyền vào là UIColor tương ứng với màu progress bạn muốn vẽ, lần lượt viết các lệnh vẽ path cho ShapeLayer

funcsetupUI(color:UIColor){// Remove layer trước khi thêm để tránh view chèn vào nhiều layer,// Phần này sẽ giúp bạn tránh vẽ đè khi gọi là hàm setup
        mainLayer?.removeFromSuperlayer()
        backgroundLayer?.removeFromSuperlayer()// Khởi tạo lại layer
        mainLayer =CAShapeLayer()
        backgroundLayer =CAShapeLayer()let center =CGPoint(x: frame.width/2, y: frame.height/2)// center nằm ở giữa view chalet circularPath =UIBezierPath(arcCenter: center,// tâm đường tròn
                                        radius: frame.height/2,// bán kính đường tròn
                                        startAngle:CGFloat.pi *3/4,// điểm vẽ đầu
                                        endAngle:CGFloat.pi *13/6,// điểm vẽ cuối
                                        clockwise:true)// Vẽ theo chiều kim đồng hồ
        mainLayer?.path = circularPath.cgPath
        backgroundLayer?.path = circularPath.cgPath
        setupSubLayer(backgroundLayer, color:UIColor.separator, progress:1)setupSubLayer(mainLayer, color: color, progress:0)}

Tiếp theo là hàm setup của ShapeLayer, sau setup ta sẽ add vào thành subLayer của SemiCircleView

privatefuncsetupSubLayer(_ shapeLayer:CAShapeLayer?, color:UIColor, progress:CGFloat){
        shapeLayer?.fillColor =UIColor.clear.cgColor // Màu của layer
        shapeLayer?.strokeEnd = progress // Độ phủ của stroke, tính theo %, max là 1
        shapeLayer?.strokeColor = color.cgColor // Màu của stroke
        shapeLayer?.lineWidth =12// Độ rộng stroke
        shapeLayer?.lineCap =.round // Hình dạng 2 đầu stroke (round là bo tròn)iflet sub = shapeLayer {
            layer.addSublayer(sub)}}

Cuối cùng ta sẽ viết hàm để thay đổi giá trị progress

funcsetProgress(_ progress:Float){UIView.animate(withDuration:0.3){// Đặt hiệu ứng cho chuyển động bắt mắt hơnself.mainLayer?.strokeEnd =CGFloat(progress)}}

Demo

Ở Story board Main ta thêm View có kích thước 200 x 200 căn giữa view cha và cho kế thừa SemiCircleView ta vừa tạo.

Tiếp theo ta kéo thêm 1 label hiển thị giá trị progress và 1 button thay đổi giá trị progress.

Ở class ViewController ta chỉ cần gọi setup cho SemiCircleViewviewDidLoad và gọi hàm setProgress mỗi khi click button thay đổi progress là sẽ có được phần giao diện thay đổi progress bar tròn như hình phía đầu bài viết.

classViewController:UIViewController{@IBOutletweakvar semiCircleView:SemiCircleView!@IBOutletweakvar progressLabel:UILabel!overridefuncviewDidLoad(){super.viewDidLoad()
        semiCircleView.setupUI(color:.systemBlue)
        semiCircleView.setProgress(0)}@IBActionfuncrecTap(_ sender:UIButton){let progress =Int.random(in:0...100)
        progressLabel.text ="(progress) %"
        semiCircleView.setProgress(Float(progress)/100)}}

Kết thúc

Bài viết này mình đã chia sẻ về cách đơn giản để tạo 1 Progress Bar tròn khuyết dùng CAShapeLayer, mong rằng chia sẻ này sẽ giúp ích cho các bạn.

Xin cảm ơn các bạn đã dành thời gian đọc bài viết và nếu thấy bổ ích hãy cho mình +1 đánh giá động viên nhé!

Nguồn: viblo.asia

Bài viết liên quan

WebP là gì? Hướng dẫn cách để chuyển hình ảnh jpg, png qua webp

WebP là gì? WebP là một định dạng ảnh hiện đại, được phát triển bởi Google

Điểm khác biệt giữa IPv4 và IPv6 là gì?

IPv4 và IPv6 là hai phiên bản của hệ thống địa chỉ Giao thức Internet (IP). IP l

Check nameservers của tên miền xem website trỏ đúng chưa

Tìm hiểu cách check nameservers của tên miền để xác định tên miền đó đang dùn

Mình đang dùng Google Domains để check tên miền hàng ngày

Từ khi thông báo dịch vụ Google Domains bỏ mác Beta, mình mới để ý và bắt đầ