Activity indicator with custom image

后端 未结 10 1213
甜味超标
甜味超标 2021-01-31 05:58

I am loading a UIWebView and in the meantime I wan\'t to show a blank page with this\"spinner\" activity indic

相关标签:
10条回答
  • 2021-01-31 06:22

    Swift 5.0 version of accepted Answer

    public extension UIImageView {
      func spin(duration: Float) {
        let rotation = CABasicAnimation(keyPath: "transform.rotation")
        rotation.fromValue = 0
        rotation.toValue = 2 * Double.pi
        rotation.duration = 0.7
        rotation.repeatCount = duration
        layer.add(rotation, forKey: "spin")
      }
    
      func stopSpinning() {
        layer.removeAllAnimations()
      }
    }
    
    0 讨论(0)
  • 2021-01-31 06:30

    Without Image , you can use third party library

    for objective C (also support in iOS 6) https://github.com/shebinkoshy/UIControllsRepo

    for swift https://github.com/shebinkoshy/Activity-Indicator-Swift

    Advantages

    -> Able to set colors for spinner

    -> Available in different sizes like tiny, small, medium, large, very large

    -> Able to set Title (center and bottom) for medium, large, very large sizes

    0 讨论(0)
  • 2021-01-31 06:31

    You may use this beautiful loader inspired from Tumblr app:
    Asich/AMTumblrHud

    0 讨论(0)
  • 2021-01-31 06:31

    SWIFT 4 Sweet And Simply just put extension UIView{}

    Modified answer of @gandhi Mena

    if you want to create your own custom Loading indicator

    Create a UIView extension which create and customize your brand logo as a custom indicator put this code in you global declaration file.

    extension UIView{
    func customActivityIndicator(view: UIView, widthView: CGFloat?,backgroundColor: UIColor?, textColor:UIColor?, message: String?) -> UIView{
    
        //Config UIView
        self.backgroundColor = backgroundColor //Background color of your view which you want to set
    
        var selfWidth = view.frame.width
        if widthView != nil{
            selfWidth = widthView ?? selfWidth
        }
    
        let selfHeigh = view.frame.height
        let loopImages = UIImageView()
    
        let imageListArray = ["image1", "image2"] // Put your desired array of images in a specific order the way you want to display animation.
    
        loopImages.animationImages = imageListArray
        loopImages.animationDuration = TimeInterval(0.8)
        loopImages.startAnimating()
    
        let imageFrameX = (selfWidth / 2) - 30
        let imageFrameY = (selfHeigh / 2) - 60
        var imageWidth = CGFloat(60)
        var imageHeight = CGFloat(60)
    
        if widthView != nil{
            imageWidth = widthView ?? imageWidth
            imageHeight = widthView ?? imageHeight
        }
    
        //ConfigureLabel
        let label = UILabel()
        label.textAlignment = .center
        label.textColor = .gray
        label.font = UIFont(name: "SFUIDisplay-Regular", size: 17.0)! // Your Desired UIFont Style and Size
        label.numberOfLines = 0
        label.text = message ?? ""
        label.textColor = textColor ?? UIColor.clear
    
        //Config frame of label
        let labelFrameX = (selfWidth / 2) - 100
        let labelFrameY = (selfHeigh / 2) - 10
        let labelWidth = CGFloat(200)
        let labelHeight = CGFloat(70)
    
        // Define UIView frame
        self.frame = CGRect(x: 0, y: 0, width: UIScreen.main.bounds.size.width , height: UIScreen.main.bounds.size.height)
    
    
        //ImageFrame
        loopImages.frame = CGRect(x: imageFrameX, y: imageFrameY, width: imageWidth, height: imageHeight)
    
        //LabelFrame
        label.frame = CGRect(x: labelFrameX, y: labelFrameY, width: labelWidth, height: labelHeight)
    
        //add loading and label to customView
        self.addSubview(loopImages)
        self.addSubview(label)
        return self }}
    

    Hide an indicator something like this you can remove subview at the top from the subview stack. put this code in the same globally declared swift file.

    func hideLoader(removeFrom : UIView){
    removeFrom.subviews.last?.removeFromSuperview()
    }
    

    Now you can shoot at the mark by this code To display activity indicator in your view controller put this code when you want to display.

     self.view.addSubview(UIView().customActivityIndicator(view: self.view, widthView: nil, backgroundColor:"Desired color", textColor: "Desired color", message: "Loading something"))
    

    To hide animating loader you can user above function you defined in the globally. In your ViewController.swift where you want to hide put this line of code.

    hideLoader(removeFrom: self.view)
    

    imageListArray looks like this.

    0 讨论(0)
  • 2021-01-31 06:34

    I've faced a similar issue lately. And this is my solution. Basically, it's what topic starter initially wanted: blank page with custom activity indicator on it.
    I have partly used @Azharhussain Shaikh answer but I've implemented auto-layout instead of using frames and added a few other refinements with the intention to make usage as simple as possible.

    So, it's an extension for UIView with two methods: addActivityIndicator() and removeActivityIndicator()

    extension UIView {
    
    func addActivityIndicator() {
        //    creating a view (let's call it "loading" view) which will be added on top of the view you want to have activity indicator on (parent view)
        let view = UIView()
        //    setting up a background for a view so it would make content under it look like not active
        view.backgroundColor = UIColor.white.withAlphaComponent(0.7)
    
        //    adding "loading" view to a parent view
        //    setting up auto-layout anchors so it would cover whole parent view
        self.addSubview(view)
        view.translatesAutoresizingMaskIntoConstraints = false
        view.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
        view.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
        view.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true
        view.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true
    
        //    creating array with images, which will be animated
        //    in my case I have 30 images with names activity0.png ... activity29.png
        var imagesArray = [UIImage(named: "activity\(0)")!]
        for i in 1..<30 {
            imagesArray.append(UIImage(named: "activity\(i)")!)
        }
    
        //    creating UIImageView with array of images
        //    setting up animation duration and starting animation
        let activityImage = UIImageView()
        activityImage.animationImages = imagesArray
        activityImage.animationDuration = TimeInterval(0.7)
        activityImage.startAnimating()
    
        //    adding UIImageView on "loading" view
        //    setting up auto-layout anchors so it would be in center of "loading" view with 30x30 size
        view.addSubview(activityImage)
        activityImage.translatesAutoresizingMaskIntoConstraints = false
        activityImage.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        activityImage.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        activityImage.widthAnchor.constraint(equalToConstant: 30).isActive = true
        activityImage.heightAnchor.constraint(equalToConstant: 30).isActive = true
    }
    
    func removeActivityIndicator() {
        //    checking if a view has subviews on it
        guard let lastSubView = self.subviews.last else { return }
        //    removing last subview with an assumption that last view is a "loading" view
        lastSubView.removeFromSuperview()
    } }
    

    "Rotating" effect is achieved by those 30 images you've put in imagesArray. Each image is a new frame of a rotating indicator like this.

    Usage. In your view controller for showing an activity indicator simply put:

        view.addActivityIndicator()
    

    For removing an activity indicator:

        view.removeActivityIndicator()
    

    For example, in case of using it with table view (like I do) it can be used like this:

    func setLoadingScreen() {
        view.addActivityIndicator()
        tableView.isScrollEnabled = false
    }
    
    func removeLoadingScreen() {
        view.removeActivityIndicator()
        tableView.isScrollEnabled = true
    }
    

    It works in Swift 4.

    0 讨论(0)
  • 2021-01-31 06:39

    it works in both SWITF 3 and 4

    var activityIndicator = UIActivityIndicatorView()
    var myView : UIView = UIView()
    
    func viewDidLoad() {
        spinnerCreation()
    }
    
    func spinnerCreation() {
    
        activityIndicator.activityIndicatorViewStyle =  .whiteLarge
    
        let label = UILabel.init(frame: CGRect(x: 5, y: 60, width: 90, height: 20))
        label.textColor = UIColor.white
        label.font = UIFont.boldSystemFont(ofSize: 14.0)
        label.textAlignment = NSTextAlignment.center
        label.text = "Please wait...."
    
        myView.frame = CGRect(x: (UIScreen.main.bounds.size.width - 100)/2, y: (UIScreen.main.bounds.size.height - 100)/2, width: 100, height: 100)
    
        myView.backgroundColor = UIColor.init(white: 0.0, alpha: 0.7)
        myView.layer.cornerRadius = 5
        activityIndicator.center = CGPoint(x: myView.frame.size.width/2, y:  myView.frame.size.height/2 - 10)
        myView.addSubview(activityIndicator)
        myView.addSubview(label)
    
        myView.isHidden = true
        self.window?.addSubview(myView)
    }
    
    @IBAction func activityIndicatorStart(_ sender: Any) {
        myView.isHidden = false
        self.activityIndicator.startAnimating()
        self.view.isUserInteractionEnabled = false
        self.view.bringSubview(toFront: myView)
    }
    
    @IBAction func activityIndicatorStop(_ sender: Any)() {
        myView.isHidden = true
        self.activityIndicator.stopAnimating()
        self.view.isUserInteractionEnabled = true
    }
    
    0 讨论(0)
提交回复
热议问题