I try to create my first iPhone application. I created two differents views in my Storyboard.
A "master" and a "detail" view. I embedded the Master View into a Navigation Controller. The Master View is made of an UITableView, with custom cells.
I try to show the Detail View when I tap the cell. but I don't understand how to make that... I created a "view detail" segue between the cell and the Detail View, but when I tap the cell, nothing happens.
Thanks for the help.
Embed the UITableView into a navigation controller.
Do you have a code in your method "didSelectRowAtIndexPath" in your table?
You can try with this solution here:
The problem is that you're not handling your data correctly. If you look into your currentResponse Array, you'll see that it holds NSDictionaries but in your prepareForSegue you try to cast a NSDictionary to a NSArray, which will make the app crash.
Change the data variable in RestaurantViewController to a NSDictionary and change your prepareForSegue to pass a a NSDictionary
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if let cell = sender as? UITableViewCell {
let i = redditListTableView.indexPathForCell(cell)!.row
if segue.identifier == "toRestaurant" {
let vc = segue.destinationViewController as RestaurantViewController
vc.data = currentResponse[i] as NSDictionary
}
}
}
Related
I am developing in Swift.
And the following picture is my storyboard.
There has a Main view. The Main view will change the view to the Scan view and also pass the data to the Scan view when press the Scan (Right Bar button item).
And the identifier of the StoryBoard Segue is ScanView
I use the following code to pass the data from Main to the Scan
When press the Scan (Right Bar button item).
self.performSegueWithIdentifier("ScanView", sender: self)
And pass the data to the next view
//prepare jumping to next page
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier=="ScanView"){
let desViewController = segue.destinationViewController as! ScanViewController
desViewController.myCenteralManager = myCenteralManager
}
}
And it will crash at let desViewController = segue.destinationViewController as! ScanViewController and show the error like the following :
Could not cast value of type 'UINavigationController' (0x3960e0a8) to 'BLEConnect.ViewController' (0x5514c).
Can someone teach me how to solve the issue ? Thanks in advance.
The error message are pretty clear, you try to get segue.destinationViewController as ScanViewController while in fact it is a navigation controller. You need to get the navigation controller first and then use its topViewController property to get your targeted view controller.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
if (segue.identifier=="ScanView") {
if let navController: UINavigationController = segue.destinationViewController as? UINavigationController {
if let desViewController: ScanViewController = navController.topViewController as? ScanViewController {
desViewController.myCenteralManager = myCenteralManager
}
}
}
}
Your NavigationController is (probably) in the wrong place in Interface Builder. Right now, when you segue, you are going to the UINavigationController and not the ScanViewController like you expect. This is why the cast fails, because you are trying to force the UINavigationController to be a ScanViewController.
To fix this, you should place your MainViewController in the UINavigationController and then segue straight to your ScanViewController.
This guide shows exactly how you can use Interface Builder, UINavigationController, and segues to achieve what you're trying to do.
You can embed your navigation controller to the main ViewController and perform a segue as you have done above. That should solve the problem.
The error message is displayed because you have type casted Navigation Controller instead of Scan ViewController .
I am developing an IOS app using swift language in which I want to segue from uitableview's row to uitextview to show some text and I want to use attributed text property of uitextview but its not working.How to do that?
First of all, you can't segue to a UITextView; you can segue only to another view controller. But maybe you meant to say that your segue goes to a view controller with a UITextView in it. If so, then control-drag a segue from your table view cell to the other view controller, and give the segue an identifier. Then, in your table view controller, implement:
func prepareForSegue(_ segue: UIStoryboardSegue, sender sender: AnyObject?) {
if segue.identifier == "the-segue-id-that-you-put-in-your-storyboard" {
// Cast your destination view controller to the specific type
if let destinationVC = segue.destination as? <your-view-controller-type> {
destinationVC.textView.attributedText = <your-string>
}
}
}
Currently developing a small ios app in swift, I have populated a collection view cell with data from a .plist, each cell has a title and button, what i'm wanting is to segue to multiple view controllers in the storyboard depending on the segue identity once the button is pressed. For example if the segue has the id set as food, i want it to navigate to the view called food?
or if it is easier for the segue to pull the title from the cell then navigate to the view with the same title as the cell?
ill try and explain in code:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?)
{
if segue.identifier == "food"
{
//then navigate to the view controller called food
}
else if segue.identifier == "drink"{
{
//navigate to the view called drink
}
}
If food, drink or any other items have their own unique view in storyboard this is achievable.
You can assign a string to each button in UICollectionView and check which item in the collection was tapped and do a performSegueWithIdentifier: with button string.
performSegueWithIdentifier("toComments", sender: self)
Then prepareForSegue: method to pass data. Do another if for drink.
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "toFood" {
let ExchangeViewData = segue.destinationViewController as! FoodViewController
ExchangeViewData.foodMenuToShow = foodMenuID //This can be anything that you get your food items.
}
}
You can't do what you are asking for. A segue identifier is what determines which view controller gets invoked by the segue. If you want to go to a different view controller, invoke a segue with a different identifier. By the time you get to prepareForSegue it's too late. The segue to a specific view controller is already in progress.
You should explain what it is you're trying to do and we can help you solve your problem rather than trying to fight the APIs and do something that's neither possible nor appropriate. (Your question is an example of an "XY problem".)
I promise that I'm completely new to Xcode and Swift, so I know I am making silly mistakes but I don't know where. This is part of my iOS app storyboard:
where the segue between the first table view and the second navigation controller is called myTaskDetailSegue and its type is Show (e.g. Push). Now I have some problems:
Neither in the first table view controller nor in the second the back button is showed and I don't know why. Many people told me that navigation bar and back button are as default in navigation controllers but they did not appear
In the class of the first table view controller here is the method prepareForSegue()
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "myTaskDetailSegue" ) {
let indexPath = self.tableView.indexPathForSelectedRow()
let task = self.taskCollection[indexPath!.row] as Task
let controller = (segue.destinationViewController as! UINavigationController).topViewController as! DetailsMyTasksViewController
controller.detailItem = task
println("segue mostra task \(task.id)")
controller.navigationItem.leftItemsSupplementBackButton = true
}
}
so you can read that the segue identifier is correct but when a row is tapped nothing happens and the second table view controller is not showed.
I don't really know what I am missing because of my inexperience.
Here is the complete storyboard:
You don't need two UINavigationController's to what you want to achieve. Is important to note that every time you push(with a segue or manually) a new UIViewController it's added to the navigation stack.
According to Apple:
Pushing a view controller displays its view in the navigation interface and updates the navigation controls accordingly. You typically push a view controller in response to user actions in the current view controller—for example, in response to the user tapping a row in a table.
So you can remove the second UINavigationController in your Storyboard and make the segue directly to your DetailsMyTaskViewController and update your prepareForSegue like in the following way:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier == "myTaskDetailSegue" ) {
let indexPath = self.tableView.indexPathForSelectedRow()
let task = self.taskCollection[indexPath!.row] as Task
let controller = segue.destinationViewController as! DetailsMyTasksViewController
controller.detailItem = task
println("segue mostra task \(task.id)")
}
}
And your back button should appear by default as you said before. Nevertheless I strongly recommend you read the following two guides :
UINavigationViewController
View Controller Programming Guide for iOS
For a better understanding of the navigation stack, etc.
I hope this help you.
I must be doing something wrong here.
I have a UITableView, and have implemented a UISearchController.
I have a Prototype cell linked to the details screen and pass the selected value in the prepareForSegue method.
For the normal view controller, all works OK, a row is selected and the details screen pushed (i.e. slide in from right).
However when there is an active search, using the UISearchController, the details screen is presented modally (i.e. slide up from bottom of screen) without the UINavigationBar (so there is no possibility to go "back")
I am not using didSelectRowAtIndexPath since I have used storyboard to push the details screen
Why is the presenting animation different when the same code in "prepareForSegue" is being correctly called in each case:
// MARK: - Navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if (segue.identifier! == "PresentContactDetail") {
// pass person details from selected row
if let selectedRow = self.tableView.indexPathForSelectedRow()?.row {
let selectedPerson = self.visibleResults[selectedRow]
(segue.destinationViewController as ContactDetail).personRecord = selectedPerson
}
}
}
Any suggestions gratefully received.
in ViewDidLoad of UITableViewController set
definesPresentationContext = true