<NME> CariocaMenu.swift
<BEF> //
//  CariocaMenu.swift
//  CariocaMenu
//
//  Created by Arnaud Schloune on 21/11/2017.
//  Copyright © 2017 CariocaMenu. All rights reserved.
//

import Foundation
import UIKit
///🇧🇷 Carioca Menu 🇧🇷
public class CariocaMenu: CariocaGestureManagerDelegate {
    ///The menu's content controller
    let controller: CariocaController
    ///The view in which the menu will be displayed
    let hostView: UIView
    ///The edges of the menu. Supported : .left, .right
    let edges: [UIRectEdge]
    ///The container view. Created programatically,
    ///it takes the same dimensions as the host view
    let container: CariocaMenuContainerView
    ///Gestures manager
    let gestureManager: CariocaGestureManager
    ///The selected index of the menu. Default: 0
	internal var selectedIndex: Int
    ///Can the menu go offscreen with user's gesture ? (true)
    ///Or should it always stay fully visible ? (false)
    var isOffscreenAllowed = true
    // swiftlint:disable weak_delegate
    ///Receiver of UITableView events
    let tableViewDelegate: CariocaTableViewDelegate
    // swiftlint:enable weak_delegate
    ///The selected index of the menu. Default: 0
    var selectedIndex: Int = 1
	///The indicatorView
    ///- Parameter controller: The menu's dataSource
    ///- Parameter hostView: The view in which the menu will be displayed
    ///- Parameter edges: The supported edges
    ///- Parameter delegate: The menu's event delegate
	///- Parameter selectedIndex: The menu's default selected index
	///- Parameter indicator: The custom indicator view
    public init(controller: CariocaController,
				hostView: UIView,
				edges: [UIRectEdge],
				delegate: CariocaDelegate,
				selectedIndex: Int = 0,
				indicator: CariocaIndicator) {
		self.controller = controller
        self.hostView = hostView
        self.edges = edges
        self.edges = edges
        self.container = CariocaMenuContainerView(frame: hostView.frame,
                                                  dataSource: controller)
        self.tableViewDelegate = CariocaTableViewDelegate(delegate: delegate,
                                                          heightForRow: controller.heightForRow())
        self.gestureManager = CariocaGestureManager(hostView: hostView,
                                                    controller: controller,
                                                    edges: edges,
                                                    container: self.container)
        self.delegate = delegate
		self.indicator = CariocaMenuIndicatorView(edge: edges.first!)
        self.gestureManager.delegate = self
        self.tableViewDelegate.menu = self
        self.controller.tableView.delegate = tableViewDelegate
		self.controller.tableView.dataSource = CariocaTableViewDataSource()
        self.hideMenu()
    }

    ///Adds the menu's container view in the host view
    public func addInHostView() {
        hostView.addSubview(container)
		if let blurStyle = controller.blurStyle {
			container.addBlurView(style: blurStyle)
		}
        hostView.addConstraints(container.makeAnchorConstraints(to: hostView))
		indicator.addIn(hostView, tableView: controller.tableView, position: controller.indicatorPosition)
		indicator.iconView.display(icon: controller.menuItems.first!.icon)
		indicator.show(edge: edges.first!, hostView: hostView, isTraversingView: false)
		let tapGesture = UITapGestureRecognizer(target: self, action: .tappedIndicatorView)
		tapGesture.numberOfTapsRequired = 1
		indicator.addGestureRecognizer(tapGesture)
	}

	///Bring the indicator on top of all views
	public func bringToFront() {
		hostView.bringSubview(toFront: container)
		hostView.bringSubview(toFront: indicator)
	}

	///Called from the hostview, if a rotation has been detected.
	///Moves the indicator at 50% of the hostView.
	public func hostViewDidRotate() {
		let yScreenMiddle = hostView.frame.height / 2.0
		gestureManager.panned(yLocation: yScreenMiddle,
							  edge: indicator.edge,
							  state: .began,
							  fromGesture: false)
		gestureManager.panned(yLocation: yScreenMiddle,
							  edge: indicator.edge,
							  state: .changed)
		indicator.repositionXAfterRotation(hostView)
	}
    func didSelectItem(at index: Int) {
        selectedIndex = index
        delegate?.cariocamenu(self, didSelectItemAt: index)
        /*menuOriginalY = location.y
         //Unselect the previously selected cell, but first, update the selectedIndexPath
         let indexPathForDeselection = selectedIndexPath
         selectedIndexPath = preSelectedIndexPath
         dataSource.unselectRowAtIndexPath(indexPathForDeselection)
         didSelectRowAtIndexPath(selectedIndexPath, fromContentController: true)*/
        /*
         if preSelectedIndexPath !=  calculatedIndexPath {
         if preSelectedIndexPath != nil {
         dataSource.unselectRowAtIndexPath(preSelectedIndexPath)
         }
         preSelectedIndexPath = calculatedIndexPath
         dataSource.preselectRowAtIndexPath(preSelectedIndexPath)
         }
         updateIndicatorsForIndexPath(preSelectedIndexPath)
         }*/
    }
}
		}
		UIView.animate(withDuration: duration, animations: {
			self.container.alpha = 0.0
		}, completion: { _ in
			self.container.isHidden = true
			self.container.alpha = 1.0
		})
    }
	///The selection index was updated, while user panning in the view
	///- Parameter index: The updated selection index
	///- Parameter selectionFeedback: Should we make a selection feedback?
	internal func didUpdateSelectionIndex(_ index: Int, selectionFeedback: Bool) {
		indicator.moveTo(index: index, heightForRow: controller.heightForRow())
		let item = controller.menuItems[index]
		indicator.iconView.display(icon: item.icon)
		if selectionFeedback {
			makeSelectionFeedback()
		}
    }
	///Haptick feedback, if supported. Min iOS 10.0.
	internal func makeSelectionFeedback() {
		if #available(iOS 10.0, *) {
			let selectionFeedback = UISelectionFeedbackGenerator()
			selectionFeedback.selectionChanged()
		}
	}
	///The user did select a menu item
	///- Parameter index: The selected index
    internal func didSelectItem(at index: Int) {
		self.selectedIndex = index
		self.delegate?.cariocamenu(self, didSelect: self.controller.menuItems[index], at: index)
		self.makeSelectionFeedback()
		self.hideMenu(0.5)
		indicator.restore(hostView: hostView, boomerang: controller.boomerang,
						  initialPosition: controller.indicatorPosition,
						  firstStepDuration: 0.5,
						  firstStepDone: {
							if self.controller.boomerang == .originalPosition || self.controller.boomerang == .vertical {
								//Set the container on top to avoid incorrect calculations.
								self.container.topConstraint.constant = 0.0
								self.hostView.setNeedsLayout()
							}
		})
    }

	// MARK: UITableView datasource/delegate
	///Number of menu items
	public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
		return controller.menuItems.count
	}
	///Cell for row. Forwarded to the controller, with the extra edge parameter.
	public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
		return controller.tableView(tableView, cellForRowAt: indexPath, withEdge: indicator.edge)
	}
	///Number of sections. Cannot be updated for now, as the menu's tableView only supports 1 section
	public func numberOfSections(in tableView: UITableView) -> Int { return 1 }
	///UITableView selection delegate, forwarded to CariocaDelegate
	public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
		didUpdateSelectionIndex(indexPath.row, selectionFeedback: true)
		didSelectItem(at: indexPath.row)
	}
	///Takes the specified heightForRow passed in the initialiser
	public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
		return controller.heightForRow()
	}
	///Default footer view (to hide extra separators)
	public func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
		return UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: 0))
	}
}

<MSG> move datasource and delegate in CariocaMenu, for more simplicity

<DFF> @@ -9,7 +9,7 @@
 import Foundation
 import UIKit
 ///🇧🇷 Carioca Menu 🇧🇷
-public class CariocaMenu: CariocaGestureManagerDelegate {
+public class CariocaMenu: NSObject, CariocaGestureManagerDelegate, UITableViewDelegate, UITableViewDataSource {
     ///The menu's content controller
     let controller: CariocaController
     ///The view in which the menu will be displayed
@@ -26,10 +26,6 @@ public class CariocaMenu: CariocaGestureManagerDelegate {
     ///Can the menu go offscreen with user's gesture ? (true)
     ///Or should it always stay fully visible ? (false)
     var isOffscreenAllowed = true
-    // swiftlint:disable weak_delegate
-    ///Receiver of UITableView events
-    let tableViewDelegate: CariocaTableViewDelegate
-    // swiftlint:enable weak_delegate
     ///The selected index of the menu. Default: 0
     var selectedIndex: Int = 1
 	///The indicatorView
@@ -51,18 +47,17 @@ public class CariocaMenu: CariocaGestureManagerDelegate {
         self.edges = edges
         self.container = CariocaMenuContainerView(frame: hostView.frame,
                                                   dataSource: controller)
-        self.tableViewDelegate = CariocaTableViewDelegate(delegate: delegate,
-                                                          heightForRow: controller.heightForRow())
         self.gestureManager = CariocaGestureManager(hostView: hostView,
                                                     controller: controller,
                                                     edges: edges,
                                                     container: self.container)
         self.delegate = delegate
 		self.indicator = CariocaMenuIndicatorView(edge: edges.first!)
+		super.init()
         self.gestureManager.delegate = self
-        self.tableViewDelegate.menu = self
-        self.controller.tableView.delegate = tableViewDelegate
-		self.controller.tableView.dataSource = CariocaTableViewDataSource()
+		self.controller.tableView.dataSource = self
+		self.controller.tableView.delegate = self
+		self.controller.tableView.frame = CGRect(x: 0, y: 0, width: 375, height: 500)
         self.hideMenu()
     }
 
@@ -103,21 +98,29 @@ public class CariocaMenu: CariocaGestureManagerDelegate {
     func didSelectItem(at index: Int) {
         selectedIndex = index
         delegate?.cariocamenu(self, didSelectItemAt: index)
-        /*menuOriginalY = location.y
-         //Unselect the previously selected cell, but first, update the selectedIndexPath
-         let indexPathForDeselection = selectedIndexPath
-         selectedIndexPath = preSelectedIndexPath
-         dataSource.unselectRowAtIndexPath(indexPathForDeselection)
-         didSelectRowAtIndexPath(selectedIndexPath, fromContentController: true)*/
-        /*
-         if preSelectedIndexPath !=  calculatedIndexPath {
-         if preSelectedIndexPath != nil {
-         dataSource.unselectRowAtIndexPath(preSelectedIndexPath)
-         }
-         preSelectedIndexPath = calculatedIndexPath
-         dataSource.preselectRowAtIndexPath(preSelectedIndexPath)
-         }
-         updateIndicatorsForIndexPath(preSelectedIndexPath)
-         }*/
     }
+
+	// MARK: UITableView datasource/delegate
+	public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+		return controller.menuItems.count
+	}
+
+	public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
+		return tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
+	}
+
+	///UITableView selection delegate, forwarded to CariocaDelegate
+	public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
+		didSelectItem(at: indexPath.row)
+	}
+
+	///Takes the specified heightForRow passed in the initialiser
+	public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
+		return controller.heightForRow()
+	}
+
+	///Default footer view (to hide extra separators)
+	public func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? {
+		return UIView(frame: CGRect(x: 0, y: 0, width: tableView.frame.size.width, height: 0))
+	}
 }

{'addition_count': 29, 'commit_subject': 'move datasource and delegate in CariocaMenu, for more simplicity', 'deletion_count': 26, 'file_extension': '.swift', 'lang': 'swift', 'license': 'mit', 'repo_name': 'arn00s/cariocamenu'}