I want to display next ViewController ondidSelectRowAtIndexPath and is happening as follows.
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
var section = indexPath.section
var row = indexPath.row
var cell:UITableViewCell = self.tblView.dequeueReusableCellWithIdentifier("cell") as! UITableViewCell
cell.textLabel?.text = "hello"
return cell
}
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let storyboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
frequentVC = storyboard.instantiateViewControllerWithIdentifier("frequentVC") as? DropOffFrequentVC
self.presentViewController(frequentVC!, animated: true,completion: nil)
}
The nextViewController is presented and i dismiss the UIViewController as self.dismissViewControllerAnimated(true, completion:nil) and again the previous UIViewController gets called but now when i wait for sometime and try again presenting UIViewController, the UIViewController gets called very slowly but thedidSelectRowAtIndexPath is called instantly. During the waiting period if i tap aroundView anywhere then instantlyUIViewController is presented.Also, if i tapp for two timesUIViewController is presented instantly.
HERE IS THE PROJECT:
https://drive.google.com/open?id=0B6dTvD1JbkgBN0J3SkFOTDJtZlU&authuser=0
I've encountered this many times.
I don't fully understand why this fixes the problem but it works.
tableView.deselectRow(at: indexPath, animated: false)
Make sure animated is false and call this before you present the view controller.
My hypothesis:
The selected cell is the first responder.
Therefore it's in charge of presenting the new view controller.
Hence the lag.
We can't see the actual UITableViewCell code because it's private but something in there is responsible for performing that action with a delay.
Note: The response above said that the lag is due to using storyboard.
That is wrong because I'm not using storyboards and I still get the lag.
I downloaded you code. Did not experience any lag in opening the ViewController. It may depend on the performance on your computer (if running in simulator like I did).
However, you should definitely make some changes to your code. Firstly look into how storyboards can be constructed. You are making a lot of UI in code now which is both harder and in your case performance wise bad. Always creating a new UILabel and other UI-element every time cellForRowAtIndexPath is called is a bad practice.
Secondly using seques with storyboards also makes your life easier. Skip presentViewController and use performSegueWithIdentifier and other methods instead. A lot of the logic can be created directly in Interface builder by just dragging between the views.
http://www.raywenderlich.com/81879/storyboards-tutorial-swift-part-1
You should present your viewcontroller in main thread just like:
DispatchQueue.main.async {
self.presentViewController(
frequentVC!,
animated: true,
completion: nil
)
}
Related
I have a tableview list with clickable cells, when one is clicked a new viewcontroller opens up. When a back button is clicked and the first VC is called, the tableview resets to the top of the list. How can I change this so when the back button is clicked the tableview goes back to the original cell clicked? From what I understand, I need a tableview.scrollToRow, but I'm getting a little lost in the indexPath that I need to select (believe I need to save the last selected row, but now sure how to do this)
Here's the code:
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let webVC = UIStoryboard.init(name: "MainVC", bundle: nil).instantiateViewController(withIdentifier: "SecondaryVC") as! WebViewController
webVC.urlLink = self.listings?[indexPath.row].url
self.present(webVC, animated: true, completion: nil) }
override func viewWillAppear(_ animated: Bool) {
tableview.scrollToRow(at: indexPathSelected, at: .middle, animated: false)
}
Your problem is that you are actually moving forward to a new instance of your view controller rather than back to the existing instance. If you move back then the state of the view controller will be as you left it and there will be no need to do anything to the tableview.
You should use an unwind segue to move back
As your cell is respond to your touch(and you did not call deselectRow(at indexPath: IndexPath) after selecting cell), the tableView will keep your selection(s), so when you back to your viewController just call tableView.indexPathForSelectedRow(or tableView.indexPathsForSelectedRows) in your viewWillAppear() method.
First sorry for my english.
I have a UISplitViewController and i replaced the template master UITableViewController with an UIViewController put a UITableView and UIContainerView what contains a second static UITAbleViewController for settings one of this settings cell has another detail UITableViewController to change its value. on iPhone works well but on iPad with that splitviewcontroller this settings value table shows over on the splitviewcontroller detail view. its good too but i can't hide anymore. (On iPhone has a back button and just works well)
I couldn't find the solution.
My question is how can i hide that detail view to show the original detail view of the split view?
Here are my 3 pics from storyboard, the initial view and when the settings values are opens(that can't be hide n iPad)
Any advice would be nice. Thanks
Storyboard
Ipad screenshots
Finally i made an easy solution. Delete show detail storyboard segue on settings tableviewcontroller and define didSelectRowAtIndexPath for custom push
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
//i want only the third row to perform an action
if indexPath.row == 2 {
let mainStoryboard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let groupListViewController = mainStoryboard.instantiateViewControllerWithIdentifier("GroupListViewController") as! GroupListViewController
self.navigationController!.pushViewController(groupListViewController, animated: true)
}
}
This way i can push any view to the split view left or right side cos both have navigation controller. After this i defined the same function on the pushed tableviewcontroller fire some action and go back. It works like a charm on iPad and iPhone too.
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
self.appDelegate.client.selectedGroupIndex = indexPath.row
//The main master viewcontroller of split view
let vehicleListViewController = self.navigationController?.viewControllers.first as! VehicleListViewController
//settingsviewcontroller that embedded in master viewcontroller
let vehicleListSettingsViewController = vehicleListViewController.childViewControllers.first as! VehicleListSettingsViewController
//call a custom function on embedded settings viewcontroller to change selected value
vehicleListSettingsViewController.changeGroup(indexPath.row)
//refresh splitviewcontroller's master tableview
vehicleListViewController.tableView.reloadData()
//Easy go back to masterview
self.navigationController?.popViewControllerAnimated(true)
}
I haven't coded this, but I am wondering if it is even possible and how it can be done. Let's say I am on VC1. If I press a button on VC1, I want to be taken to VC2, which has a table view, and then have it automatically select the first cell and segue to a VC3. Anybody with experience of doing this.
Assuming this is more of a conceptual question, yes, this can be done. I've worked on an app where the feature required animating through multiple levels of table views programmatically using NSNotification's. Essentially, you can just have a shared method that is called from tableView:didSelectRowAtIndexPath: that you would call directly to "select" the table cell and do whatever the default action was.
Let me know if this answers your question.
Yes It can be done.There can be many ways, One way is this -
1.In Your viewDidAppear of VC2 have this lines -
override func viewDidAppear() {
super.viewDidAppear()
let rowToSelect:NSIndexPath = NSIndexPath(forRow: 0, inSection: 0)
tableView.selectRowAtIndexPath(rowToSelect, animated: true, scrollPosition: UITableViewScrollPosition.None)
self.tableView(tableView, didSelectRowAtIndexPath: rowToSelect)
}
In your tableView method didSelectRowAtIndexPath -
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if indexPath.row == 0 {
self.presentVC3()
}
}
func presentVC3() {
//Initialize VC3
// And Segue to VC3
}
I am totally new at IOS swift and working with android.
Here is my issue :
I'm developing a simple chatting App of IOS. I've already completed android ver and this is a kind of clone.
It has view controllers named VCList, VCMyFriends and VCChat. VCList is my very first view controller and has a table view. Touching a table view cell changes current view controller to VCMyFriends or VCChat.
When I touch a cell, app checks the member counts of the cell, so if it has other members then go to VCChat. If not, VCMyFriends on to invite my friends. Like following pic.
What I found is, I cannot assign two segues on a cell or split a segue with two ways. So I thought that can I change my VC without a segue? However I could not find any references or tutorial about it.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if( memberCnt == 0 ) {
self.presentViewController(VCMyFriends(), animated: true, completion: nil);
} else {
self.presentViewController(VCChat(), animated: true, completion: nil);
}
}
Above is my last try, and failed. It moves somewhere, but shows nothing at all. And if I can, I wish to use segues because have some datas to pass with segue.
Take care.
What I normally do is to create an instance of the controller via the instantiateViewControllerWithIdentifier and set the necessary member variables before calling presentViewController. You can also add a NavigationController if you want the capability the go back to the previous window.
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath)
{
let mainStoryBoard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
if( memberCnt == 0 )
{
let vcMyFriends = mainStoryBoard.instantiateViewControllerWithIdentifier("VCMyFriend") as! VCMyFriends
vcMyFriends.membervar1 = membervar1
vcMyFriends.membervar2 = membervar2
self.presentViewController(vcMyFriends, animated: true, completion: nil)
}
else
{
let vcChat = mainStoryBoard.instantiateViewControllerWithIdentifier("VCChat") as! VCChat
vcChat.membervar1 = membervar1
vcChat.membervar2 = membervar2
self.presentViewController(vcChat, animated: true, completion: nil)
}
}
membervar and membervar2 are the data that you pass to the View Controllers. You need to set it before calling presentViewController so that they will be available when viewDidLoad is called.
Simply do this
func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
if( memberCnt == 0 ) {
performSegueWithIdentifier("VCMyFriends_segue", sender: self)
} else {
performSegueWithIdentifier("VCChat_segue", sender: self)
}
}
In your storyboard, select the first segue (the red line in your image) and choose Attributes inspector, then add VCMyFriends_segue as identifier.
Do the same thing for the second line (blue) and add VCChat_segue identifier.
Hope this helps
Im pretty new to ios development and am starting with a viewcontroller that displays a table of data. When I click on one of the cells, I try to push a tabbarcontroller into view. It works, but I can't see the tabs and the view area is black instead of displaying either of the two default views associated with the tabbarcontroller.
If I set the tabbarcontroller as the intialviewcontroller, it works fine, but this breaks my design.
Any help appreciated.
UDPATE: this is how I'm pusing the tabbarcontroller into view
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
let vc = TrialSiteViewController()
navigationController?.pushViewController(vc, animated: true)
}
I tried about four different ways to transition from my tableviewcontroller to my tabbarcontroller and the only way I could get this to work was to use a segue setup in my storyboard with an identifier, then call this when I click the cell.
performSegueWithIdentifier("trialSitesSegue", sender: self)
Probably obvious to a lot of IOS developers, but I am new to all this, so still thought I would share.