Δημιουργία ατέρμονου progress bar για το iOS

By tgalanis , 13 October 2023
Swift progress bar

Οι δείκτες (ή μπάρες) προόδου (progress indicators or bars) βοηθούν τους χρήστες της εφαρμογής μας να γνωρίζουν ότι δεν έχει "κολλήσει", κατά την διάρκεια φόρτωσης δεδομένων ή άλλων διεργασιών που απαιτούν αρκετό χρόνο να εκτελεστούν.

Δεδομένου ότι η διάρκεια μιας διεργασίας είναι είτε γνωστή είτε άγνωστη σε εμάς ως developers, υπάρχουν δύο τύποι progress indicators:

  • Determinate (καθορισμένος), για εργασίες με "μετρήσιμη" διάρκεια όπως η μετατροπή ή λήψη ενός ενός αρχείου.

  • Indeterminate (μη καθορισμένος), για εργασίες που δεν γνωρίζουμε εκ των προτέρων πόσο μπορεί να διαρκέσουν, όπως ο συγχρονισμός πολύπλοκων δεδομένων.

Μονο για το MacOS;

Σύμφωνα με το documentation της Apple, τη στιγμή που γράφω αυτό το άρθρο, η ατέρμονη κίνηση χρήσιμη σε εμάς στην περίπτωση μη καθορισμένης εργασίας, είναι διαθέσιμη μόνο στο MacOS και όχι στο iOS.

Για το λόγο αυτό θα δημιουργήσουμε έναν δικό μας με το πιο devItEasy τρόπο.

import UIKit
/// Creates an *indeterminate* indicator for iOS.
/// Suitable for unquantifiable tasks, such as loading or synchronizing complex data.
class IndeterminateIndicator: UIView {
    var barLength: CGFloat?
    var barHeight: CGFloat?
    var barColor: UIColor?
    var lineLength: CGFloat?
    var lineHeight: CGFloat?
    var lineCenter: CGFloat?
    var lineColor: UIColor?
    var lineSpeed: Double?
    
    override init(frame: CGRect) {
        super.init(frame: frame)
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }
    
    override func draw(_ rect: CGRect) {
        let barLength: CGFloat = self.barLength ?? self.frame.width
        let barHeight: CGFloat = self.barLength ?? self.frame.height
        
        let lineLength: CGFloat = self.lineLength ?? barLength / 2
        let lineHeight: CGFloat = self.lineHeight ?? barHeight / 2
        let lineY: CGFloat = self.lineCenter ?? lineHeight
        let lineColor: UIColor = self.barColor ?? .red
        let lineSpeed: Double = self.lineSpeed ?? 1.0
        
        let path = UIBezierPath()
        path.move(to: CGPoint(x: -lineLength, y: lineY))
        path.addLine(to: CGPoint(x: 0, y: lineY))
        
        let shape = CAShapeLayer()
        shape.path = path.cgPath
        shape.strokeColor = lineColor.cgColor
        shape.lineWidth = lineHeight
        
        self.layer.addSublayer(shape)
        
        let animation = CABasicAnimation(keyPath: "position.x")
        animation.fromValue = 0
        animation.toValue = barLength + lineLength
        animation.duration = lineSpeed
        animation.repeatCount = .greatestFiniteMagnitude
        shape.add(animation, forKey: "play")
    }
}

If you have any questions, comments or corrections regarding the article, don't hesitate to write them in the comments below.

Do you want us to dedicate the next one to you?

If you are having difficulty at any point (especially if you are interested in starting with programming), write in the comments the topic you want us to write about and we will dedicate it to you!

Comments