I have created 3 outlets for labels,2 actions for buttons and 1 outlet for UIDatePickerView. lblField displays the current date with month, date and year. lblField2 displays the selected dates by the user after pressing dueDate action. lblField3 displays the differences between the current date and selected date.
When I click on the cell of Due date: it opens DatePickerViewController as given above.
Now I need to pass data of lblField3 of DatePickerViewController to "Due date: " cell of TodayViewController in Swift 3 after pressing Done button. How shall I do it using simple way in Swift 3?
For that you need to simply use delegate/protocol. Create one delegate and create its instance in the DatePickerViewController, Now implement that protocol with your TodayViewController and when you move to the DatePickerViewController set its delegate to the self. Now simply call the delegate method on DatePickerViewController to pass the data.
protocol DatePickerDelegate {
func getDifference(diff: String)
}
Now create its instance in DatePickerViewController and call the method where you get the difference of date.
class DatePickerViewController: UIViewController {
var delegate: DatePickerDelegate?
//Other instances property declaration ...
//other methods
#IBAction func Done(_ sender: Any) {
self.delegate?.getDifference(diff: lblField3.text ?? "")
_ = self.navigationController?.popViewController(animated: true)
}
}
Now simply implement DatePickerDelegate with your TodayViewController and add its method.
class TodayViewController: UIViewController, DatePickerDelegate, UITableViewDelegate, UITableViewDataSource {
//Other methods
//Set the delegate when you are push to DatePickerViewController
let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "DatePickerViewController") as! DatePickerViewController
//Set delegate of DatePickerViewController
secondViewController.delegate = self
selectedIndexPath = indexPath
self.navigationController?.pushViewController(secondViewController, animated: true)
//DatePickerDelegate method
func getDifference(diff: String) {
//Access diff here
print(diff)
}
}
Edit: The problem is in didSelectRowAt you are comparing the text of cell's label instead of that you need to compare the row of tableView
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if (tableView.tag == 1) {
if indexPath.row == 4 {
//Show view for Baby size guide:
let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "BabySizeViewController") as! BabySizeViewController
selectedIndexPath = indexPath
self.navigationController?.pushViewController(secondViewController, animated: true)
}
else if indexPath.row == 1 {
//Show view for Due date:
let secondViewController = self.storyboard?.instantiateViewController(withIdentifier: "DatePickerViewController") as! DatePickerViewController
selectedIndexPath = indexPath
secondViewController.delegate = self
self.navigationController?.pushViewController(secondViewController, animated: true)
}
}
}
Related
I am working in Swift and the function categoryPressedFunction is not being called.
Protocol:
protocol categoryPressed: class { //1 create a protocol with function that passes a string
func categoryPressedFunction(category: String)
}
View Controller 2:
//set the delegate
weak var delegate: categoryPressed?
//when cell is selected in tableview, grab the "category" which is a string and then dismiss
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let category = guideCategoryArray[indexPath.row] // gets category
delegate?.categoryPressedFunction(category: category) // sets delegate to know it was pressed
self.presentingViewController?.dismiss(animated: true, completion: nil) //dismisses
}
}
View Controller 1 (Previous)
//set class delegate
...categoryPressed
//add function that sets label to category and looks up items based off category
func categoryPressedFunction(category: String) {
print("categoryPressedFunctionPressed")
resourceArray.removeAll()
resourceLabel.text = category
getItems(item: category, { [self] in
print("got new items for \(category) and refreshed the tableview")
self.resourceTableView.reloadData()
})
}
When returning to ViewController 1, nothing happens. The tableview does not reload, nor does the label change to the category pressed. Am I missing something?
Delegates might be nil. Did you add this line in the ViewDidLoad method?
delegate = self
You might have missed assigning delegate to self while moving from VC1 to VC2.
Hope below code helps you.
//Some Navigation logic
let VC2 = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(withIdentifier: "VC2Identifier") as! VC2;
VC2.delegate = self
self.present(VC2, animated: true, completion: nil)
I am quite new to this. I am getting an issue with selection items and post back to tableview on specific index cell (reload).
Scenario: I have two view controllers and both contains tableview.
FirstViewController: I am already displaying data from webservice into Tableview but on different action types I have used didSelectRow function which shows to ListViewController for item selection. In FirstViewController main model is Unit.
ListViewController: Simple list of data displaying in tableView for selection.
Issue: is how can I select item from ListViewController and pass data to FirstViewController tableview that change occurs on specific cell and then I have to post values with updated values. How can I reload tableview or model?
Model:
struct Unit : Codable {
let sectionList : [SectionList]?
}
struct SectionList : Codable {
let title : String?
let items : [Item]?
}
struct Item : Codable {
let actionType : Int?
let textField : String?
let textValue : String?
let pickList: [SectionList]?
let multiSelect: Bool?
let selectedValue: [String]?
let version: Int?
let masterId: Int?
let itemValue: String?
}
Updated FirstController:
class FirstViewController: UIViewControlller, ListDelegate {
var selectedIndex: Int?
var selectedSection: Int?
//Click event for navigation from FirstViewController to SecondViewController
#IBAction func BackButtonAction(_ sender: Any) {
let vc = self.storyboard?.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
vc.delegate = self
self.navigationController?.pushViewController(vc, animated: true)
}
func listFunc(listValue: String) {
AppData?.sectionList?[selectedSection!].items?[selectedIndex!].textField = listValue
tableView.reloadData()
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//Add these two line in your code
selectedIndex = indexPath.row
selectedSection = indexPath.section
}
}
Updated : ListViewController:
protocol ListDelegate {
func listFunc(listValue: String)
}
class SecondViewController: UIViewControlller {
var delegate: ListDelegate?
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let indexPath = tableView.indexPathForSelectedRow
let currentCell = tableView.cellForRow(at: indexPath!)!
//print(currentCell.textLabel?.text as Any)
currentCell.accessoryType = .checkmark
delegate?.listFunc(listValue: currentCell.textLabel?.text ?? "")
self.navigationController?.popViewController(animated: true)
}
}
You've got a handful of options to accomplish this. Assuming that the selected value is the only value that you've got to pass, using closures would be the easiest thing you could do.
1) Declare a closure that holds a type of your need inside ListViewController:
`var didSelectItem : ((YourType, IndexPath) -> ())?`
2) In ListViewController's didSelectRow method, use the closure:
`self.didSelectItem?(yourDataSourceItemAtIndexpath, indexPath)`
3) You'll get a callback for the triggered closure when you use this closure from your ListViewController instance inside FirstViewController like:
let myListInstance = ListViewController()
myListInstance.didSelectItem = { selectedItem, selectedIndex in
//You'll get the selected item inside this block, do model updation here
}
After updating your model with new values, if you want to reload your tableView only at the particular(updated) index, you can use:
self.yourTableView.reloadSections(sections: IndexSet, with: UITableView.RowAnimation) to reload a whole section or..
self.yourTableView.reloadRows(at: [IndexPath], with: UITableView.RowAnimation) to reload a row in a section
(If you're performing multiple updates simultaneously, keep in mind that you'll have to do these reloads inside self.yourTableView.beginUpdates() and self.yourTableView.endUpdates())
NOTE:
You'll have to handle your dataSource properly during these reloads to make sure you have the right number of rows or sections before and after the reload, adding/subtracting the rows/sections that you insert/delete. Else, your app will crash!
If you don't want to risk that, just reload the whole table with yourTableView.reloadData()
Also keep in mind that there are other ways to pass data across controllers and this is just a suggestion based on what I assume your use case to be
I hardly able to understand your code, it's totally messed up according to me.
I found that most of your code is done and I am adding rest your things that you need to do.
In your FirstViewController.swift, didSelectRowAt func,
let vc = self.storyboard?.instantiateViewController(withIdentifier: "ViewController") as! ViewController
vc.Indexdata = // your data that you wanted to show in your next controller,
// if variable is different then assign data to that var
vc.delegate = self
self.navigationController?.pushViewController(vc, animated: true)
In ViewController.swift, didSelectRowAt func,
// Comment these below lines
// let vc = self.storyboard?.instantiateViewController(withIdentifier: "FirstViewController") as! FirstViewController
// self.navigationController?.pushViewController(vc, animated: true)
// Add below line
self.navigationController?.popViewController(animated: true)
Now check it should work.
I have a complicated issue I'd like to explain visually and through code.
Currently, this is how my app is suppose to work visually:
I have a ViewControllerOneclass that contains a UITableView with 9 cells. Any rows selected except rows 2, 6, and 7 will segue to ViewControllerTwo with its own UITableView and number of rows.
If rows 2, 6, or 7 is selected, a push segue will stack another ViewControllerOne onto the existing ViewControllerOne. The reason for doing this is because every row is a category, but rows 2, 6, and 7 also contains sub-categories that looks exactly like ViewControllerOne Main-VC on the left.
Rather than creating another class that contains the exact same code as in Main-VC, I wanted to reuse the ViewControllerOne class.
Now, if any rows in SUB-VC is selected, it will also perform a push segue to ViewControllerTwo.
Since ViewControllerOne and ViewControllerTwo are embedded in a UINavigationController, the issue I'm having is in the 5th step:
I select a row not 2, 6, or 7 in Main-VC, it takes me to ViewControllerTwo (as it should)
I go back to Main-VC via navigation bar back button and select row 2, 6, or 7 in MAIN-VC, it will take me to SUB-VC (as it should)
I select a row not 2, 6, or 7 in Sub-VC, it will take me to ViewControllerTwo (as it should)
I go back to Sub-VC via navigation bar back button on the navigation bar
I select a row 2, 6, or 7 in Sub-VC, it will push segue and stack another Sub-VC on top of the existing Sub-VC instead of doing a push segue to ViewControllerTwo
I have a Manager class that handles the logic and communicates with ViewControllerOne and ViewControllerTwo to display the data.
import UIKit
enum SubGroupState
{
case SubGroup1, None, SubGroup2, SubGroup3
}
class Manager: NSObject
{
public var subGroupState = SubGroupState.None
public var oldSubGroupState = SubGroupState.None
public var showSubGroups = Bool()
override init()
{
super.init()
}
public func initializeGroupState(row: Int) -> UIViewController
{
if showSubGroups == false && oldSubGroupState == .None
{
switch row
{
case 2:
subGroupState = .SubGroup1
break
case 6:
subGroupState = .SubGroup2
break
case 7:
subGroupState = .SubGroup3
break
default:
subGroupState = .None
break
}
}
if (subGroupState != .None && oldSubGroupState == .None)
|| (subGroupState == .None && oldSubGroupState != .None)
{
showSubGroups = true
}
else
{
showSubGroups = false
}
return initializeGroupVC(row: row)
}
fileprivate func initializeGroupVC(row: Int) -> UIViewController
{
let storyboard = UIStoryboard(name: "Main",
bundle: nil)
if showSubGroups == true
&& subGroupState != .None
{
guard let viewControllerOne = storyboard.instantiateViewController(withIdentifier: "ViewControllerOne")
as? ViewControllerOne else {
return UIViewController()
}
viewControllerOne.manager.oldSubGroupState = muscleSubGroupState
viewControllerOne.manager.showSubGroups = showSubGroups
return viewControllerOne
}
else
{
guard let viewControllerTwo = storyboard.instantiateViewController(withIdentifier: "ViewControllerTwo")
as? ViewControllerTwo else {
return UIViewController()
}
return muscleGroupExercisesVC
}
}
}
The purpose of the states is so I can handle displaying the different sub-categories depending on the state of the selected cell.
I create an instance of Manager in ViewControllerOne when the user selects a cell:
extension ViewControllerOne: UITableViewDataSource
{
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
tableView.deselectRow(at: indexPath,
animated: true)
let viewController = manager.initializeGroupState(row: indexPath.row)
self.navigationController?.pushViewController(viewController,
animated: true)
}
}
class ViewControllerOne: UIViewController
{
public var manager = Manager()
....
}
The issue is in logic handling in the function initializeGroupState, but I've tried other different combinations and I always get the Sub-VC stacked on top of an existing Sub-VC for rows 2, 6, and 7, which obviously corresponds to the subgroup rows in Main-VC, and that's where the issue I'm having a difficult time handling the logic with.
If I am doing this the wrong way, is there a better alternative to what I'm trying to achieve without repeating code?
NOTE: My Storboard only has the Main-VC ViewControllerOne with a segue to ViewControllerTwo. The added Sub-VC ViewControllerOne is there to visually see what I'm trying to do, but does not actually exist in my Storyboard.
I think we can keep it simple as posible
class ViewControllerOne: UIViewController, UITableViewDelegate {
var isSubVC = false
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: false)
if self.isSubVC {
// Push to ViewControllerTwo
} else {
// MainVC
if indexPath.row == 2 || indexPath.row == 6 || indexPath.row == 7 {
let subVC = self.storyboard?.instantiateViewController(withIdentifier: "ViewControllerOne") as! ViewControllerOne
subVC.isSubVC = true
self.navigationController?.pushViewController(subVC, animated: true)
} else {
// Push to ViewControllerTwo
}
}
}
}
Here is the code using your manager ideas for navigation without any tests.
enum ViewControllerType {
case main, subGroup1, subGroup2, subGroup3
}
class Manager {
public var currentState = ViewControllerType.main
public func initializeGroupState(row: Int) -> UIViewController {
if self.currentState == .main {
// MainVC, should push to SubVC if match condition
switch row {
case 2:
return self.makeSubViewController(state: .subGroup1)
case 6:
return self.makeSubViewController(state: .subGroup2)
case 7:
return self.makeSubViewController(state: .subGroup3)
default:
return self.makeViewControllerTwo()
}
} else {
// Current is SubVC, dont care kind of row, should push to ViewControllerTwo
return self.makeViewControllerTwo()
}
}
private func makeViewControllerTwo() -> UIViewController {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "ViewControllerTwo")
return vc
}
private func makeSubViewController(state: ViewControllerType) -> UIViewController {
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "ViewControllerOne") as! ViewControllerOne
vc.manager.currentState = state
return vc
}
}
OK! What's happening here is that you have segues connected to your tableView, and that causes issues when you also push a new view controller in your code.
From the code you've posted here, I think just removing the segues from your storyboard would solve the issue. Doing it in only code as you're already doing in tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) is perfectly fine.
You can delete segues by clicking on them and pressing backspace, view controller can float for themselves in the storyboard without being connected by segues.
In Objective-C, but the logic should be the same, that's what I would do:
CustomModel:
#property (nonatomic, strong) NSArray *subdata;
#property (nonatomic, strong) NSString *title;
#property (nonatomic, assing) BOOL isSpecial; //of course wording should be adapted to the real logic and your needs
By default on the init of a CustomModel object, isSpecial is set to NO.
ViewControllers:
#property (nonatomic, strong), NSArray *tableViewDataSource;
The tableViewDataSource of MainViewController should be like this:
- CustomData isSpecial: NO
subdata = [CustomData11, CustomData12...]
- CustomData isSpecial: NO
subdata = [CustomData21, CustomData22...]
- CustomData isSpecial: YES
subdata = [CustomData31, CustomData32...]
- CustomData isSpecial: NO
subdata = [CustomData41, CustomData42...]
- CustomData isSpecial: NO
subdata = [CustomData51, CustomData52...]
- CustomData isSpecial: NO
subdata = [CustomData61, CustomData62...]
- CustomData isSpecial: YES
subdata = [CustomData71, CustomData72...]
- CustomData isSpecial: YES
subdata = [CustomData81, CustomData82...]
- CustomData isSpecial: NO
subdata = [CustomData91, CustomData92...]
Logic for deciding on next viewcontroller:
You can use either Segue or manual instantiation/push, but I'd suggest you keep doing the same method for both of thems
CustomModel *selectedData = tableViewDataSource[indexPath.row]
if ([selectedData isSpecial])
{
//Go to SubVC, ie. another MainVC
SubViewController *nextVC = ... //segue.destinationViewController looping on itself or storyboard.instatianteViewController instantiating another MainViewController
nextVC.data = selectedData.subdata;
}
else
{
//Go VC2
ViewController *nextVC = ... //segue.destinationViewController or storyboard.instatianteViewController...
nextVC.data = selectedData.subdata;
}
You can manage you viewcontroller and manager class as below:
class ViewControllerOne: UIViewController, UITableViewDelegate {
var isSubVC = false
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: false)
let wireframe = WireFrame()
let nextVC = wireframe.getNextVC(forView: self)
self.navigationController?.pushViewController(nextVC, animated: true)
}
}
class WireFrame {
func getNextVC (forView view: UIViewController) -> UIViewController {
if view.isKind(of: ViewControllerOne) {
return ViewControllerTwo
} else {
// MainVC
if indexPath.row == 2 || indexPath.row == 6 || indexPath.row == 7 {
let subVC = self.storyboard?.instantiateViewController(withIdentifier: "ViewControllerOne") as! ViewControllerOne
subVC.isSubVC = true
return subVC
} else {
return ViewControllerTwo
}
}
}
}
I want to send the text which is in textfield in ViewControllerC to another textfield which is in ViewControllerA
By using delegate am trying to pass the text from ViewControllerC to ViewControllerA.
i cant get the logic what to write here delegate?.userDidEnterInformation() in ViewControllerC
could any one help me regarding this
ViewControllerC
protocol DataEnteredInDestinationDelegate: class {
func userDidEnterInformation(info: String)
}
class DestinationSearchViewController: MirroringViewController {
var delegate: DataEnteredInDestinationDelegate?
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let cell: UITableViewCell? = tableView.cellForRow(at: indexPath)
componetsTextField.text = cell?.textLabel?.text
delegate?.userDidEnterInformation()
self.navigationController?.popToRootViewController(animated: true)
}
}
ViewControllerA
class HomeViewController: MirroringViewController, DataEnteredInDestinationDelegate
{
func userDidEnterInformation(info: String){
locationView.destination.text = info
}
}
Firstly you have to always mark delegate as weak e.g.:
weak var delegate: DataEnteredInDestinationDelegate?
and then you need to connect delegate like this:
let vcA = ViewControllerA()
let vcC = ViewControllerC()
vcC.delegate = vcA // Connect delegate
and then your delegate method in ViewControllerC will work after invoking this code:
delegate?.userDidEnterInformation(textString)
Here NotificationCentre can be a good approach instead of delegates. Make Viewcontroller A an observer to receive text information as below.
Write this code in viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(userDidEnterInformation(notification:)), name: NSNotification.Name.init(rawValue: "UserDidEnterInformation"), object: nil)
and write this anywhere in class Viewcontroller A
func userDidEnterInformation(notification: Notification) {
if let textInfo = notification.userInfo?["textInfo"] {
textField.text = textInfo
}
}
In Viewcontroller C post the notification with textInfo by writing below code
NotificationCenter.default.post(name: NSNotification.Name.init(rawValue: "UserDidEnterInformation"), object: nil, userInfo: ["textInfo": textField.text])
delegate?.userDidEnterInformation(cell!.textLabel!.text)
Also, you should set the delegate of ViewControllerC.
viewControllerC.delegate = viewControllerA
Consider the following example:-
let aVCobjA = UIViewController()
let aVCobjB = UIViewController()
let aVCobjC = UIViewController()
var aNavigation = UINavigationController()
func pushVC() {
aNavigation.pushViewController(aVCobjA, animated: true)
aNavigation.pushViewController(aVCobjB, animated: true)
aNavigation.pushViewController(aVCobjC, animated: true)
//Here you will get array of ViewControllers in stack of Navigationcontroller
print(aNavigation.viewControllers)
//To pass data from Viewcontroller C to ViewController A
self.passData()
}
// To pass data access stack of Navigation Controller as navigation controller provides a property viewControllers which gives you access of all view controllers that are pushed.
func passData() {
let aVCObj3 = aNavigation.viewControllers.last
let aVCObj1 = aNavigation.viewControllers[0]
//Now you have access to both view controller pass whatever data you want to pass
}
I have a Master-Detail VC setup for a Core Data project. If the searchBar is active, one set of results is displayed, if it's not active, the objects from the fetchedResultsController displays in the MasterVC.
I had been trying to segue using prepareForSegue, but I my instructor suggested I use didSelectRowAtIndexPath to do the segue.
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var selectedNote: Note
// Check to see which table view cell was selected.
if tableView == self.tableView {
selectedNote = self.fetchedResultsController.objectAtIndexPath(indexPath) as! Note // <--this is "everything"
} else {
// need this to unwrap the optional
if let filteredObjects = filteredObjects {
selectedNote = filteredObjects[indexPath.row]
}
}
// Set up the detail view controller to show.
let detailViewController = DetailViewController()
detailViewController.detailDescriptionLabel = selectedNote.valueForKey("noteBody") as! UILabel
// Note: Should not be necessary but current iOS 8.0 bug requires it.
tableView.deselectRowAtIndexPath(tableView.indexPathForSelectedRow()!, animated: false)
// original code
navigationController?.pushViewController(detailViewController, animated: true)
}
I'm getting this compiler error:
Variable 'selectedNote' used before being initialized--it's declared at the top of the method!
If I add "self" before selectedNote like so:
detailViewController.detailDescriptionLabel = self.selectedNote.valueForKey("noteBody") as! UILabel
'MasterViewController' does not have a member named 'selectedNote' despite being there. So I'm obviously mucking up something.
I put a breakpoint in before let detailViewController = DetailViewController() and in lldb it's printing out the right object. I've looked around here for a solution, but I'm coming up short. I can't find applicable code that works on GitHub.
class Note: NSManagedObject {
#NSManaged var dateCreated: NSDate
#NSManaged var dateEdited: NSDate
#NSManaged var noteTitle: String
#NSManaged var noteBody: String
}
Any ideas how to pass the selectedNote's properties forward to the detailViewController?
Update:
Based on the responses I've gotten, I've shut up the compiler warnings with this code:
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
var selectedNote: Note?
// Check to see which table view cell was selected.
if tableView == self.tableView {
selectedNote = self.fetchedResultsController.objectAtIndexPath(indexPath) as? Note // <--this is "everything"
} else {
// need this to unwrap the optional
if let filteredObjects = filteredObjects {
selectedNote = filteredObjects[indexPath.row]
}
}
// Set up the detail view controller to show.
let detailViewController = DetailViewController()
detailViewController.detailDescriptionLabel.text = (selectedNote!.valueForKey("noteBody") as! String)
// Note: Should not be necessary but current iOS 8.0 bug requires it.
tableView.deselectRowAtIndexPath(tableView.indexPathForSelectedRow()!, animated: false)
// original code
navigationController?.pushViewController(detailViewController, animated: true)
}
But I'm getting this in the console when it crashes:
There are already notes in the app
fatal error: unexpectedly found nil while unwrapping an Optional value
However, when I type po selectedObject the object I clicked displays in the console.
You need to declare selectedNote as optional like this:
var selectedNote: Note?
And later check if value exist before using it.
if let note = selectedNote {
// Set up the detail view controller to show.
let detailViewController = DetailViewController()
detailViewController.detailDescriptionLabel = note.valueForKey("noteBody") as! UILabel
// Note: Should not be necessary but current iOS 8.0 bug requires it.
tableView.deselectRowAtIndexPath(tableView.indexPathForSelectedRow()!, animated: false)
// original code
navigationController?.pushViewController(detailViewController, animated: true)
}
Update:
The problem is that you are trying to create DetailViewController
let detailViewController = DetailViewController()
But what you need instead is to have reference to the DetailViewController in order to pass information to it.
So you can create segue from Master to Detail controller in Interface builder. Then remove logic from didSelectRowAtIndexPath
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
// Note: Should not be necessary but current iOS 8.0 bug requires it.
tableView.deselectRowAtIndexPath(tableView.indexPathForSelectedRow()!, animated: false)
}
And implement it in prepareForSegue method:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "showDetail" {
if let cell = sender as? UITableViewCell {
let indexPath = tableView.indexPathForCell(cell)!
var selectedNote: Note?
if filteredObjects?.count > 0 {
selectedNote = filteredObjects![indexPath.row]
}else {
selectedNote = self.fetchedResultsController.objectAtIndexPath(indexPath) as? Note // <--this is "everything"
}
if let note = selectedNote {
let controller = (segue.destinationViewController as! UINavigationController).topViewController as! DetailViewController
controller.detailItem = note
}
}
}
}
showDetail - segue identifier which you need to setup in IB.
var detailItem: AnyObject? - you need to declare it in DetailViewController.