2016-04-29 6 views
2

Ich bin mir nicht sicher, ob ich meine Frage ziemlich gut zusammengestellt habe. Wenn man bedenkt, es zu verbessern, tun Sie es :) aber kurz das ist, was ich meine:Wie erstellt man Abschnitte mit Kopfzeilen links von Zellen mit UICollectionView?

enter image description here

  • Jede Orange Box ist der Header neuen Abschnitt Box (Breite und Höhe ist statisch) .
  • Dies wird mit den Abschnitten
  • Die gelben Zellen immer den Rest des Bildschirms in der Breite, und verfügen über eine automatische Dimension Höhe (je nach Länge des Textes) zu abgerufenen Ergebnisse Controller verbunden werden.

Bitte sagen Sie mir:

  1. Ist es möglich, mit UICollectionView dies überhaupt zu tun?
  2. Wie automatische Höhe Abmessungen für gelb Zellen anordnen?
  3. Wie float gelb diejenigen wie es ist auf dem Bild?

Antwort

2

Ich denke, Sie können UITableViewController verwenden, um etwas ähnliches zu tun.

enter image description here

Die Idee ist:

  • Passen Sie die Zelle als zwei Teile, links und rechts.
  • Die linke des ersten Elements eines Abschnitts wird für Abschnittsüberschrift verwendet, beachten Sie, dass Clip Subviews von CellView und ContentView deaktiviert werden sollte.
  • Die Höhe des letzten Elements eines Abschnitts muss angepasst werden, damit keine Überlappung entsteht. Hier

ist der Beispielcode:

class ViewController: UITableViewController { 

    struct Item { 
     var height: CGFloat = 0 
    } 

    var itemDic: [Int: [Item]]! 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 

     itemDic = [0 : [Item(height: 10), Item(height: 30), Item(height: 50)], 
       1 : [Item(height: 20), Item(height: 10)], 
       2 : [Item(height: 40), Item(height: 30), Item(height: 20)]] 
    } 

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


    override func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
     return itemDic.count 
    } 

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return itemDic[section]!.count 
    } 

    let sectionHeaderHeight: CGFloat = 100 

    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { 

     let section = indexPath.section 
     let row = indexPath.row 
     let items = itemDic[section]! 

     var height = items[row].height 
     if (row == items.count - 1) { 

      var total: CGFloat = 0 
      for i in items { 
       total += i.height + 10 
      } 

      if(sectionHeaderHeight + 10 > total){ 
       height += (sectionHeaderHeight + 10 - total) 
      } 
     } 

     return height + 10 
    } 

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 

     let section = indexPath.section 
     let row = indexPath.row 
     let items = itemDic[section]! 

     let cell = tableView.dequeueReusableCellWithIdentifier("Cell")! 

     let orangeView = cell.viewWithTag(100)! 
     let yellowView = cell.viewWithTag(101)! 

     if(row == 0){ 
      let orangeFrame = orangeView.frame 
      orangeView.frame = CGRect(origin: orangeFrame.origin, size: CGSize(width: orangeFrame.width, height: sectionHeaderHeight)) 
     } 

     let yellowFrame = yellowView.frame 
     let height = items[row].height 
     yellowView.frame = CGRect(origin: yellowFrame.origin, size: CGSize(width: yellowFrame.width, height: height)) 

     return cell 
    } 

    override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { 
     let orangeView = cell.viewWithTag(100)! 
     let yellowView = cell.viewWithTag(101)! 

     let orangeFrame = orangeView.frame 

     print(orangeFrame) 

     let yellowFrame = yellowView.frame 

     print(yellowFrame) 
    } 
} 

Update: Eigentlich gibt es einen Fehler in obigen Lösung, wenn bis der erste Abschnitt nach oben Scrollen verschwindet, und dann werden Sie es zu sehen bekommen neu gerendert und das Layout wird gebrochen.

Es gibt einen besseren Weg, dies zu tun.

Fügen Sie eine innere Ansicht (orange) in die headerView hinzu, die über die TableCells gerendert wird. Denken Sie daran, die Höhe der Kopfzeile> 0 festzulegen. In diesem Fall muss die Zelle nur den rechten Teil (gelb) enthalten. Noch müssen Sie die Höhe des letzten Artikels anpassen.

Beispielcode:

class ViewController: UITableViewController { 

    struct Item { 
     var height: CGFloat = 0 
    } 

    var itemDic: [Int: [Item]]! 

    override func viewDidLoad() { 
     super.viewDidLoad() 
     // Do any additional setup after loading the view, typically from a nib. 

     itemDic = [0 : [Item(height: 10), Item(height: 30), Item(height: 50), Item(height: 20)], 
       1 : [Item(height: 20), Item(height: 10)], 
       2 : [Item(height: 40), Item(height: 30), Item(height: 20), Item(height: 30)]] 
    } 

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


    override func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
     return itemDic.count 
    } 

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return itemDic[section]!.count 
    } 

    let sectionHeaderHeight: CGFloat = 100 
    let innerViewOffset: CGFloat = 10 
    override func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 

     // Must > 0 
     return innerViewOffset 
    } 

    override func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 
     let view = UIView(frame: CGRect()) 

     view.backgroundColor = UIColor.blueColor() 

     let innerView = UIView(frame: CGRect(x: 0, y: innerViewOffset, width: 100, height: 100)) 
     innerView.backgroundColor = colorForSection(section) 
     view.addSubview(innerView) 

     return view 
    } 

    func colorForSection(section: Int) -> UIColor { 
     let colors = [UIColor.greenColor(), UIColor.redColor(), UIColor.purpleColor()] 

     return colors[section] 
    } 

    override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat { 

     let section = indexPath.section 
     let row = indexPath.row 
     let items = itemDic[section]! 

     var height = items[row].height 
     if (row == items.count - 1) { 

      var total: CGFloat = 0 
      for i in items { 
       total += i.height + 10 
      } 

      if(sectionHeaderHeight + 10 > total){ 
       height += (sectionHeaderHeight + 10 - total) 
      } 
     } 

     return height + 10 
    } 

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 

     let cell = tableView.dequeueReusableCellWithIdentifier("Cell")! 

     return cell 
    } 
} 
+0

Wenn ich gut verstehe ... das einzige Problem damit für mich wird entstehen, wenn ich versuche, Höhe der Zellen in Abschnitt zu schätzen, um die Höhe der letzten Zelle in Abschnitt zu bestimmen. Habe ich recht? –

+0

Eigentlich gibt es einen Bug, mit dem ich nicht umgehen kann. Wenn man nach oben scrollt, sieht man, dass der erste Teil neu gerendert wird und der erste Teil abgedeckt wird, das ist nicht das was du willst. Ich finde eine bessere Lösung für Sie. Siehe die Änderung. – dichen

0

Ich glaube nicht, dass Sie diesen Abschnitt tun können header.but Sie es mit Kollektion cell.Adjust die Größe der anderen Zellen entsprechend tun.

+0

Es wird nicht sehr komfortabel es Controller mit abgerufenen Ergebnisse zu arbeiten. –

Verwandte Themen