Xcode: TableView cell to create ViewController - ios

I've recently started using Xcode and Beginner to creating apps. I've come across something I'd like to implement but research hasn't been quite clear/complicated to understand.
I have a TableView with Days of Week and also a segmentedControl that duplicates these days 3 times. I'm wondering how I'm able to get user click to take me to an alternative ViewController depending on which day it is and what segment of the segmentedController is selected without having to create 21 viewcontrollers in the storyboard.
I've used a ViewController and made an outlet to a tableView for this setup.

in you tableview delegate method -> didSelectedRowAtIndexPath
you can simply write
let vc = UIViewController()
/*
you can add informations here
*/
present(vc, animated: true)
and inside this method you can use the indexPath to get the cell you've clicked
let cell = tableView.cellForRowAt(indexPath)
now you can get the information in this cell

You can have one viewcontroller which is basically a recipe for the viewcontroller you want to go to.
For example you want to show a viewcontroller with a label that states a combination of the number from the segmented control and the date which the user tapped on.
If you now create a ViewController which has a label in storyboard, the text on the label doesnt matter, you can use code to change the text to anything you would like.
In the tableviewcontroller you can use the didSelect delegate method of your tableview to present the viewcontroller and set the label to the values of the segmented control and the cell which is tapped.
I think you just need some more information about iOS and programming in general, therefore I suggest you watch the following iTunes U course:
https://itunes.apple.com/us/course/developing-ios-10-apps-with-swift/id1198467120
It has everything you need to know

Create a detail view controller with two variables (Ex - dayName and selectedSegmentIndex). And in your current viewController "tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)" push detailsViewController with these details like this
let objViewController: DetailsViewController? = UIStoryboard.mainStoryboard().instantiateViewController(withIdentifier: "DetailsViewController") as? DetailsViewController
objViewController?.dayName = dayName
objViewController?.selectedSegment = segmentControl.selectedSegmentIndex
navigationController?.pushViewController(objViewController ?? UIViewController(), animated: true)

Related

Set NavigationBar title on next ViewController without visual bugs

So I have a UICollectionView called WeatherVC that has a NavigationController.
WeatherVC segues to WeatherDetailVC which is UITableView upon UICollectionViewCell selection.
I want to set WeatherDetailVC NavigationBar title based on which UICollectionViewCell was selected.
This code below makes my whole NavigationBar just buggy.
Example: https://imgur.com/a/vOIbxK5
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if let vc = segue.destination as? WeatherDetailVC {
let cities = ["City1", "City2", "City3", "City4"]
// cellPressed = 3 - for example this would work without bugs
vc.navigationItem.title = cities[cellPressed]
}
}
Variable cellPressed was set on cell highlight or tap. It behaves like this only in iOS 13 and only if I give it number based on cell tapped - if it is static, title changes with no visual bugs. I already tried creating functions inside WeatherDetailVC to change its title and calling them in prepare for:segue but it did not help whatsoever.
EDIT: My main problem is those bugs or glitches that comes with this solution. I have no problem with changing next VC title.
Since navigationBar title represents the title of the view controller, You can set it directly:
vc.title = cities[cellPressed]
Assuming cities[cellPressed] is tested and returning correct value
I figured it out. It happens because of the diacritic. If I assign title with diacritic character navigation bar just bugs everytime. Anyone know how to fix it?
EDIT: You can see this happening in IMGUR link that I provided. Character "รก" is in the title.

How to delete a tableView row in VC 1 from a modalVC?

I am using coreData and simply sending data from the tableView cell content that is text and the color of the cell to a modal view controller. In modalVC, I am able to change the text and when I press done, the tableView gets updated.
Now I want to add a feature in which if the text is removed completely and the user press done, the data from coreData should be deleted and so should the tableView row.
Here is what I am doing in order to achieve this:
#IBAction func doneButton(_ sender: Any) {
if edittasktextview.text.isEmpty == true
{
moContext.delete(editnotes[num] as NSManagedObject)
editnotes.remove(at: num)
}
else
{
editnotes[num].sNote = edittasktextview.text
}
}
num is the indexPath which I am sending from the first VC to modal VC (kind of keeping track of which cell is tapped)
Now when I dismiss the modal viewcontroller, a notification is send to the firstVC to trigger a func which essentially reloads the tableView in firstVC. However, while the row is no longer seen in the tableview, I still have have to go back to my rootVC and then back to first VC to update the tableView completely.
Help will be appreciated!
Use an NSFetchedResultsController to let your table view be triggered by CoreData changes.
Here's a tutorial to get you started. There are various other good tutorials and YT videos that are easy to find.

How can I get a Table View to register taps when each cell has an Image View covering it?

I've been trying to create table view cells each with a UIImageView serving as a background for them. However, when I tap on each cell the table view will not register the click and will not transition to the view controller I have hooked up, even while I'm using the didSelectRowAtIndexPath function.
I realize it's probably an issue with the ImageView obstructing the table views ability to register the cell tap. The cells will transition however when I drag my finger/mouse on it from left to right, just not on taps. I tried to use a Tap Gesture Recognizer on the Image View however it only worked for the cell at the very top and not all of them. How do I tackle this issue?
Here is an image of the table view cells so you have an idea of what I'm working with: http://imgur.com/a/Ku4uD. Thank you!
If you uncheck User Interaction Enabled on your Image View, the problem should be solved. When running into a problem always check the user interaction of the most child view and work your way up.
One trick I have also learned is to create a subclass of a child and override touchesShouldCancel like so:
override func touchesShouldCancel(in view: UIView) -> Bool {
print("touchesShouldCancel")
//Run extra code that you want when the user selects this view
//then still retrieve the tap by its parent.
return false
}
I am unsure of exactly what your problem is, but I would delete whatever segue that you have, add a new one by dragging from the yellow circle on the left side of the center portion of the top of your tableView ViewController inside the storyboard, to the viewController that you desire it to segue to. Give the segue an appropriate identifier, and then inside your tableView class under tableView didSelectRow add performSegue(withIdentifier: "ChosenIdentifier", sender: indexPath)
Then in prepare forSegue add in:
if let vc = sender.destination as? TheViewControllerYouAreSegueingTo {
if let indexPath = sender as? IndexPath {
vc.variableIdentifyingWhatCellWasClicked = indexPath.row
}
}
with whatever adjustment is needed to meet your specific needs.

How to add a view to UINavigationController that is visible above any child view

I'm creating an app which shows data in a UITableView. This data also contains location information, so I want to add a MapView to display this data. When a user taps a UITableViewCel, I need to segue to another UITableView to show the detailed data. I still want to show the MapView with the same data above this detailed data, and I still want the NavigationBar to update, i.e. the back buttons returns the user to the first UITableView.
In image form to make it easier to understand
I was thinking of making a subclass of a UINavigationController and putting the container underneath the MapView, but I don't really know where to go from there.
Have VC0 embedded in a navigation controller or subclass UINavigationController. Create an Info ViewController and push that on the navigation controller.
In your particular case you'll want to use the didSelectRowAt method from UITableViewDelegate.
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
// use indexPath.section and indexPath.row to use your data
let infoVC = yourInfoViewController()
infoVC.title = "Info Cell Name"
navigationController?.pushViewController(infoVC, animated: true)
}
Edit after first comment:
I'm not sure what the best way of doing this is but one way you can do it is:
Modify your table view based on what is being shown, ie: first set of data or cell detail data
Update the navigation bar's title and left bar buttons per set of data you're displaying
One of those buttons will only appear in the cell detail data set and it sets your switch back to displaying the first set of data

Swift UITableViewController Reduce Loading Time

I'm currently creating an iOS app in Swift 1.2 with a master-detail UITableViewController setup so that MasterTableViewController has cells that push to DetailTableViewController.
DetailTableViewController has fairly complex cells that pull data from a web client to generate a chart, similar to in Apple's Health app. It usually takes about 5-10 seconds for all the data to download.
As a result, there is a 5-10 second delay when a cell in MasterTableViewController is tapped before DetailTableViewController is shown.
I would ideally like to push immediately from the MasterTableViewController to the DetailTableViewController and then display an activity indicator on the DetailTableViewController page that is dismissed when all the data is downloaded.
Could someone point me in a good direction to accomplish this? Thank you! :)
My code is below for pushing from master to detail. Fairly basic. I feel like if I change something in the viewDidLoad or cellForRowAtIndexPath method, I could get this done fairly easily.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
tableView.deselectRowAtIndexPath(indexPath, animated: false)
let detailVC = DetailTableViewController()
detailVC.navigationItem.title = "Your Charts"
self.navigationController?.pushViewController(detailVC, animated: true)
}
On your detail view controller you can create a UIActivityIndicatorView variable.
In viewDidAppear you can call the activity indicator, bring it to front and start animating it.
The create a function that populates an array that will store the data your cells will use and re work your cellForRowAtIndexPath to use it. (Instead of fetching the data in each cell).
Then in your function to fetch data, right after (or before) you update your table tell the activity indicator to stop animating.

Resources