enter image description here
This is my current swift code in Xcode. I have 2 problems, the first one being unable to control-drag the textfield to the code. The second one is how to transition from the first scene to the second scene.
first scene is the access_code one,
the second is the map view.
I want to be able to have the user enter an access code in the text field, and when they hit return. the program will change the view to the map view. (the user will get different maps based on the code they enter).
Thanks
For the first problem, I see that on the right side you have manual UIViewController set.
If the UIViewController on the right is not matching scene to the right it will not work. (You can't drag text field to the code.) It is very hard to say what is wrong but this could be a clue.
Second think is transition between two scenes.
You will need to create segue between those two screens. You dreg from first UIViewController to another in storyboard and give this seque the identifier.
Then in code, inside method where return key is pressed, call
performSegue(withIdentifier: "myIdentifireSetInStoryboard", sender: self)
To get method that is called when return key is pressed, look into UITextfieldDelegate method textFieldDidEndEditing...
I hope it help.
Related
I'm creating a simple app which has a tab bar controller where the summary is one tab and the history is another. In the summary tab, there is a button to add a new round. Whenever this round gets added it has to go to the history tab as well.
I'm trying to send the data through the tabBarController.
What I'm experiencing is whenever I don't open the history tab before adding a new round my program crashes because my IBOutlets are nil. But whenever I open the tab first and then go back to add a new round it works fine. I also don't have to reopen the tab after every round. It looks like the tab isn't getting instantiated before I open it up the first time.
Gif of failure (Error is that the Chart View is nil):
http://i.imgur.com/VPa0RmK.gifv
Gif of success:
http://i.imgur.com/LqxYBjV.gifv
Is there any way to do this manually?
I'm new to iOS programming so that is what I think the problem is. If there's happening something else that's crashing my code I'd like to know!
You are right. The problem is that the outlets for the second tab do not get set up until you visit that tab.
Solutions:
You can write the data to a property of the second viewController, and then move that data into the outlet in an override of viewWillAppear.
Another possibility is to check if the outlet is nil before you write to it. If it is, call loadView on the second viewController to tell it to set up its outlets, and then you'll be able to write to them. Note, if you call loadView manually, the method viewDidLoad will then not run, so if you're doing any additional setup in there, you'll also need to do that from loadView.
Perhaps even simpler than calling loadView manually is to trigger the viewDidLoad of the secondViewController by accessing the view property. This can be as simple as:
if let svc = self.tabBarController?.viewControllers?[1] as? SecondViewController {
// check if outlet is nil
if svc.myLabel == nil {
// trigger viewDidLoad to set up the outlets
_ = svc.view
}
svc.myLabel = "Success!"
}
That said, directly accessing another viewController's views (i.e. outlets) is poor design and a violation of the MVC (Model-View-Controller) paradigm. You should really put your data in a place that can be accessed by all tabs and then have each viewController update itself in viewWillAppear when the tab is selected. See this answer: Sharing data in a TabBarController for one way to do this.
This is how it's supposed to work. Each Tab is created only when it has to be displayed. This the same idea for TableViews and CollectionViews.
The easy one to fix this for you is to override the viewWillAppear (or viewDidAppear) method of your HistoryViewController and refresh the UI from there.
This way, you never assume that the History tab exists in the Summary tab, History refreshes its UI by itself.
Hope this helps.
i'm fairly new to swift, so please bear with me.
right now my problem can be broken down to this:
I have one Test View Controller that can display my 'Test' object by showing the description and the title. I also have an array of Test objects. In the top right hand corner, there is a 'skip this test' button, and if the user clicks on it, the viewcontroller will segue to itself, but change the Test object that is being displayed, e.g. its just basically looping through an array of Tests. I have changed the prepare for segue methods accordingly to push the data through the view controllers.
However, I want to be able to move to a completely different ViewController (lets just call it FinalViewController) if I have reached the last Test in my Test array.
Now this is the part that I can't fix.
I would like to create a segue directly from the 'skip test' button, only that it segues to a different view controller, depending on a certain condition. However, as i tried creating a segue in IB by right clicking on the Button and pulling it to the FinalViewController, it erased my previous segue I had for that button.
Does anybody know if there is a fix for this problem? thank you!!!!
However, as i tried creating a segue in IB by right clicking on the
Button and pulling it to the FinalViewController, it erased my
previous segue I had for that button
Actually, you don't want to do that, instead, you should drag from the controller itself, not from the button because if your segue has been created based on a button, tapping on it should always perform it and this is NOT what you want.
After creating a segue from the ViewController, you can -programmatically- call performSegue method and handle what data should be passed to the next viewController by implementing prepareForSegue method.
For more information, check my answer to know how to create multiple segues with identifiers and work with them.
EDIT:
If you want to push to the same current ViewController, performSegue method would not be the optimal solution. You should instead push/present to same ViewController it self:
class ViewController: UIViewController {
var myString: String?
override func viewDidLoad() {
super.viewDidLoad()
// here we go
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let sameViewController = storyboard.instantiateViewControllerWithIdentifier("ViewControllerStoryboardID") as! ViewController
sameViewController.myString = "the value of the new myString"
navigationController?.pushViewController(sameViewController, animated: true)
print(myString)
}
}
Probably, you don't want to implement it in viewDidLoad, it's just for demonstration purpose.
Make sure that the ViewController has a storyboard ID (in code snippet, I assume it is "ViewControllerStoryboardID"):
In my story board I have VC1>VC2>VC2>VC4
In order to go right back to VC1 from VC4 I have setup the function:
#IBAction func unwindToVcOne(segue: UIStoryboardSegue) {
}
Then adding that to my segue from the storyboard.
Everything works fine except that it shows up as an empty circle in my editor as its not connected:
It works, so is this something that I can ignore?
As far as I know the circle next to an unwind method always shows as empty as there isn't a fixed binding between the storyboard scene and the method the way that there is with an action method.
The IBAction lets Interface Builder know that there is a method it should be interested in; the method signature indicates that it is an unwind segue method.
The actual unwind method that is called is determined at runtime as describe in this Apple Technical Note.
I've got a two View Controllers, when user press a button on the first one - app segue to the second one. But problem is that I need to use custom animation of segue. There is array of images, that must be animated before segue.
I guess that I need to create child-class myStoryboardSegue and override some method, but I don't even know which one.
Hope you can help me to understand.
Here how my storyboard looks like:
Initially when the users taps one of the squares, scene passes to the second one. At this point when the user closes the application and reopens it I want the second scene to come up.
I dont mind if first scene loads and then passes to the second one but I want second scene to show up.
Thanks in advance..
EDIT: I read that I can use generic segue but even if I create a generic segue with control drag from first view controller to the second one and using the code below nothing happens:
[self performSegueWithIdentifier: #"switch" sender: self];
SOLUTION:
You got to have a navigation control :)
In order to user the code below:
[self performSegueWithIdentifier: #"switch" sender: self];
You need to have a navigation control.