2017-02-17 3 views
0

, поэтому я могу загружать изображения в свой табличный вид с моего сервера синтаксического анализа, но если он отстает, ячейка просто белая. Итак, что я хочу сделать, добавьте настраиваемый индикатор поворота на задний план, который будет вращаться, пока изображение не загрузится полностью. Вот индикатор. Это от репозитория от github. Репозиторий «https://github.com/Tueno/MaterialLoadingIndicator» и код для него ниже. Мне нужна помощь, чтобы кто-то показал мне, как я могу реализовать этот индикатор в ячейке для вращения до загрузки изображения.Индикатор для uiimage в таблицеView

Heres код для индикатора `класса MaterialLoadingIndicator: UIView {

let MinStrokeLength: CGFloat = 0.05 
let MaxStrokeLength: CGFloat = 0.7 
let circleShapeLayer = CAShapeLayer() 

override init(frame: CGRect) { 
    super.init(frame: frame) 
    backgroundColor = UIColor.clear 
    initShapeLayer() 
} 

required 
init?(coder aDecoder: NSCoder) { 
    fatalError("init(coder:) has not been implemented") 
} 

func initShapeLayer() { 
    circleShapeLayer.actions = ["strokeEnd" : NSNull(), 
           "strokeStart" : NSNull(), 
           "transform" : NSNull(), 
           "strokeColor" : NSNull()] 
    circleShapeLayer.backgroundColor = UIColor.clear.cgColor 
    circleShapeLayer.strokeColor  = UIColor.blue.cgColor 
    circleShapeLayer.fillColor  = UIColor.clear.cgColor 
    circleShapeLayer.lineWidth  = 5 
    circleShapeLayer.lineCap   = kCALineCapRound 
    circleShapeLayer.strokeStart  = 0 
    circleShapeLayer.strokeEnd  = MinStrokeLength 
    let center      = CGPoint(x: bounds.width*0.5, y: bounds.height*0.5) 
    circleShapeLayer.frame   = bounds 
    circleShapeLayer.path   = UIBezierPath(arcCenter: center, 
                radius: center.x, 
                startAngle: 0, 
                endAngle: CGFloat(M_PI*2), 
                clockwise: true).cgPath 
    layer.addSublayer(circleShapeLayer) 
} 

func startAnimating() { 
    if layer.animation(forKey: "rotation") == nil { 
     startColorAnimation() 
     startStrokeAnimation() 
     startRotatingAnimation() 
    } 
} 

private func startColorAnimation() { 
    let color  = CAKeyframeAnimation(keyPath: "strokeColor") 
    color.duration = 10.0 
    color.values = [UIColor(hex: 0x4285F4, alpha: 1.0).cgColor, 
         UIColor(hex: 0xDE3E35, alpha: 1.0).cgColor, 
         UIColor(hex: 0xF7C223, alpha: 1.0).cgColor, 
         UIColor(hex: 0x1B9A59, alpha: 1.0).cgColor, 
         UIColor(hex: 0x4285F4, alpha: 1.0).cgColor] 
    color.calculationMode = kCAAnimationPaced 
    color.repeatCount  = Float.infinity 
    circleShapeLayer.add(color, forKey: "color") 
} 

private func startRotatingAnimation() { 
    let rotation   = CABasicAnimation(keyPath: "transform.rotation.z") 
    rotation.toValue  = M_PI*2 
    rotation.duration  = 2.2 
    rotation.isCumulative  = true 
    rotation.isAdditive  = true 
    rotation.repeatCount = Float.infinity 
    layer.add(rotation, forKey: "rotation") 
} 

private func startStrokeAnimation() { 
    let easeInOutSineTimingFunc = CAMediaTimingFunction(controlPoints: 0.39, 0.575, 0.565, 1.0) 
    let progress: CGFloat  = MaxStrokeLength 
    let endFromValue: CGFloat = circleShapeLayer.strokeEnd 
    let endToValue: CGFloat = endFromValue + progress 
    let strokeEnd     = CABasicAnimation(keyPath: "strokeEnd") 
    strokeEnd.fromValue    = endFromValue 
    strokeEnd.toValue    = endToValue 
    strokeEnd.duration    = 0.5 
    strokeEnd.fillMode    = kCAFillModeForwards 
    strokeEnd.timingFunction  = easeInOutSineTimingFunc 
    strokeEnd.beginTime    = 0.1 
    strokeEnd.isRemovedOnCompletion = false 
    let startFromValue: CGFloat  = circleShapeLayer.strokeStart 
    let startToValue: CGFloat  = fabs(endToValue - MinStrokeLength) 
    let strokeStart     = CABasicAnimation(keyPath: "strokeStart") 
    strokeStart.fromValue   = startFromValue 
    strokeStart.toValue    = startToValue 
    strokeStart.duration   = 0.4 
    strokeStart.fillMode   = kCAFillModeForwards 
    strokeStart.timingFunction  = easeInOutSineTimingFunc 
    strokeStart.beginTime   = strokeEnd.beginTime + strokeEnd.duration + 0.2 
    strokeStart.isRemovedOnCompletion = false 
    let pathAnim     = CAAnimationGroup() 
    pathAnim.animations   = [strokeEnd, strokeStart] 
    pathAnim.duration   = strokeStart.beginTime + strokeStart.duration 
    pathAnim.fillMode   = kCAFillModeForwards 
    pathAnim.isRemovedOnCompletion = false 
    CATransaction.begin() 
    CATransaction.setCompletionBlock { 
     if self.circleShapeLayer.animation(forKey: "stroke") != nil { 
      self.circleShapeLayer.transform = CATransform3DRotate(self.circleShapeLayer.transform, CGFloat(M_PI*2) * progress, 0, 0, 1) 
      self.circleShapeLayer.removeAnimation(forKey: "stroke") 
      self.startStrokeAnimation() 
     } 
    } 
    circleShapeLayer.add(pathAnim, forKey: "stroke") 
    CATransaction.commit() 
} 

func stopAnimating() { 
    circleShapeLayer.removeAllAnimations() 
    layer.removeAllAnimations() 
    circleShapeLayer.transform = CATransform3DIdentity 
    layer.transform   = CATransform3DIdentity 
} 

} 

    extension UIColor { 

convenience init(hex: UInt, alpha: CGFloat) { 
    self.init(
     red: CGFloat((hex & 0xFF0000) >> 16)/255.0, 
     green: CGFloat((hex & 0x00FF00) >> 8)/255.0, 
     blue: CGFloat(hex & 0x0000FF)/255.0, 
     alpha: CGFloat(alpha) 
    ) 
} 

}` 

И вот мой код для загрузки изображения с моего сервера.

let query = PFQuery(className: "Users") 
    query.addDescendingOrder("createdAt") 
    query.findObjectsInBackground(block: { (objects, error) -> Void in 
     if error == nil { 

      // clean up 
      self.UserNameArray.removeAll(keepingCapacity: false) 
      self.ImageArray.removeAll(keepingCapacity: false) 

      // find related objects 
      for object in objects! { 
       self.UserNameArray.append(object.object(forKey: "User") as! String) 
       self.ImageArray.append(object.object(forKey: "Image") as! PFFile) 
      } 

      //ADD THIS 
      self.horizontalContacts.reloadData() 

     } else { 
      print(error!.localizedDescription) 
     } 
    }) 
+0

Удалите объектив-c-тэг с вашего вопроса при использовании быстрого кода. –

ответ

0
//something like that 
class ImageTableViewCell: UITableViewCell { 
    var contentImage: UIImage?{ 
     didSet{ 
      if contentImage == nil{ 
       self.imageView.addSubview(MaterialLoadingIndicator) 
      }else{ 

       self.imageView = UIImageView(image: contentImage) 
      } 
     } 
    } 


    //and in TableViewController 

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCell(withIdentifier: cellReuseIdentifier, for: indexPath) as! ImageTableViewCell 
     if images[indexPath.row] == nil{ 
      cell.image = nil 
     }else{ 
      cell.image = images[indexPath.row] 
      return cell 
     } 
} 
+0

это хорошо, но можете ли вы помочь мне с реализацией materialloadingindicator – john

+0

Как вы думаете, – john

+0

[link] (https://www.evernote.com/l/ARIEicjI3AFF1aev0NAjIVt2ot1Md8WOSMg) [ссылка] (https://www.evernote.com/l/ARJqhrEZ0l5IMIeLUn1IkjZ1ear94QtFUsE) –

0

Создать MaterialLoadingIndicator и добавить его в качестве subview из imageView.

let indicator = MaterialLoadingIndicator(frame: CGRect(x: 0, y: 0, width: imageView.frame.size.width, height: imageView.frame.size.height)) 
indicator.center = imageView.center 
imageView.addSubview(indicator) 

//Start animating the loader 
indicator.startAnimating() 

И когда вы получаете изображение от синтаксического анализа сервера просто позвонить indicator.stopAnimating() и установить изображение на imageView

+0

Я пробовал это, он не работал – john

+0

это не сработало, вы думаете, что можете мне помочь – john

0

Вы можете легко достичь, создав пользовательский класс UIImageView. Затем вы можете использовать его, когда хотите асинхронно загружать изображения в свой проект.

Сначала создайте новый файл coca touch class в качестве подкласса для UIImageView и дайте содержательное имя. Я предлагаю положить AsyncImageView в качестве названия.

Затем скопируйте пасту ниже фрагмент кода в созданный файл (Здесь я рассматриваю AsyncImageView как ваше имя созданного файла, если не изменить имя класса, соответственно),

import UIKit 

class AsyncImageView: UIImageView { 

    /* 
    // Only override draw() if you perform custom drawing. 
    // An empty implementation adversely affects performance during animation. 
    override func draw(_ rect: CGRect) { 
     // Drawing code 
    } 
    */ 

    func downloadedFrom(url: URL, defaultImage:UIImage, contentMode mode: UIViewContentMode = .scaleAspectFit) { 
     contentMode = mode 

    self.image = defaultImage 

    let activityView = UIActivityIndicatorView(activityIndicatorStyle: .gray) 
    activityView.frame = CGRect(origin: CGPoint(x: 0,y :0), size: CGSize(width: self.frame.size.width, height: self.frame.size.height)) 
    activityView.layer.cornerRadius = self.layer.cornerRadius 
    activityView.center = self.center 
    activityView.backgroundColor = UIColor.clear 
    activityView.startAnimating() 
    self.superview?.addSubview(activityView) 

     URLSession.shared.dataTask(with: url) { (data, response, error) in 
      guard 
       let httpURLResponse = response as? HTTPURLResponse, httpURLResponse.statusCode == 200, 
       let mimeType = response?.mimeType, mimeType.hasPrefix("image"), 
       let data = data, error == nil, 
       let image = UIImage(data: data) 
       else { return } 
      DispatchQueue.main.async() {() -> Void in 
       self.image = image 
       activityView.stopAnimating() 
       activityView.removeFromSuperview() 
      } 
      }.resume() 
    } 
func downloadedFrom(link: String, defaultImage:UIImage, contentMode mode: UIViewContentMode = .scaleAspectFit) { 
     guard let url = URL(string: link) else { return } 
     downloadedFrom(url: url, defaultImage:defaultImage, contentMode: mode) 
    } 

} 

Thats это мы сделали! просто сохраните файл и используйте этот пользовательский класс вместо UIImageView (укажите имя класса в Identity Inspector Xcode). После создания выхода вашего ImageView в контроллере с помощью перетаскивания вы можете загрузить изображение асинхронно, используя код, приведенный ниже фрагмент кода

@IBOutlet weak var asyncImageView: AsyncImageView! 
    override func viewDidLoad() { 
     super.viewDidLoad() 
     asyncImageView.downloadedFrom(link: "https://s29.postimg.org/qqxoigjbr/Arun_Photo.png", defaultImage:UIImage(named:"noImage")!) 
     // change image link to your image in parse server & default image means you can set a background image at time of indicator run 
    } 

Я знаю, как свежее, у вас есть еще сомневаетесь в этих шагов, чтобы получить больше ясности я сделал образец проекта и вы можете скачать его с here https://bitbucket.org/arunjos007/swfit_asyncimageview/downloads

+0

У меня есть одна проблема. Я загружаю изображения из разбора. Не могли бы вы взглянуть на мой проект – john

+0

Как вы думаете, – john

+0

О, конечно, дайте мне файл проекта и укажите, что является ошибкой – arunjos007

Смежные вопросы