when I try to create a generic class which implement UICollectionViewDataSource in swift it say that my class does not conform to protocol (and sometime Xcode crash).
Does it mean that we can't create generic data provider for UICollectionView and that we have to duplicate code ?
Here is the generic code :
// Enum protocol
protocol OptionsEnumProtocol
{
typealias T
static var allValues:[T] {get set}
var description: String {get}
func iconName() -> String
}
// enum : list of first available options
enum Options: String, OptionsEnumProtocol
{
typealias T = Options
case Color = "Color"
case Image = "Image"
case Shadow = "Shadow"
static var allValues:[Options] = [Color, Image, Shadow]
var description: String {
return self.rawValue
}
func iconName() -> String
{
var returnValue = ""
switch(self)
{
case .Color: returnValue = "color_icon"
case .Image: returnValue = "image_icon"
case .Shadow: returnValue = "shadow_icon"
}
return returnValue
}
}
// class to use as the uicollectionview datasource and delegate
class OptionsDataProvider<T>: NSObject, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
{
private let items = T.allValues
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return items.count
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(OptionsCellReuseIdentifier, forIndexPath: indexPath) as! GenericIconLabelCell
let item = self.items[indexPath.row]
// Configure the cell
cell.iconFileName = item.iconName()
cell.labelView.text = item.description
return cell
}
}
But because it failed I have to use this non generic form instead :
enum Options: String
{
case Color = "Color"
case Image = "Image"
case Shadow = "Shadow"
static var allValues:[Options] = [Color, Image, Shadow]
var description: String {
return self.rawValue
}
func iconName() -> String
{
var returnValue = ""
switch(self)
{
case .Color: returnValue = "color_icon"
case .Image: returnValue = "image_icon"
case .Shadow: returnValue = "shadow_icon"
}
return returnValue
}
}
class OptionsDataProvider: NSObject, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
{
private let items = Options.allValues
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return items.count
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(OptionsCellReuseIdentifier, forIndexPath: indexPath) as! GenericIconLabelCell
let item = self.items[indexPath.row]
// Configure the cell
cell.iconFileName = item.iconName()
cell.labelView.text = item.description
return cell
}
}
which obligate me to duplicate the class for each enum type I have.
Exact error :
You are right, it is not possible to write a generic class. However, I have found a workaround. It doesn't use enums and so maybe you don't find it very useful. However, it achieves what you want - you are getting a collection view data source which can be used with different classes providing necessary data. Here is the code:
protocol OptionsProviderProtocol
{
func allValues() -> [OptionsItem]
}
class OptionsItem:NSObject {
let itemDescription:String
let iconName:String
init(iconName:String,description:String) {
self.itemDescription = description
self.iconName = iconName
}
}
// class stores first available options
class Options: NSObject, OptionsProviderProtocol
{
let color = OptionsItem(iconName: "color_icon", description: "Color")
let image = OptionsItem(iconName: "image_icon", description: "Image")
let shadow = OptionsItem(iconName: "shadow_icon", description: "Shadow")
func allValues() -> [OptionsItem] {
return [color, image, shadow]
}
}
// class to use as the uicollectionview datasource and delegate
class OptionsDataProvider: NSObject, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout
{
private var items:[OptionsItem] = []
convenience init(optionsProvider:OptionsProviderProtocol) {
self.items = optionsProvider.allValues()
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
return items.count
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
{
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(OptionsCellReuseIdentifier, forIndexPath: indexPath) as! GenericIconLabelCell
let item = self.items[indexPath.row]
// Configure the cell
cell.iconFileName = item.iconName()
cell.labelView.text = item.description
return cell
}
}
If you have any questions please let me know.
When you inherit from a protocol you must implement all required methods. Swift 2 will change this somewhat. Perhaps you really want to inherit from a class.
I had the similar problem/question when I was trying to inherit Generic class from NSOperation class. xCode didn't give me a compile error because there were no protocols involved, instead my override func main() was simply never called :)
Anyway... If you follow workaround that mr. Topal Sergey advised, you can achieve exactly what you want relatively easily.
class ViewController: UIViewController {
#IBOutlet weak var collectionView: UICollectionView?
private var defaultDataProvider = OptionsDataProvider<Options>()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
collectionView?.delegate = defaultDataProvider
collectionView?.dataSource = defaultDataProvider
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
// Enum protocol
protocol OptionsEnumProtocol {
static var allValues: [OptionsEnumProtocol] {get set}
var description: String {get}
func iconName() -> String
}
// enum : list of first available options
enum Options: String, OptionsEnumProtocol {
case Color = "Color"
case Image = "Image"
case Shadow = "Shadow"
static var allValues: [OptionsEnumProtocol] = [Color, Image, Shadow]
var description: String {
return self.rawValue
}
func iconName() -> String
{
var returnValue = ""
switch(self)
{
case .Color: returnValue = "color_icon"
case .Image: returnValue = "image_icon"
case .Shadow: returnValue = "shadow_icon"
}
return returnValue
}
}
class OptionsDataProviderWrapper: NSObject, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
// MARK: protocols' funcs
final func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return wrapperCollectionView(collectionView, numberOfItemsInSection: section)
}
final func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
return wrapperCollectionView(collectionView, cellForItemAtIndexPath: indexPath)
}
// MARK: for override
func wrapperCollectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 0
}
func wrapperCollectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
return UICollectionViewCell()
}
}
class OptionsDataProvider<T: OptionsEnumProtocol>: OptionsDataProviderWrapper {
private let items = T.allValues
override func wrapperCollectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return items.count
}
override func wrapperCollectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("reuseId", forIndexPath: indexPath) as! GenericIconLabelCell
let item = self.items[indexPath.row]
cell.labelView?.text = item.description
return cell
}
}
class GenericIconLabelCell: UICollectionViewCell {
#IBOutlet weak var labelView: UILabel?
}
The key here is to create OptionsDataProviderWrapper that is not a generic and implements all your protocols. The only thing that it does - it redirects calls to another functions like func wrapperCollectionView...
Now you can inherit your Generic class from this OptionsDataProviderWrapper and override that wrapper functions.
Note: you have to override exactly wrapper functions because native func collectionView... functions will not be called in your generic subclass similarly to my issue with NSOperation. That's why I marked native functions with final.
Related
I want to create a UITableViewController that accepts an enum as it's data source.
The thing is, I have quite a few enums that I want it to be able to handle.
I created a protocol called TableViewSelectable and created some enums that conform to it like so:
protocol TableViewSelectable {
}
enum Genders: Int, TableViewSelectable {
case male = 0, female
static let allKeys = [male, female]
static let allNames = [male.getName, female.getName]
var getName: String {
switch self {
case .male:
return "Male"
case .female:
return "Female"
}
}
}
enum Goals: Int, TableViewSelectable {
case gainMuscleMass, getTrimFit, loseWeight
static let allKeys = [gainMuscleMass, getTrimFit, loseWeight]
static let allNames = [gainMuscleMass.getName, getTrimFit.getName, loseWeight.getName]
var getName: String {
switch self {
case .gainMuscleMass:
return "Gain muscle mass"
case .getTrimFit:
return "Get trim & fit"
case .loseWeight:
return "Lose weight"
}
}
}
And I have created an instance variable on my UITableViewController like so:
class ChoiceListTableViewController: UITableViewController {
var data: TableViewSelectable?
}
The problem is I have no idea how to go from here.
What I want to have is the option to give that UITableViewController any enum that conforms to TableViewSelectable in order to use as its data source.
I want to access it on the UITableViewController like this:
final class ChoiceListTableViewController: UITableViewController {
var data: TableViewSelectable?
// MARK: Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
self.clearsSelectionOnViewWillAppear = false
}
}
// MARK: Table View Data Source & Delegate
extension ChoiceListTableViewController {
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.allKeys.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ChoiceTableViewCell", for: indexPath)
cell.textLabel?.text = data.allNames[indexPath.row]
return cell
}
}
Help please? :)
The issue with your current implementation is that the allKeys and allNames static properties that you should be using in your UITableViewDataSource method are not part of the TableViewSelectable protocol, so you cannot access them using the data variable.
You should modify your protocol to include these.
protocol TableViewSelectable {
static var allKeys: [TableViewSelectable] {get}
static var allNames: [String] {get}
}
You also need to modify your enums conforming to it accordingly.
enum Genders: Int, TableViewSelectable {
case male = 0, female
static let allKeys:[TableViewSelectable] = [male, female]
static let allNames = [male.getName, female.getName]
var getName: String {
switch self {
case .male:
return "Male"
case .female:
return "Female"
}
}
}
enum Goals: Int, TableViewSelectable {
case gainMuscleMass, getTrimFit, loseWeight
static let allKeys:[TableViewSelectable] = [gainMuscleMass, getTrimFit, loseWeight]
static let allNames = [gainMuscleMass.getName, getTrimFit.getName, loseWeight.getName]
var getName: String {
switch self {
case .gainMuscleMass:
return "Gain muscle mass"
case .getTrimFit:
return "Get trim & fit"
case .loseWeight:
return "Lose weight"
}
}
}
Then you can simply use data.allKeys and data.allNames to access the corresponding element of these arrays in your data source methods.
class ChoiceListTableViewController: UITableViewController {
var data:TableViewSelectable.Type! // make sure that this is actually initialized before accessing it
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return data.allKeys.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "id", for: indexPath)
cell.textLabel?.text = data.allNames[indexPath.row]
return cell
}
}
This code right here display a array on a collection view. It works exactly how I want it to.
import UIKit
import CoreData
class collectionVIEW: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource{
var sam = ["3","j"]
var users = [User]()
#IBOutlet var theIssues: UICollectionView!
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return sam.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! whyCollectionViewCell
// cell.general.text = users[indexPath.row].userName
cell.general.text = sam[indexPath.row]
return cell
}
}
In my 2nd code. The code is slightly alerted to call core data and display on the cells. As you can see in the photo there are no cells visible. All I want to do is have the core data be displayed exactly how I was able to do in the first code set.
import UIKit
import CoreData
class collectionVIEW: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource{
var sam = ["3","j"]
var users = [User]()
#IBOutlet var theIssues: UICollectionView!
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return users.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! whyCollectionViewCell
cell.general.text = users[indexPath.row].userName
// cell.general.text = sam[indexPath.row]
return cell
}
}
CORE DATA
import UIKit
import CoreData
class cdHandler: NSObject {
private class func getContext() -> NSManagedObjectContext {
let appdeleagetzz = UIApplication.shared.delegate as! AppDelegate
return appdeleagetzz.persistentContainer.viewContext
}
class func saveObject(userName: String) -> Bool {
let context = getContext()
let entity = NSEntityDescription.entity(forEntityName: "User", in: context)
let managedObject = NSManagedObject(entity: entity!, insertInto: context)
managedObject.setValue(userName, forKey: "userName")
do {
try context.save()
return true
} catch {
return false
}
}
class func fetchObject() -> [User]? {
let context = getContext()
var users: [User]? = nil
do {
users = try context.fetch(User.fetchRequest())
return users
} catch {
return users
}
}
}
First of all do not return an optional in fetchObject(), return an empty array on failure:
class func fetchObject() -> [User] {
do {
let context = getContext()
return try context.fetch(User.fetchRequest())
} catch {
return [User]()
}
}
Second of all, to answer the question, you have to call fetchObject() in viewDidLoad to load the data
func viewDidLoad() {
super.viewDidLoad()
users = cdHandler.fetchObject()
theIssues.reloadData()
}
Note: Please conform to the naming convention that class names start with a capital letter.
i am a beginner to the json parsing terminology. i am actually trying to fetch data from a json file that is stored locally in my swift project. i have done all the things correct and can fetch data presently. But, i am unable to create an array of objects(objects will be created based on the set of values coming from the json file) . and then use that array in a view controller(CompanyViewController.swift) class. i have written my json parsing code in a different class(CompanyHandler.swift here..) and all the fields have been initialized in another swift class(Company.swift here..).
My CompanyViewController.swift controller file is as following:
class CompanyViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
#IBOutlet var collectionView: UICollectionView!
override func viewDidLoad() {
super.viewDidLoad()
var customCollectionViewCell = CustomCollectionViewCell()
collectionView.registerNib(UINib(nibName: "CustomCollectionViewCell", bundle:nil), forCellWithReuseIdentifier: "CustomCollectionViewCell")
collectionView!.multipleTouchEnabled = true
collectionView!.backgroundColor = UIColor.whiteColor()
self.view.addSubview(collectionView!)
AppEngine().getCompanyDetails()
}
func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
var cell = collectionView.cellForItemAtIndexPath(indexPath) as CustomCollectionViewCell
// cell.customImageView?.image = UIImage(named: "\(array[indexPath.row])")
AppEngine().getCompanyDetails()
// if ((cell.selected) && (indexPath.row == 0)) {
// var vc: AbcViewController = AbcViewController(nibName: "AbcViewController", bundle: nil)
// self.navigationController?.pushViewController(vc, animated: true)
// }
}
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
var abc = CGSize(width: collectionView.frame.size.width,height: collectionView.frame.size.height/2)
return abc
}
func collectionView(collectionView: UICollectionView, shouldHighlightItemAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
func collectionView(collectionView: UICollectionView, shouldSelectItemAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 15
}
func collectionView(collectionView: UICollectionView, shouldShowMenuForItemAtIndexPath indexPath: NSIndexPath) -> Bool {
return true
}
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier("CustomCollectionViewCell", forIndexPath: indexPath) as CustomCollectionViewCell
cell.customImageView?.image = UIImage(named: "image1.png")
cell.customLabel?.text = "\(indexPath.row)"
return cell
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
My Company.swift controller file is as following:
class Company {
var companyID: String
var companyName: String
var companyAddress: String
var companyWebAddress: String
var companyFB_Address: String
var companyTWT_Handle: String
var companyLI_Address: String
var aboutUs: String
var email_ID: String
var ivrNo: String
// var projects: NSMutableArray = ["Project"]
// var projectStatus: String
init(companyID: String, companyName: String,companyAddress: String, companyWebAddress: String, companyFB_Address: String, companyTWT_Handle: String, companyLI_Address: String, aboutUs: String, email_ID: String, ivrNo: String)
{
self.companyID = companyID
self.companyName = companyName
self.companyAddress = companyAddress
self.companyWebAddress = companyWebAddress
self.companyFB_Address = companyFB_Address
self.companyTWT_Handle = companyTWT_Handle
self.companyLI_Address = companyLI_Address
self.aboutUs = aboutUs
self.email_ID = email_ID
self.ivrNo = ivrNo
// self.projects = projects
// self.projectStatus = projectStatus
}
}
My CompanyHandler.swift controller file is as following:
class CompanyHandler {
// MARK: - company details
func getCompanyDetails() {
var jsonPath = NSBundle.mainBundle().pathForResource("companyDetails", ofType: "json")
var data = NSData(contentsOfFile: jsonPath!)
var jsonData: NSDictionary = NSJSONSerialization.JSONObjectWithData(data!,
options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
var companyArray:NSArray = jsonData["companyDetails"] as NSArray!
for i in companyArray{
var cmpID: String = i["companyID"] as String
var cmpName: String = i["companyName"] as String
var cmpAdd: String = i["companyAddress"] as String
var cmpWebAdd: String = i["companyWebAddress"] as String
var cmpfbAdd: String = i["companyFB_Address"] as String
var cmptwtAdd: String = i["companyTWT_Handle"] as String
var cmpliAdd: String = i["companyLI_Address"] as String
var abtUs: String = i["aboutUs"] as String
var emailId: String = i["email_ID"] as String
var ivrNo: String = i["ivrNo"] as String
println("\(ivrNo)")
var company = Company(companyID: "cmpID", companyName: "cmpName", companyAddress: "cmpAdd", companyWebAddress: "cmpWebAdd", companyFB_Address: "cmpfbAdd", companyTWT_Handle: "cmptwtAdd", companyLI_Address: "cmpliAdd", aboutUs: "abtUs", email_ID: "emailId", ivrNo: "ivrNo")
}
}
}
You're not actually creating an array of Company objects, which would act as your Data Source for your collection view. You're just initializing new Company objects but not doing anything with them. Create a property on your CompanyViewController and make it of type [Company]. In each iteration through your json dictionaries, after you create a new Company, append it to your array of Company's, then use that array for your collection view.
i have a problem and confusing i want to ask how can i make a new object ( i want to make date ) under the icons, and under the date there's icon again.. like gallery on iPhone,
in example:
august
(photos)
september
(photos)
and so on..thx
will be looks like this, but how
there is my code in this view
import UIKit
let reuseIdentifier = "Cell"
class SummaryViewController: UICollectionViewController, UICollectionViewDataSource, UICollectionViewDelegate {
#IBOutlet var collectionview: UICollectionView!
var photos:NSArray?
var items = NSMutableArray()
var TableData:Array< String > = Array < String >()
var json:String = ""
var arrayOfMenu: [ImageList] = [ImageList]()
override func viewDidLoad() {
super.viewDidLoad()
self.setUpMenu()
collectionview.dataSource = self
collectionview.delegate = self
NSLog("%d", items.count)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return arrayOfMenu.count //hitung banyak data pada array
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! UICollectionViewCell
let image = UIImage(named: items.objectAtIndex(indexPath.row) as! String)
let imageView = cell.viewWithTag(100) as! UIImageView
imageView.image = image
return cell
}
func setUpMenu() //membaca json pada setiap arraynya
{
var json: JSON = JSON (data: NSData())
DataManager.getactivityDataFromFileWithSuccess{ (data) -> Void in
json = JSON(data: data)
let results = json["results"]
for (index: String, subJson: JSON) in results {
}
for (var i = 0; i < json["Activity"].count; i++) {
if let icon: AnyObject = json["Activity"][i]["icon"].string {
self.items.addObject(icon)
dispatch_async(dispatch_get_main_queue(), {self.collectionView!.reloadData()})
var menu = ImageList(image: icon as! String)
self.arrayOfMenu.append(menu)
self.TableData.append(icon as! String)
}
}
}
}
override func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView
{
let header = collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionHeader, withReuseIdentifier: "headersection", forIndexPath: indexPath) as! UICollectionReusableView
return header
}
}
You can set number of sections to required number of months.
Like this :
override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int
{
return 3
}
And for the menu, you need to give it according to section(month).
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
{
if section == 0
{
return arrayOfFirstMenu.count
}
else if section == 1
{
return arrayOfSecondMenu.count
}
else
{
return arrayOfThirdMenu.count
}
}
Hope this helps!
how to make this become looks like iPhone gallery (if the data meets the end, i want to add the label which is shows the month) and make it repeatable
it become looks like this
i've tried every objects and insert to uicollectionview, but it doesn't appear at all..is there any way to help?
here is my code
import UIKit
let reuseIdentifier = "Cell"
class SummaryViewController: UICollectionViewController, UICollectionViewDataSource, UICollectionViewDelegate {
#IBOutlet var collectionview: UICollectionView!
var photos:NSArray?
var items = NSMutableArray()
var TableData:Array< String > = Array < String >()
var json:String = ""
var arrayOfMenu: [ImageList] = [ImageList]()
override func viewDidLoad() {
super.viewDidLoad()
self.setUpMenu()
collectionview.dataSource = self
collectionview.delegate = self
NSLog("%d", items.count)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
override func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
return 1
}
override func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return arrayOfMenu.count //hitung banyak data pada array
}
override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(reuseIdentifier, forIndexPath: indexPath) as! UICollectionViewCell
let image = UIImage(named: items.objectAtIndex(indexPath.row) as! String)
let imageView = cell.viewWithTag(100) as! UIImageView
imageView.image = image
return cell
}
func setUpMenu() //membaca json pada setiap arraynya
{
var json: JSON = JSON (data: NSData())
DataManager.getactivityDataFromFileWithSuccess{ (data) -> Void in
json = JSON(data: data)
let results = json["results"]
for (index: String, subJson: JSON) in results {
}
for (var i = 0; i < json["Activity"].count; i++) {
if let icon: AnyObject = json["Activity"][i]["icon"].string {
self.items.addObject(icon)
dispatch_async(dispatch_get_main_queue(), {self.collectionView!.reloadData()})
var menu = ImageList(image: icon as! String)
self.arrayOfMenu.append(menu)
self.TableData.append(icon as! String)
}
}
}
}
override func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView
{
let header = collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionHeader, withReuseIdentifier: "headersection", forIndexPath: indexPath) as! UICollectionReusableView
return header
}
}