2014-10-27 20 views
13

Jestem kompletnym nowicjuszem w programowaniu Swift i iOS, więc będziesz musiał wybaczyć prawdopodobnie proste pytanie.Dodawanie sekcji, oddzielonych datami, do UITableView w Swift

Utworzono tableView wyświetlający zawartość tablicy (łańcuchów) za naciśnięciem jednego przycisku. Teraz chciałbym "pogrupować" te ciągi w sekcje tableView, posortowane według daty.

Bardziej szczegółowo: Gdy użytkownik dotknie przycisku, łańcuch powinien zostać wstawiony w indeksie 0 tablicy i powinien być wyświetlony w sekcji z nagłówkiem dzisiejszych dat. Jeśli w tablicy są wartości starsze niż dzisiejsza, powinny być one wyświetlane w oddzielnej sekcji dla tej daty. Każda sekcja powinna odpowiadać 24-godzinnemu dniu i wyświetlać wszystkie ciągi dodane w tym dniu.

Oto niektóre przykładowy kod z czego się osiągnąć do tej pory:

var testArray[String]() 
var sectionsInTable[String]() 

@IBOutlet weak var testTable: UITableView! 

@IBAction func saveButton(sender: AnyObject) { 

testArray.insert("\(strTest)", atIndex: 0) 
testTable.reloaddata() 

} 

func numberOfSectionsInTableView(tableView: UITableView) -> Int { 

    return sectionsInTable.count 

} 

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{ 

    return testArray.count 

} 

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

    var cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell") 

    cell.textLabel.text = String(testArray[indexPath.row])   

    return cell 
} 

ja naprawdę nie wiem, jak zarządzać część sekcji. Mam nadzieję, że ktoś wskaże mi właściwy kierunek. Dzięki!

Odpowiedz

17

Zwykle robię to z Core Data i NSFetchedResultsController, ponieważ ma wbudowane metody otrzymywania sekcji.

Jednak odpowiem na to pytanie bez korzystania z danych podstawowych. Kod jest trochę zawikłany, ale proszę ...

Najpierw należy utworzyć obiekt, w którym będzie przechowywana zarówno data, jak i tekst. TestArray będzie tablicą tych obiektów, zamiast tablicy String. Na przykład:

Następnie po naciśnięciu przycisku saveButton utworzymy i dodamy obiekt DateTextItem. Dodamy również datę do sectionsInTable, jeśli jeszcze nie istnieje.

@IBAction func saveButton(sender: AnyObject) { 
    let newItem = DateTextItem() 
    newItem.text = "Test \(testArray.count)" 

    // this is for development only 
    // increment the date after 2 records so we can test grouping by date 
    if testArray.count >= (testArray.count/2) { 
     let incrementDate = NSTimeInterval(86400*(testArray.count/2)) 
     newItem.insertDate = NSDate(timeIntervalSinceNow:incrementDate) 
    } 

    testArray.append(newItem) 

    // this next bit will create a date string and check if it's in the sectionInTable 
    let df = NSDateFormatter() 
    df.dateFormat = "MM/dd/yyyy" 
    let dateString = df.stringFromDate(newItem.insertDate) 

    // create sections NSSet so we can use 'containsObject' 
    let sections: NSSet = NSSet(array: sectionsInTable) 

    // if sectionsInTable doesn't contain the dateString, then add it 
    if !sections.containsObject(dateString) { 
     sectionsInTable.append(dateString) 
    } 

    self.tableView.reloadData() 
} 

Następnie stworzyłem funkcję, aby uzyskać elementy w sekcji, ponieważ potrzebujemy jej w kilku miejscach.

func getSectionItems(section: Int) -> [DateTextItem] { 
    var sectionItems = [DateTextItem]() 

    // loop through the testArray to get the items for this sections's date 
    for item in testArray { 
     let dateTextItem = item as DateTextItem 
     let df = NSDateFormatter() 
     df.dateFormat = "MM/dd/yyyy" 
     let dateString = df.stringFromDate(dateTextItem.insertDate) 

     // if the item's date equals the section's date then add it 
     if dateString == sectionsInTable[section] as NSString { 
      sectionItems.append(dateTextItem) 
     } 
    } 

    return sectionItems 
} 

Wreszcie, tutaj jest to, co metody źródłowe Tabela przeglądać dane wyglądać

// MARK: - Table view data source 
override func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
    return sectionsInTable.count 
} 

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return self.getSectionItems(section).count 
} 

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

    // Configure the cell... 
    var cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell") 

    // get the items in this section 
    let sectionItems = self.getSectionItems(indexPath.section) 
    // get the item for the row in this section 
    let dateTextItem = sectionItems[indexPath.row] 

    cell.textLabel.text = dateTextItem.text 

    return cell 
} 

// print the date as the section header title 
override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 
    return sectionsInTable[section] 
} 
+0

Dziękuję bardzo! Spróbuję od razu i pokażę, jak to działa. – maxpetter

+0

Za każdym razem, gdy przewijana jest tabela - działa pętla i inicjowana jest tablica. Nie jestem pewien, czy to świetne rozwiązanie. Musisz raz przygotować listę z obiektami, a następnie użyć jej. –

0

Musisz zrobić tablicę dla każdego dnia (zwanego dayArray [] na przykład) i dodać go do sectionInTable [] i zrobić coś takiego:

func numberOfSectionsInTableView(tableView: UITableView) -> Int { 

    return sectionsInTable.count 

} 

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int{ 

    return sectionsInTable.objectAtIndex(section).count 

} 

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

    var cell = UITableViewCell(style: UITableViewCellStyle.Default, reuseIdentifier: "Cell") 

    cell.textLabel.text = String(sectionInTable.objectAtIndex(indexPath.section).objectAtIndex(indexPath.row))   

    return cell 
} 

Niestety jeśli zrobiłem błędy, jestem Nie jestem zaznajomiony z szybkim, ale myślę, że pomysł może pomóc.

+0

gdzie jest metoda dodawania tytuł w sekcji – SARATH

17

byłem w potrzebie coś podobnego, a jednocześnie Ron Fessler „s rozwiązanie działa, gdy istnieje wiele odcinków/wiersze, załadowanie danych zajęło bardzo dużo czasu, a nawet później nie reagowało zbyt szybko. Główny problem tam Myślę, że jest funkcja getSectionItems, ponieważ zawsze będzie przejść przez wszystkie elementy ...

Moje rozwiązanie: Metody DataSource

struct TableItem { 
    let title: String 
    let creationDate: NSDate 
} 

var sections = Dictionary<String, Array<TableItem>>() 
var sortedSections = [String]() 

@IBAction func saveButton(sender: AnyObject) { 

    let date:String = "your date in string..." 

    //if we don't have section for particular date, create new one, otherwise we'll just add item to existing section 
    if self.sections.indexForKey(date) == nil { 
     self.sections[date] = [TableItem(title: name, creationDate: date)] 
    } 
    else { 
     self.sections[date]!.append(TableItem(title: name, creationDate: date)) 
    } 

    //we are storing our sections in dictionary, so we need to sort it 
    self.sortedSections = self.sections.keys.array.sorted(>) 
    self.tableView.reloadData() 
} 

Tableview:

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

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

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

    var cell = tableView.dequeueReusableCellWithIdentifier("Cell")   

    let tableSection = sections[sortedSections[indexPath.section]] 
    let tableItem = tableSection![indexPath.row] 

    cell.titleLabel?.text = tableItem.title 

    return cell 
} 

override func tableView(tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 
    return sortedSections[section] 
} 
+0

Jest to ładne proste rozwiązanie, które można łatwo wdrożyć na istniejącym TableView. Wielkie dzięki. – tonyedwardspz

+0

Ciągle pojawia się błąd ataku: Indeks poza zakresem, gdy używam [sekcja] w delegacji na tablicy. – Skovie

+0

@Skovie sprawdź, czy 'sekcja' faktycznie znajduje się w przedziale' sortedSections' przed 'return'. Np .: 'jeśli sekcja

Powiązane problemy