2017-07-20 50 views
3

最近,我正在嘗試做一些練習項目。因此,我觀看了斯坦福大學CS193P 2017版「開發iOS應用程序」課程。CollectionView在iOS中使用Swift 3的動態高度

現在,我正在做「Smashtag」項目,但是我遇到了一些問題。 我想通過兩個UICollectionViewFlowLayout使用CollectionView在SegmentedControl的每個xib中顯示兩個類型(一個像tableView,另一個顯示一個正方形的圖像)。

我的問題如下:

  1. 如何使CollectionViewCell顯示動態高度一樣的TableView的UITableViewAutomaticDimension?

    而這就是我剛剛試過以下:

    我試圖讓的CollectionView的自動調整設置像TableView中的autoDimension使用UICollectionViewFlowLayoutAutomaticSize。 (@available(iOS的10.0,*))

enum CollectionViewType { 
    case tweet 
    case image 
} 

// MARK: - Decide What Kind Of FlowLayout 
func decideFlowLayout(type: CollectionViewType) -> UICollectionViewFlowLayout { 

    // just for .image type 
    var howManyImageShowing = 3 
    var imageShowingWidth: Double { 
     return Double(self.view.frame.width)/Double(howManyImageShowing) 
    } 

    // .tweet is a type showing like TableViewCell -> this make me confused !! 
    // another type is just showing a image in square -> I have no problem here 
    let estimatedItemSize = type == .tweet ? CGSize(width: self.view.frame.width, height: 155.0) : 
               CGSize(width: imageShowingWidth, height: imageShowingWidth) 

    let collectionViewLayout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() 
    collectionViewLayout.sectionInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0) 

    // --------- Make this setting as TableView does --------- 
    // ------------ Somethis just like this below ------------ 
    /* 
     tableView.estimatedRowHeight = 155.0 
     tableView.rowHeight = UITableViewAutomaticDimension 
    */ 

    collectionViewLayout.estimatedItemSize = estimatedItemSize 
    collectionViewLayout.itemSize = UICollectionViewFlowLayoutAutomaticSize 
    // ------------------------------------------------------- 

    collectionViewLayout.minimumLineSpacing = 0 
    collectionViewLayout.minimumInteritemSpacing = 0 

    return collectionViewLayout 
} 

我CollectionViewCell廈門國際銀行的約束在這裏: enter image description here 但它有錯誤,當我運行這個程序

我不不知道我錯過了什麼或誤解。 enter image description here

  1. 爲什麼這種解決方案將工作?

    我已經尋找這個問題的很多解決方案堆棧溢出,但我只是覺得這,讓我真的很困惑:(

    這個解決方案給視圖寬度約束這是廈門國際銀行CollectionViewCell和設置此約束的常數的價值和它的作品!我無法配置爲什麼寬度約束會使細胞的高度動態的?這讓我真的很困惑,我認爲這是奇怪...

    https://github.com/tttsunny/CollectionViewAutoSizingTest

class Cell: UICollectionViewCell { 
    @IBOutlet weak var headerLabel: UILabel! 
    @IBOutlet weak var descriptionLabel: UILabel! 
    @IBOutlet weak var widthConstraint: NSLayoutConstraint! 

    override func awakeFromNib() { 
     super.awakeFromNib() 
     // Initialization code 
     self.contentView.translatesAutoresizingMaskIntoConstraints = false 
     let screenWidth = UIScreen.main.bounds.size.width 
     widthConstraint.constant = screenWidth - (2 * 12) 
    } 
} 
  • 如何做CollectionViewCell動態高度而不使用UICollectionViewFlowLayoutAutomaticSize。 (@available(iOS 10.0,*))

    因爲我想處理不同的iOS版本不僅在iOS 10中,而且在iOS 10以下。

  • 我真的想在iOS開發和偉大的開發者親,但我還在學習和嘗試。任何答覆,我將不勝感激。

    謝謝!

    回答

    3

    使用下面的代碼根據顯示的文本改變高度:

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, minimumLineSpacingForSectionAt section: Int) -> CGFloat { 
        return 0 
    } 
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize { 
        return CGSizeMake(view.frame.width , 64) 
    } 
    override func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize 
    { 
        let approximateWidthOfContent = view.frame.width - x 
        // x is the width of the logo in the left 
    
        let size = CGSize(width: approximateWidthOfContent, height: 1000) 
    
        //1000 is the large arbitrary values which should be taken in case of very high amount of content 
    
    let attributes = [NSFontAttributeName: UIFont.systemFont(ofSize: 15)]    
    let estimatedFrame = NSString(string: user.bioText).boundingRect(with: size, options: .usesLineFragmentOrigin, attributes: attributes, context: nil) 
    return CGSize(width: view.frame.width, height: estimatedFrame.height + 66)   
    } 
    
    +0

    對不起,你的身高[indexPath.row]是什麼意思? – Kevin

    +0

    它給你當前行的高度 –

    +0

    但我沒有看到你的「高度」聲明在哪裏? – Kevin

    1

    我解決它:)

    我只是試圖計算我的單元格的寬度,並期望在sizeForItemAt功能的高度和其作品!下面

    代碼:

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 
        let imageShowingWidth: CGFloat = self.view.frame.width/CGFloat(self.howManyImageShowing) 
    
        let labelName = "@\(self.tweetShowing[indexPath.row].user.screenName) (\(self.tweetShowing[indexPath.row].user.name))" 
        let labelNameFont: UIFont = UIFont(name: "PingFangTC-Semibold", size: 16)! 
        let labelNameWidth: CGFloat = self.view.frame.width - YourWidthOffSet// (YourWidthOffSet include all images' width and all margins) 
        let labelNameHeight: CGFloat = self.getHeightForLable(labelWidth: labelNameWidth, labelText: labelName, labelFont: labelNameFont) 
    
        let labelContentFont: UIFont = UIFont(name: "PingFangTC-Regular", size: 16)! 
        let labelContentHeight: CGFloat = self.getHeightForLable(labelWidth: labelNameWidth, numberOfLines: 0, labelText: self.tweetShowing[indexPath.row].text, labelFont: labelContentFont) 
    
        let cellHeight: CGFloat = labelNameHeight + labelContentHeight + YourHeightOffSet // (YourHeightOffSet means all margins) 
    
        return self.typeControl.selectedSegmentIndex == 0 ? CGSize(width: self.view.frame.width, height: cellHeight) : CGSize(width: imageShowingWidth, height: imageShowingWidth) 
    } 
    
    func getHeightForLable(labelWidth: CGFloat, numberOfLines: Int = 1, labelText: String, labelFont: UIFont) -> CGFloat { 
        let tempLabel: UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: labelWidth, height: CGFloat.greatestFiniteMagnitude)) 
        tempLabel.numberOfLines = numberOfLines 
        tempLabel.text = labelText 
        tempLabel.font = labelFont 
        tempLabel.sizeToFit() 
        return tempLabel.frame.height 
    } 
    
    0

    所有你需要做的是使該UICollectionView佈局一個IBOutlet什麼, 設置estimatedItemSize爲任意大小, 在你的類,你必須指定單元格的寬度(如果您只想要高度爲動態且寬度爲靜態)和/或高度爲awakeFromNib並禁用translatesAutoresizingMaskIntoConstraints self.contentView.translatesAutoresizingMaskIntoConstraints = false。 所以最終的結果應該是這樣的

    class ProfileViewController: UIViewController { 
        @IBOutlet var collectionView: UICollectionView! 
        @IBOutlet var collectionLayout: UICollectionViewFlowLayout! 
    
    
        var person: Person! 
    
    override func viewDidLoad() { 
         super.viewDidLoad() 
    
         collectionView.register(UINib(nibName: "ProfileCollectionViewCell", bundle: nil), forCellWithReuseIdentifier: "Cell") 
         collectionLayout.estimatedItemSize = CGSize(width: screenWidth * 0.4, height: 1) 
         collectionView.reloadData() 
        } 
    
        func numberOfSections(in collectionView: UICollectionView) -> Int { 
         return 1 
        } 
    
        func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
         return 1 
        } 
    
        func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
         let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "Cell", for: indexPath) as! ProfileCollectionViewCell 
    
         return cell 
        } 
        } 
    

    和你的類應該是這樣的

    class ProfileCollectionViewCell: UICollectionViewCell { 
    @IBOutlet var containerWidthConstraint: NSLayoutConstraint! 
    override func awakeFromNib() { 
         super.awakeFromNib() 
    
         self.contentView.translatesAutoresizingMaskIntoConstraints = false 
         containerWidthConstraint.constant = screenWidth - (2 * 12) 
        } 
        } 
    

    ,這是iOS中的自我上漿一個很好的教程 https://engineering.shopspring.com/dynamic-cell-sizing-in-uicollectionview-fd95f614ef80

    相關問題