UICollectionView滞后/帧下降

时间:2019-04-16 10:00:20

标签: ios swift xcode

下午好,我的所有应用程序当前都在掉帧,我不确定如何修复它……有点丢失。

希望你们/加尔斯能向我指出正确的方向。

我目前正在使用Kingfisher从我的后端下载图像,除了向下滚动时滚动有点断断续续,一切正常。

控制器代码如下所示,也许有些问题。

我正在使用情节提要,并删除并添加了约束...但是我没有运气。


import UIKit
import Kingfisher

class WallpaperCVC: UICollectionViewController , UIViewControllerTransitioningDelegate {

    var categoryId: String!
    var categoryName: String!
    var wallpaperBackend: Backend!
    var result:CGSize!
    // Header peralax
    fileprivate let headerId = "headerId"
    fileprivate let padding: CGFloat = 16



    @IBOutlet var wpMain: UICollectionView!

    override func viewDidLoad() {
        super.viewDidLoad()
        self.title = self.categoryName // Name to the controller or section selected
        // go go gadget data...
        getData()
        buttonGray()
        setupCollectionViewLayout()
        setupCollectionView()
    }

    func getData(){
        GLOBAL_BACKEND_DATA.removeAll()
        self.wallpaperBackend = Backend()
        self.wallpaperBackend.getWallByIdData(id: self.categoryId) { (god) in
            for post in god {
                let postData = post as! NSDictionary
                let wallpaperCVCId = postData.value(forKey: "id") as! String
                let wallpaperCVCFile = postData.value(forKey: "file") as! String
                let wallpaperCVCCategory = postData.value(forKey: "category") as! String
                let wallpaperCVCDownload = Int(postData.value(forKey: "download") as! String)

                GLOBAL_BACKEND_DATA.append(WallpaperModel(wallpaperModelId: wallpaperCVCId, wallpaperModelFile: wallpaperCVCFile, wallpaperModelCategoryId: wallpaperCVCCategory, wallpaperModelDownload: wallpaperCVCDownload!))
            }
         self.collectionView?.reloadData()
        }
    }

    @IBAction func pressedAction(_ sender: UIButton) {
        // do your stuff here
        self.dismiss(animated: true, completion: nil)
        print("you clicked on button \(sender.tag)")
    }
    func buttonGray(){
        let myButton = UIButton() // if you want to set the type use like UIButton(type: .RoundedRect) or UIButton(type: .Custom)
        let img = UIImage(named: "buttonA")
        myButton.setImage(img, for: .normal)
       // myButton.setTitleColor(UIColor.blue, for: .normal)
        myButton.frame = CGRect(x: 15, y: 50, width: 100, height: 100)
        // shadow
        myButton.layer.shadowOpacity = 0.5
        myButton.layer.shadowRadius = 4
        myButton.layer.shadowOffset = CGSize(width: 0, height: 5)
        myButton.addTarget(self, action: #selector(pressedAction(_:)), for: .touchUpInside)
        // haptic feedback
        myButton.isHaptic = true
        myButton.hapticType = .impact(.medium)
        //floatbutton like this
        view.addSubview(myButton)
        myButton.translatesAutoresizingMaskIntoConstraints = false
        myButton.leftAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leftAnchor, constant: 10).isActive = true
        myButton.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 0).isActive = true
    }
    // MARK: UICollectionViewDataSource

    override func numberOfSections(in collectionView: UICollectionView) -> Int {
        // You only need one section for now
        return 1
    }
    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        // Here call the wallpapers
        return GLOBAL_BACKEND_DATA.count
    }

    override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        // pulling & going to the controller
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "wallpapers", for: indexPath) as! WallpaperCVCell
        let godData = GLOBAL_BACKEND_DATA[indexPath.row]
        let imageURL = String(format:"%@uploads/image/%@", BASE_BACKEND_URL,godData.wallpaperModelFile) // calling wallpaperModel controller
        let escapedURL = imageURL.addingPercentEncoding(withAllowedCharacters: CharacterSet.urlQueryAllowed)
        let urls = URL(string:escapedURL!)
        // if nothing load this...
        let loadImage = UIImage(named: "skullLoading")
        cell.collWallpaperImage.kf.setImage(with: urls, placeholder: loadImage)
        cell.collWallpaperImage.kf.indicatorType = .activity  // Showing a loading indicator while downloading
        // lets count the downloads
        let count = godData.wallpaperModelDownload as Int // calling wallpaperModel controller
        cell.collectionCount.text = String(count) //collection view cell count label
        cell.configure() // calling a function from the cell

        return cell
    }

    // Lets move over to the next controller
    override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        print("Tapped....Tapped go to the next controller..")
        collectionView.deselectItem(at: indexPath, animated: true)

        let vc = self.storyboard!.instantiateViewController(withIdentifier: "page") as! PageViewController
        vc.position = indexPath.row
        vc.categoryName = self.categoryName
        vc.transitioningDelegate = self
        vc.modalPresentationStyle = .custom
        self.present(vc, animated: true, completion: nil)
    }
}

// MARK: - CollectionView Delegate
extension WallpaperCVC {
    // size images
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize {

        result =  CGSize(width: 187, height: 314)
        if DeviceType.IS_IPHONE_5 {
            result = CGSize(width: 160, height: 280)
        }
        if DeviceType.IS_IPHONE_6 {
            result =  CGSize(width: 187, height: 314)
        }
        if DeviceType.IS_IPHONE_6P {
            result = CGSize(width: 207, height: 320)
        }
        if DeviceType.IS_IPHONE_4_OR_LESS {
            result = CGSize(width: 151, height: 200)
        }
        return result;
    }

        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAt section: Int) -> UIEdgeInsets {


            return UIEdgeInsets(top: 15, left: 8, bottom: 5, right: 8)
        }

        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat {
            return 10
        }

     //size to all model screens to one.....NOW!!!!!!!!
        func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
            let width = UIScreen.main.bounds.width
            return CGSize(width: (width - 28)/2, height: 350) // width & height are the same to make a square cell
            }

}
// MARK: - CollectionView Layout Delegate
extension WallpaperCVC : UICollectionViewDelegateFlowLayout  {
    // Header peralax
    fileprivate func setupCollectionViewLayout() {
        let padding: CGFloat = 16
        if let layout = wpMain.collectionViewLayout as? UICollectionViewFlowLayout {
            layout.sectionInset = .init(top: padding, left: 0, bottom: padding, right: 0)
        }
    }
   // Header peralax
    fileprivate func setupCollectionView(){
        wpMain.contentInsetAdjustmentBehavior = .never
        wpMain.register(headerView.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: headerId)

    }
   // Header peralax
    override func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        let headerView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: headerId, for: indexPath)

        return headerView
    }
    // Header peralax
    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize {
        return .init(width: view.frame.width, height: 400)
      }
    }

该单元格看起来像这样

import UIKit
import Spring
import UICountingLabel



class WallpaperCVCell: UICollectionViewCell {


    override func layoutSubviews() {
        super.layoutSubviews()
      // self.textLabel?.frame = self.bounds
    }

    func configure() {

            layer.shouldRasterize = true
            layer.rasterizationScale = UIScreen.main.scale
            contentView.layer.cornerRadius = 7
            contentView.layer.masksToBounds = true
           // contentView.layer.borderWidth = 1.0
          //  contentView.layer.borderColor = UIColor.black.cgColor
    }
    @IBOutlet weak var collectionCount: UICountingLabel!

    @IBOutlet weak var collWallpaperImage: UIImageView!


    override func awakeFromNib() {
        super.awakeFromNib()
    }
}

&&这是视频...最初的滚动滞后然后消失,但每次都会播放

iPhone app lag video

编辑:最后,我重新设置了Kingfisher并安装了SDWebImage,这解决了该问题。

1 个答案:

答案 0 :(得分:0)

根据给定的代码,没有什么应该引起延迟。如果您可以分享一段有关时滞的简短视频,可以帮助您更好地理解问题。

另外,如果您可以共享cell.configure()方法中的代码也有帮助的话。

我确实为您提供了一些建议,可能会有所帮助,您可以尝试一下。

首先您可以移动设备检查

    if DeviceType.IS_IPHONE_5 {
        result = CGSize(width: 160, height: 280)
    }
    if DeviceType.IS_IPHONE_6 {
        result =  CGSize(width: 187, height: 314)
    }
    if DeviceType.IS_IPHONE_6P {
        result = CGSize(width: 207, height: 320)
    }
    if DeviceType.IS_IPHONE_4_OR_LESS {
        result = CGSize(width: 151, height: 200)
    }

在viewDidLoad中,这将帮助您的集合视图布局更快地调整单元格的大小,而不必每次用户滚动时都进行检查

类似这样的东西

func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: IndexPath) -> CGSize {
    return result;
}

override func viewDidLoad() {
    super.viewDidLoad()
    self.title = self.categoryName // Name to the controller or section selected
    setupDeviceSize()
    // go go gadget data...
    getData()
    buttonGray()
    setupCollectionViewLayout()
    setupCollectionView()
}

func setupDeviceSize(){

  if DeviceType.IS_IPHONE_5 {
    result = CGSize(width: 160, height: 280)
  }
  if DeviceType.IS_IPHONE_6 {
    result =  CGSize(width: 187, height: 314)
  }
  if DeviceType.IS_IPHONE_6P {
    result = CGSize(width: 207, height: 320)
  }
  if DeviceType.IS_IPHONE_4_OR_LESS {
    result = CGSize(width: 151, height: 200)
  }
}

第二,您可以为占位符图像创建全局变量

let loadImage = UIImage(named: "skullLoading")

并在cellForItemAtIndexpath中使用它,这将在每次调用cellForItemAtIndexpath时再次保存占位符图像的加载。

您应始终将cellForItemAtIndexpath保持尽可能浅,以实现流畅的滚动体验。

希望这会有所帮助。