2017-01-20 3 views
4

Ich versuche, eine Today Extension Sammlung mit der Angabe der Elemente pro Zeile von 3 Elemente und auch mit der Einstellung der Abschnitt Einsätze für mit 20 für oben, links, unten und Recht. Wenn ich dies in einer Single-View-Anwendung mache, ist alles wie erwartet, aber wenn ich programmatisch dasselbe für die Today-Erweiterung mache, sieht die Kollektionsansicht anders aus, besonders der Raum rechts und unten scheint nicht wie in der Single-View-Anwendung zu sein. Was ist der Grund, warum es diesen Unterschied gibt? Ich erwartete das gleiche Verhalten für die Today-Erweiterung wie in der Single-View-Anwendung.Heute Erweiterung mit UICollectionView unterschiedliches Verhalten im Vergleich zu Single View Anwendung

Um mein Problem besser zu verstehen, unten ist der Code, der Single View-Anwendung und die Heute-Erweiterung, die beide mit Screenshots:

Viewcontroller der Single View Anwendung:

import UIKit 

class ViewController: UIViewController, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource { 

    var collectionView: UICollectionView! 
    let sectionInsets = UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20) 
    let itemsPerRow: CGFloat = 3 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() 
     layout.sectionInset = sectionInsets 

     collectionView = UICollectionView(frame: view.frame, collectionViewLayout: layout) 
     collectionView.dataSource = self 
     collectionView.delegate = self 
     collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cellId") 
     collectionView.backgroundColor = .white 
     view.addSubview(collectionView) 
    } 

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
     return 6 
    } 

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) 
     cell.backgroundColor = .blue 

     return cell 
    } 

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 
     let paddingSpace = sectionInsets.left * (itemsPerRow + 1) 
     let availableWidth = view.frame.width - paddingSpace 
     let widthPerItem = availableWidth/itemsPerRow 

     return CGSize(width: widthPerItem, height: widthPerItem) 
    } 
} 

Screenshots der Einzelansicht Anwendung:

enter image description here

TodayViewController der Heute-Erweiterung:

import UIKit 
import NotificationCenter 

class TodayViewController: UIViewController, NCWidgetProviding, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource { 

    var collectionView: UICollectionView! 
    let sectionInsets = UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20) 
    let itemsPerRow: CGFloat = 3 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     extensionContext?.widgetLargestAvailableDisplayMode = .expanded 

     let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() 
     layout.sectionInset = sectionInsets 

     collectionView = UICollectionView(frame: view.frame, collectionViewLayout: layout) 
     collectionView.dataSource = self 
     collectionView.delegate = self 
     collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cellId") 
     collectionView.backgroundColor = .white 
     view.addSubview(collectionView) 
    } 

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
     return 6 
    } 

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) 
     cell.backgroundColor = .blue 

     return cell 
    } 

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 
     let paddingSpace = sectionInsets.left * (itemsPerRow + 1) 
     let availableWidth = view.frame.width - paddingSpace 
     let widthPerItem = availableWidth/itemsPerRow 

     return CGSize(width: widthPerItem, height: widthPerItem) 
    } 

    func widgetActiveDisplayModeDidChange(_ activeDisplayMode: NCWidgetDisplayMode, withMaximumSize maxSize: CGSize) { 
     // toggle height in case of more/less button event 
     if activeDisplayMode == .compact { 
      self.preferredContentSize = CGSize(width: 0, height: 110) 
     } else { 
      self.preferredContentSize = CGSize(width: 0, height: 220) 
     } 
    } 
} 

Screenshots der Heute-Erweiterung:

enter image description here

+1

Ich glaube, dass die Berechnung von 'availableWidth' nicht funktioniert, da' view.frame.width' keine endgültige Dimension haben muss. Sehen Sie sich einfach den Wert in 'view.frame.width' an. – Sulthan

+0

@Sultan Sie hatten Recht. Der Wert in viewDidLoad ist 375.0 und in viewDidAppear ist es 359.0 – ronatory

Antwort

4

ich mein eigenes Problem mit Hilfe dieser answer gelöst. Die Lösung so weit, dass ich ein Setup nur die Sammlung Ansicht in viewDidAppear(_:) statt viewDidLoad() im TodayViewController des Heute-Extension (der Raum nach unten zur Zeit so aussieht, weil ich eine fix Höhe von 220 eingestellt):

import UIKit 
import NotificationCenter 

class TodayViewController: UIViewController, NCWidgetProviding, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource { 

    var collectionView: UICollectionView! 
    let sectionInsets = UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20) 
    let itemsPerRow: CGFloat = 3 

    override func viewDidAppear(_ animated: Bool) { 
     super.viewDidAppear(animated) 

     extensionContext?.widgetLargestAvailableDisplayMode = .expanded 

     let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() 
     layout.sectionInset = sectionInsets 

     collectionView = UICollectionView(frame: view.frame, collectionViewLayout: layout) 
     collectionView.dataSource = self 
     collectionView.delegate = self 
     collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cellId") 
     collectionView.backgroundColor = .white 
     view.addSubview(collectionView) 
    } 

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
     return 6 
    } 

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) 
     cell.backgroundColor = .blue 

     return cell 
    } 

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 
     let paddingSpace = sectionInsets.left * (itemsPerRow + 1) 
     let availableWidth = view.frame.width - paddingSpace 
     let widthPerItem = availableWidth/itemsPerRow 

     return CGSize(width: widthPerItem, height: widthPerItem) 
    } 

    func widgetActiveDisplayModeDidChange(_ activeDisplayMode: NCWidgetDisplayMode, withMaximumSize maxSize: CGSize) { 
     // toggle height in case of more/less button event 
     if activeDisplayMode == .compact { 
      self.preferredContentSize = CGSize(width: 0, height: 110) 
     } else { 
      self.preferredContentSize = CGSize(width: 0, height: 220) 
     } 
    } 
} 

Jetzt bekomme ich das gleiche Ergebnis wie in der Single View Anwendung:

enter image description here

Update:

Unfort Die Lösung von oben hatte immer noch ein nicht zu erwartendes Verhalten. Wenn die Today Extension vor dem Build in einem erweiterten Zustand war, sieht es wie oben beschrieben aus wie oben beschrieben. Das Problem ist, wenn es vor dem Bau in einem zusammengeklappten Zustand ist, und ich möchte um die Erweiterung zu erweitern, sieht das Ergebnis wie folgt aus (die gespreizte Teil der Sammlung Ansicht wird abgesägt gerade):

enter image description here

Die Lösung für dieses Problem ist bisher die anfängliche Rahmen der Sammlung im Hinblick auf .zero und stellen Sie den Rahmen in viewWillLayoutSubviews() wie folgt festgelegt:

import UIKit 
import NotificationCenter 

class TodayViewController: UIViewController, NCWidgetProviding, UICollectionViewDelegateFlowLayout, UICollectionViewDataSource { 

    var collectionView: UICollectionView! 
    let sectionInsets = UIEdgeInsets(top: 20, left: 20, bottom: 20, right: 20) 
    let itemsPerRow: CGFloat = 3 

    override func viewDidAppear(_ animated: Bool) { 
     super.viewDidAppear(animated) 

     extensionContext?.widgetLargestAvailableDisplayMode = .expanded 

     let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout() 
     layout.sectionInset = sectionInsets 

     collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout) 
     collectionView.dataSource = self 
     collectionView.delegate = self 
     collectionView.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "cellId") 
     collectionView.backgroundColor = .white 
     view.addSubview(collectionView) 
    } 

    override func viewWillLayoutSubviews() { 
     let frame = view.frame 
     collectionView?.frame = CGRect(x: frame.origin.x, y: frame.origin.y, width: frame.size.width, height: frame.size.height) 
    } 

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { 
     return 6 
    } 

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { 
     let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cellId", for: indexPath) 
     cell.backgroundColor = .blue 

     return cell 
    } 

    func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize { 
     let paddingSpace = sectionInsets.left * (itemsPerRow + 1) 
     let availableWidth = view.frame.width - paddingSpace 
     let widthPerItem = availableWidth/itemsPerRow 

     return CGSize(width: widthPerItem, height: widthPerItem) 
    } 

    func widgetActiveDisplayModeDidChange(_ activeDisplayMode: NCWidgetDisplayMode, withMaximumSize maxSize: CGSize) { 
     // toggle height in case of more/less button event 
     if activeDisplayMode == .compact { 
      self.preferredContentSize = CGSize(width: 0, height: 110) 
     } else { 
      self.preferredContentSize = CGSize(width: 0, height: 220) 
     } 
    } 
} 

Jetzt ist das Verhalten wie erwartet, wie in der ersten Folge Screenshot auch wenn die gezeigte Heute war die Erweiterung zum ersten Mal zusammengebrochen.

Verwandte Themen