在动画期间更改帧高度时,CollectionView冻结

时间:2018-07-04 03:54:04

标签: ios swift uicollectionview core-animation cgaffinetransform

我正在尝试创建一种效果,其中文本框消失,并且使用CGAffineTransform使collectionView向上滑动。这是有问题的代码

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    print("The scroll view began decelerating")
    if self.lastContentOffset > self.collectionView.contentOffset.y && self.collectionView.contentOffset.y > 0{
        print("you scrolled up:\t\(self.lastContentOffset)")

        lastContentOffset = self.collectionView.contentOffset.y
        self.feedSearchBar.isHidden = false
        UIView.animate(withDuration: 0.25, animations: {
          self.collectionView.transform = CGAffineTransform(translationX: 0, y: self.feedSearchBar.bounds.height*0.75)
            self.feedSearchBar.isHidden = false
        }, completion: nil)
    }
    else if self.lastContentOffset < self.collectionView.contentOffset.y && self.collectionView.contentOffset.y < self.collectionView.bounds.height{
        print("you scrolled down:\t\(self.lastContentOffset)")
        lastContentOffset = self.collectionView.contentOffset.y
        self.feedSearchBar.isHidden = true

         self.collectionView.frame.size = CGSize(width: self.collectionView.bounds.width, height: self.collectionView.bounds.height+5)
        UIView.animate(withDuration: 0.25, animations: {
           self.collectionView.transform = CGAffineTransform(translationX: 0, y: -self.feedSearchBar.bounds.height*0.75)


           self.collectionView.frame = CGRect(x: self.collectionView.frame.minX, y: self.collectionView.frame.minY, width: self.collectionView.frame.width, height: self.collectionView.frame.height+self.feedSearchBar.bounds.height*0.75 )
           self.feedSearchBar.isHidden = true
       }, completion: nil)
    }
    else{
        print("no difference")
    }
}

我不确定为什么在调整collectionView框架的大小后代码会冻结。我尝试过在不调整框架大小的情况下编写代码,但很快的结果是,屏幕底部下方出现了白色条。

这是全部代码

import UIKit

class ViewController: UIViewController,UICollectionViewDelegate, UICollectionViewDataSource,UICollectionViewDelegateFlowLayout,UITextFieldDelegate {

    var genericTagsArray:[String] = ["tag1","tag2","tag3","tag4","tag5","tag6","tag7","tag8","tag9","tag10","tag11","tag12","A","B","C","D","E","F","G","Ab","Abc","za","tag1","tag2","tag3","tag4","tag5","tag6","tag7","tag8","tag9","tag10","tag11","tag12","A","B","C","D","E","F","G","Ab","Abc","za"]
    var currentTagsArray:[String] = [String]()
    var tagsSelected:[String] = [String]()


    let keyboardSlider = KeyboardSlider()

    //@IBOutlet weak var feedSearchBar: UISearchBar!
    @IBOutlet weak var collectionView: UICollectionView!
    @IBOutlet weak var feedSearchBar: UITextField!

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        keyboardSlider.subscribeToKeyboardNotifications(view: view)
        feedSearchBar.delegate = self
        currentTagsArray = genericTagsArray

        feedSearchBar.autocorrectionType = .no
        feedSearchBar.keyboardType = .default
        feedSearchBar.addTarget(self, action: #selector(ViewController.textFieldDidChange), for: .editingChanged)

        let viewTapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(viewTapped(gestureRecognizer:)))
        viewTapGestureRecognizer.cancelsTouchesInView = false
        self.collectionView.addGestureRecognizer(viewTapGestureRecognizer)

        //
        collectionView.delegate = self
        collectionView.dataSource = self

       let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
          layout.sectionInset = UIEdgeInsets(top: 5, left: 1, bottom: 0, right: 1)
//        layout.itemSize = CGSize(width: collectionView.bounds.width/3, height: collectionView.bounds.width/3 )
//        layout.minimumInteritemSpacing = 0
          layout.minimumLineSpacing = 0
         collectionView.collectionViewLayout = layout


    //Styling the Search Bar
    self.feedSearchBar.borderStyle = .roundedRect
    self.feedSearchBar.layer.borderColor = UIColor.black.cgColor
    self.feedSearchBar.layer.borderWidth = 4
    var searchBarHeight = self.feedSearchBar.bounds.height
    self.feedSearchBar.frame = CGRect(x: 20, y: feedSearchBar.frame.maxY, width: self.collectionView.bounds.width, height: searchBarHeight*2)

    self.feedSearchBar.placeholder = "Tap To Search"
    self.feedSearchBar.returnKeyType = .search

//Code to add magnifying glass on right side
        //looking lgass
//        let imageView = UIImageView()
//        let magnifyingGlassImage = UIImage(named: "magnifyingGlass")
//        imageView.image = magnifyingGlassImage
//        //arrange the frame according to your textfield height and image aspect
//        imageView.frame = CGRect(x: 0, y: 5, width: 45, height: 20)
//        imageView.contentMode = .ScaleAspectFit
//        txtField.leftViewMode = .Always
//        txtField.leftView = imageView
    self.feedSearchBar.rightViewMode = .always

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        return 1
    }
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return currentTagsArray.count
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "feedViewCell", for: indexPath) as! feedViewCell


        cell.feedCellImageView.backgroundColor = .blue
        cell.feedCellImageView.clipsToBounds = true
        cell.feedCellImageView.layer.cornerRadius = CGFloat((cell.feedCellImageView.frame.width)/5)
//        cell.feedCellImageView.layer.borderWidth = 2
//        cell.feedCellImageView.layer.borderColor = UIColor.green.cgColor


        //cell.feedCellLabel.text = "Tags Go Here this is a really long tag that will exceed the bounds"
        cell.feedCellLabel.text = currentTagsArray[indexPath.item]
        return cell
    }

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        print("item: \(indexPath.item)\n\ttag: \(currentTagsArray[indexPath.item])")
    }

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

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

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {

        // Number of cells
        let collectionViewWidth = collectionView.bounds.width/4.0
        let collectionViewHeight = collectionViewWidth

        return CGSize(width: collectionViewWidth-4, height: collectionViewHeight+25)
    }

    //New stuff
    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()

        //        currentGenericArray = genericArray.filter({letter -> Bool in
        //            letter.lowercased().contains(searchBar.text!)
        //        })
        //        if currentGenericArray.isEmpty{
        //            print("This element is not in the current array")
        //        }
        collectionView.reloadData()
        return true
    }

    /// Helper to dismiss keyboard
    @objc func didStopEditing() {
        // textFieldShouldReturn(phoneNumberTextField)
    }

    func textFieldDidEndEditing(_ textField: UITextField) {
        UIView.setAnimationCurve(UIViewAnimationCurve.easeInOut)
        UIView.animate(withDuration: 0.2) {
            self.view.frame.origin.y = 0
        }
    }

    @objc func textFieldDidChange(){
        print("inside of text field did change")
        guard(!(feedSearchBar.text?.isEmpty)!) else{
            print("The search bar is empty")
            currentTagsArray = genericTagsArray
            collectionView.reloadData()
            return
        }
        print("The search bar was not empty it says: \(feedSearchBar.text)")

        currentTagsArray = genericTagsArray.filter({letter -> Bool in
            //letter.lowercased().contains(searchBar.text!)
            //mew stuff
            if feedSearchBar.text!.count > letter.count{
                return false
            }
            let stringRange = letter.index(letter.startIndex, offsetBy: feedSearchBar.text!.count)
            let subword = letter[..<stringRange]
            return subword.lowercased().contains(feedSearchBar.text!.lowercased())
            //
            //If broken delete above and uncoment below
            //letter.lowercased().contains(searchBar.text!.lowercased())

        })

        if currentTagsArray.isEmpty{
            currentTagsArray.insert(feedSearchBar.text!, at: 0)
        }

        collectionView.reloadData()
    }

    var lastContentOffset:CGFloat = 0
//    func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) {
//        print("The scroll view began decelerating")
//        self.feedSearchBar.isHidden = true
//        if self.lastContentOffset > self.collectionView.contentOffset.y{
//            print("you scrolled up")
//            self.feedSearchBar.isHidden = false
//        }
//        else if self.lastContentOffset < self.collectionView.contentOffset.y{
//            print("you scrolled down")
//            self.feedSearchBar.isHidden = true
//        }
//        else{
//            self.feedSearchBar.isHidden = false
//        }
//    }

    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        print("The scroll view began decelerating")
       // self.feedSearchBar.isHidden = true
        if self.lastContentOffset > self.collectionView.contentOffset.y && self.collectionView.contentOffset.y > 0{
            print("you scrolled up:\t\(self.lastContentOffset)")

            lastContentOffset = self.collectionView.contentOffset.y
//           // print("you scrolled up")
            self.feedSearchBar.isHidden = false
            UIView.animate(withDuration: 0.25, animations: {
              self.collectionView.transform = CGAffineTransform(translationX: 0, y: self.feedSearchBar.bounds.height*0.75)
                self.feedSearchBar.isHidden = false
            }, completion: nil)
      //        self.collectionView.frame.size = CGSize(width: self.collectionView.bounds.width, height: self.collectionView.bounds.height-5)
        }
        else if self.lastContentOffset < self.collectionView.contentOffset.y && self.collectionView.contentOffset.y < self.collectionView.bounds.height{
            print("you scrolled down:\t\(self.lastContentOffset)")
            lastContentOffset = self.collectionView.contentOffset.y
            self.feedSearchBar.isHidden = true

             self.collectionView.frame.size = CGSize(width: self.collectionView.bounds.width, height: self.collectionView.bounds.height+5)
            UIView.animate(withDuration: 0.25, animations: {
               self.collectionView.transform = CGAffineTransform(translationX: 0, y: -self.feedSearchBar.bounds.height*0.75)
               // self.collectionView.frame.size = CGSize(width: self.collectionView.bounds.width, height: self.collectionView.bounds.height+5)


               self.collectionView.frame = CGRect(x: self.collectionView.frame.minX, y: self.collectionView.frame.minY, width: self.collectionView.frame.width, height: self.collectionView.frame.height+self.feedSearchBar.bounds.height*0.75 )
               self.feedSearchBar.isHidden = true
           }, completion: nil)
        }
        else{
            print("no difference")
        }


    }





    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        NotificationCenter.default.addObserver(self, selector: #selector(ViewController.keyboardFrameChangeNotification(notification:)), name: NSNotification.Name.UIKeyboardWillChangeFrame, object: nil)
    }


     var offsetY:CGFloat = 0

    @objc func keyboardFrameChangeNotification(notification: Notification) {

    }


    @objc func viewTapped(gestureRecognizer:UIGestureRecognizer){

        if feedSearchBar.isFirstResponder{
            feedSearchBar.resignFirstResponder()
        }
    }

}

class feedViewCell:UICollectionViewCell{
    @IBOutlet weak var feedCellImageView: UIImageView!
    @IBOutlet weak var feedCellLabel: UILabel!

    override func awakeFromNib() {
        super.awakeFromNib()
        feedCellLabel.translatesAutoresizingMaskIntoConstraints = false
        feedCellImageView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
        feedCellImageView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
        feedCellImageView.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
        feedCellImageView.bottomAnchor.constraint(equalTo: self.feedCellLabel.topAnchor).isActive = true

        feedCellImageView.translatesAutoresizingMaskIntoConstraints = false
        feedCellLabel.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
        feedCellLabel.trailingAnchor.constraint(equalTo: self.trailingAnchor).isActive = true
        feedCellLabel.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
        feedCellLabel.topAnchor.constraint(equalTo: self.feedCellImageView.bottomAnchor).isActive = true

    }

}

extension Notification.Name{
    static let showKeyboard = Notification.Name("showKeyboard")
}
class KeyboardSlider: NSObject {
    // variables to hold and process information from the view using this class
    weak var view: UIView?

    @objc func keyboardWillShow(notification: NSNotification) {
        // method to move keyboard up
       // view?.frame.origin.y = 0 - getKeyboardHeight(notification as Notification)
        print("made it to keyboard will show")
    }

    func getKeyboardHeight(_ notification:Notification) -> CGFloat {
        // get exact height of keyboard on all devices and convert to float value to return for use
        let userInfo = notification.userInfo
        let keyboardSize = userInfo![UIKeyboardFrameEndUserInfoKey] as! NSValue
        return keyboardSize.cgRectValue.height
    }

    func subscribeToKeyboardNotifications(view: UIView) {
        // assigning view to class' counterpart
        self.view = view
        // when UIKeyboardWillShow do keyboardWillShow function
        NotificationCenter.default.addObserver(self, selector: #selector(keyboardWillShow(notification:)), name: .UIKeyboardWillShow, object: nil)
    }

    func unsubscribeFromKeyboardNotifications() {
        NotificationCenter.default.removeObserver(self, name: .UIKeyboardWillShow, object: nil)
    }


}

0 个答案:

没有答案