2016-10-19 15 views
16

Vì vậy, đây là một vấn đề thú vị, chúng tôi tìm thấy với UICollectionViewFlowLayout trên iOS 10 (vẫn còn là một vấn đề ngày 11) và sử dụng UICollectionViewFlowLayoutAutomaticSize cho estimatedItemSize.iOS 10/11 UICollectionViewFlowLayout sử dụng kết quả UICollectionViewFlowLayoutAutomaticSize theo quan điểm bổ sung chân lệch

Chúng tôi thấy rằng việc sử dụng UICollectionViewFlowLayoutAutomaticSize về kết quả estimatedItemSize trong giao diện bổ sung chân lơ lửng phía trên vài tế bào đáy. (Red/Pink là tiêu đề, màu xanh lá cây là chân.)

UICollectionViewFlowLayoutAutomaticSize problem enter image description here

đây là mã VC của một ứng dụng mẫu:

import UIKit 

class ViewController: UIViewController { 

    // MARK: Properties 

    let texts: [String] = [ 
     "This is some text", 
     "This is some more text", 
     "This is even more text" 
    ] 

    // MARK: Outlets 

    @IBOutlet var collectionView: UICollectionView! { 
     didSet { 
      self.collectionView.backgroundColor = .orange 
     } 
    } 

    // MARK: Lifecycle 

    override func viewDidLoad() { 

     super.viewDidLoad() 

     // Layout 
     let layout = UICollectionViewFlowLayout() 
     layout.scrollDirection = .vertical 
     if #available(iOS 10.0, *) { 
      layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize 
     } else { 
      layout.estimatedItemSize = CGSize(width: self.collectionView.bounds.width, height: 50) 
     } 
     self.collectionView.collectionViewLayout = layout 

     // Register Cells 
     self.collectionView.register(UINib(nibName: "TextCell", bundle: nil), forCellWithReuseIdentifier: String(describing: TextCell.self)) 
     self.collectionView.register(UINib(nibName: "SectionHeader", bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionHeader, withReuseIdentifier: String(describing: SectionHeader.self)) 
     self.collectionView.register(UINib(nibName: "SectionFooter", bundle: nil), forSupplementaryViewOfKind: UICollectionElementKindSectionFooter, withReuseIdentifier: String(describing: SectionFooter.self)) 

     self.collectionView.reloadData() 
    } 
} 

// MARK: - UICollectionViewDelegateFlowLayout Methods 

extension ViewController: UICollectionViewDelegateFlowLayout { 

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

     return CGSize(width: self.collectionView.bounds.width, height: 90) 
    } 

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

     return CGSize(width: self.collectionView.bounds.width, height: 90) 
    } 
} 

// MARK: - UICollectionViewDataSource Methods 

extension ViewController: UICollectionViewDataSource { 

    public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 

     return self.texts.count 
    } 

    func numberOfSections(in collectionView: UICollectionView) -> Int { 
     return 1 
    } 

    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 

     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: TextCell.self), for: indexPath) 

     if let textCell = cell as? TextCell { 

      let text = self.texts[indexPath.row] 
      textCell.configure(text: text) 
     } 

     return cell 
    } 

    func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView { 

     switch kind { 
     case UICollectionElementKindSectionHeader: 

      return collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: String(describing: SectionHeader.self), for: indexPath) 

     case UICollectionElementKindSectionFooter: 

      return collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: String(describing: SectionFooter.self), for: indexPath) 

     default: 
      return UICollectionReusableView() 
     } 
    } 
} 

// MARK: - UICollectionViewDelegate Methods 

extension ViewController: UICollectionViewDelegate { 

} 

có ai quản lý để có được UIColle ctionViewFlowLayoutAutomaticSize hoạt động trên iOS 10 với các chế độ xem đầu trang và chân trang bổ sung? Nếu tôi thêm kích thước vào tệp ước tínhItemSize thì nó có vẻ hoạt động, nhưng tôi muốn biết nếu có lỗi trong việc sử dụng tính năng iOS 10 mới hoặc nếu tôi đang sử dụng nó không chính xác.

Lỗi nộp cho Apple có ID:

CẬP NHẬT: Đây vẫn dường như là một vấn đề trên 10,3 Beta 1

UPDATE 2: Đây vẫn dường như là một vấn đề trong iOS 11 Beta 1

+0

Bạn cần cung cấp ước tínhItemSize afaik. Nó không phải là tùy chọn – Lefteris

+0

Nó đang được thiết lập, nó chỉ khác nhau giữa iOS 10 và trước đó. – dlbuckley

+0

Bạn có tìm thấy giải pháp cho việc này không? –

Trả lời

0

Tôi gặp phải vấn đề tương tự. UICollectionViewFlowLayoutAutomaticSize không hoạt động cho các chế độ xem bổ sung. Sử dụng UICollectionViewDelegateFlowLayout để cung cấp cho kích thước một cách rõ ràng. Nó tốt hơn để tính toán kích thước và sử dụng các đại biểu như tính toán kích thước tự động gây ra tụt hậu, ở lần.

sử dụng referenceSizeForHeaderInSectionreferenceSizeForFooterInSection phương thức ủy quyền để cung cấp cho kích thước đầu trang và chân trang một cách rõ ràng.

+0

Cảm ơn bạn đã nhập.Mặc dù nếu bạn nhìn vào mã tôi đã đăng, tôi đang sử dụng phương thức ủy nhiệm 'referenceSizeForHeaderInSection' và' referenceSizeForFooterInSection' để đặt chiều cao là 90pts. Hay bạn đang đề cập đến cái gì khác? – dlbuckley

+0

Mã là tốt. Loại bỏ phần này và thử cho kích thước pf các ô bằng cách sử dụng các phép tính. 'nếu #available (iOS 10,0, *) { layout.estimatedItemSize = UICollectionViewFlowLayoutAutomaticSize } else { layout.estimatedItemSize = CGSize (width: self.collectionView.bounds.width, chiều cao: 50) }' –

+0

Nó hoạt động nếu Tôi không sử dụng 'UICollectionViewFlowLayoutAutomaticSize', nhưng toàn bộ điểm của câu hỏi là hiểu cách' UICollectionViewFlowLayoutAutomaticSize' hoạt động. Giải pháp của chúng tôi đã chuyển kích thước tự động vào cuối giống như đề xuất của bạn, nhưng sẽ vẫn tốt hơn nếu sử dụng định kích thước tự động trong tương lai. – dlbuckley

14

UICollectionViewFlowLayout hỗ trợ bố trí tự động cho các tế bào rất tốt, NHƯNG nó không hỗ trợ nó cho quan điểm bổ sung. Mỗi khi mã bố trí tự động cập nhật khung của ô, nó không có gì với đầu trang và chân trang. Vì vậy, bạn cần phải nói bố cục rằng nó sẽ làm mất hiệu lực đầu trang và chân trang. Và có một phương pháp cho việc này!

Bạn nên ghi đè UICollectionViewLayout 's func invalidationContext(forPreferredLayoutAttributes: UICollectionViewLayoutAttributes, withOriginalAttributes: UICollectionViewLayoutAttributes) và thực hiện việc vô hiệu hóa chế độ xem bổ sung trong đó.

Ví dụ:

override open func invalidationContext(forPreferredLayoutAttributes preferred: UICollectionViewLayoutAttributes, 
     withOriginalAttributes original: UICollectionViewLayoutAttributes) 
       -> UICollectionViewLayoutInvalidationContext { 
    let context: UICollectionViewLayoutInvalidationContext = super.invalidationContext(
      forPreferredLayoutAttributes: preferred, 
      withOriginalAttributes: original 
    ) 

    let indexPath = preferred.indexPath 

    if indexPath.item == 0 { 
     context.invalidateSupplementaryElements(ofKind: UICollectionElementKindSectionHeader, at: [indexPath]) 
    } 

    return context 
} 

Trong ví dụ trên, chúng tôi đang sử dụng bối cảnh huỷ bỏ hiệu lực được cung cấp bởi UICollectionViewFlowLayout để làm mất hiệu lực nhìn tiêu đề bổ sung nếu ô đầu tiên trong phần đã không còn giá trị. Bạn cũng có thể sử dụng phương thức này để làm mất hiệu lực chân trang.

+2

Điều này đã giải quyết được vấn đề cho tôi. Đột nhiên, chế độ xem tiêu đề của tôi đã được định vị chính xác. – MurderDev

+0

Vì lý do của tôi, tôi cần phải vô hiệu hóa chính ô đó bên trong phạm vi 'if' bằng cách gọi' context.invalidateItems (at:) '. – billibala

Các vấn đề liên quan