Im new here and trying to write my first little App in Swift.
I have to program a little Book-Shopping-App but now I have a problem.
If I press the "add to card"-Button in my DetailView I want to pass my Book-Data to my Shopping-Card-Class. The Shopping-Card-Class is a TableView with an Array.
So this my DetailView: http://fs5.directupload.net/images/160120/tpsdezys.png
If I press this I want to pass it to my Shopping-Card-Class/Screen, here:
http://fs5.directupload.net/images/160120/qhsbi6aq.png
In my DetailView is all the book stuff like :
var autorName: String?
var title: String?
var price: String?
var image: String?
And in the Shopping-Card-Class is a Array, thats it, but I dont know how to pass the data :/
If I press the button I just add the book, I dont switch the screens.
I've used Delegates before but never in combination with arrays,
pls help :/
I used it here, look: fs5.directupload.net/images/160121/8zmfqef4.png
and passed the data to this screen:
fs5.directupload.net/images/160121/2263tiwl.png
I would suggest starting here!
Once you go through these solutions, you will have a much better understanding on how to pass information between ViewControllers. As a hunt you will need to mess around with the prepareForSegue method and use a segue identifier in order to see which view controller you are jumping to, then setting an instance variable of that class equal to the data you have available in this class. This essentially passes the data from one class to the other.
Related
In order to fulfill the promise of MVC I have a question regarding creating structs or not.
Right now, an array of customs UIViews are passed to a ViewController which arranges them.
The custom UIView looks for example like this
class TopView: UIView {
private var text: String
private var question: String
private var explanation: String
required init(text: string,...) {
self.text = text
...
}
....
}
Then those UIViews are passed as an array to a View Controller and a function inside will arranges them. Therefore, lots of arrays of UIViews are stored like this
let derivative: [UIView] = [TopView(text: "", ....),
MainBodyView(text:"",...),
BottomView(text:"",...)
]
So, to have a clear and good code structure I want to know if it better to create structs containing all these information and a function inside the ViewController which extracts the information and put them into views. Or are there better ways to do it ?
The arrays of UIViews will contain always a TopView, MainBodyView and a BottomView. The only difference is in the number of MainBodyView. There can be for example 10 oder 5 MainBodyViews.
Passing views around is very messy and completely violates MVC. It sounds like what you really want to pass here is an instance of a custom configuration struct. For example (this is minimal, just expand it as needed):
struct Config {
struct VConfig {
let text: String
}
let topViewConfig: VConfig
let bodyViewConfigs: [VConfig]
let bottomViewConfig: VConfig
}
Now pass the data and let the target view controller worry about what that means for purposes of views.
This makes sense because you, meaning the first view controller who is assembling this data and passing it to the target view controller, are not in charge of the target view controller's views — you have no business knowing anything about them or touching them in any way. Plus, this way, if it happens that the target view controller uses a storyboard to instantiate the actual views, no problem, as you are agnostic about that (and rightly, as it is none of your business).
I need to do multiple language switching within the app
Need to stay in the current view after switching the language
And my entire application UI needs to be updated to see the replaced language
I found that many people's approach is to reset the root view, which means that you want to re-create the view, the data need to re-request, etc.
I think this is very unreasonable
Do not you use Notification, is there any other way?
If there is a valid link and demo reference is even better
Thank you very much
I'm not sure on how your app works, but why don't you just try something like this:
func updateLanguage() {}
You can use dictionaries to help you to easily update your content. I've made a simple example so you can understand what I'm talking about:
enum Languages {
case english
case portuguese
}
var myLabel = UILabel()
let myLabelText : [Languages : String] = [
Languages.english : "My Label",
Languages.portuguese : "Minha Etiqueta"
]
func updateLanguage(to language : Languages) {
// Updates myLabel's text in real time:
myLabel.text = myLabelText[language]
// Update other UI elements below...
}
Whenever you call the method "updateLanguage", your UI elements will change it's text value in real time, no need to reload anything or to use another "hacks", it's pretty simple and straightforward, I have this approach on my apps, and it just works.
Hopefully that helps!
Try loadView() to refresh same view controller. And add same method in other vc's viewwillappear from which u have pushed that vc .
I am currently developing a subscription app.
I currently have 6 View Controllers to which have different options on.
For example - Name - Amount - Date etc.
Once the user completes these, I want it to create a new view controller with this information on it.
So once they go back onto the main screen, they will be able to swipe left and it will show their subscription.
All I want to know is, is there a way I can create a new view controller with their information on it once they press a complete button on the Date page?
Transferring data to a view controller is the easy part. I am more wondering on how I can create a new view controller when they try and add another Subscription, if that makes sense.
If not is there a way I can do this?
You have two options that I can think of. I am sure there are more, but these may help.
You could create a global instance of a struct that is your "subscription to add". You could then update the values for each property of this struct (e.g. name, amount, date, etc.) after each VC is dismissed
You can pass the data your user is generating to each VC through prepareForSegue. This is slightly redundant so I would recommend doing the first method. For the record, this segue method would look something like this:
VC 1 Dismissed: Pass Name to VC2
VC 2 Dismissed: Pass Name and Amount to VC3
VC 3 Dismissed: Pass Name, Amount, and Date to VC4 etc......
Once you have all of the information, you can show the last VC and just set the labels and such to the values of your struct, or the values you passed through the segue.
Edit: Further Information on Option 1
So if you made a struct like this:
struct UserToAdd {
static var name: String = String()
static var amount: Int = 0
static var date: Date = Date()
}
with all of the properties that you want a subscription to have, then you can store this information in this struct as you progress through each VC.
For example, if your first VC got the subscription name, then when your "prepareForSegue" function is called, as you are about to move to the second VC, then you could do something like this:
UserToAdd.name = "My Subscription Name"
Of course the string you assign to this name would depend on the data the user enters and such, but I hope it illustrates my point. It would be a similar process for each initial VC, but then once you have all of the data you need, you could just then call this data when your last VC loads, and set it to the text of a label or something like this:
var nameLabel = UILabel()
nameLabel.text = UserToAdd.name
self.view.addSubview(nameLabel);
Let me know if you have any further questions.
I am trying to navigate to a UIViewController using Swift 2.3. To be more precise, I am trying to reload the UIViewController that is currently active. I do not know which view the user currently has active, so this must be defined dynamically.
I have tried several approaches, but they all result in either compile or runtime errors.
Is something like this possible?
let activeViewIdentifier = ??? // Get currently active view identifier as a string
self.performSegueWithIdentifier(activeViewIdentifier, sender:self)
You can get like this :
Objective-C :
self.navigationController.topViewController.restorationIdentifier
Swift :
self.navigationController?.topViewController?.restorationIdentifier
I think you have some issues with your architecture; it's not the best approach to reload just everything on some View Controller you can chose;
Much better way of thinking is to determine, what exactly you want to reload and add methods to reload only thus things
Anyway, if my answer hasn't assure you, consider replacing existing view controller with new and presenting it with some animation, or without it; so your general algorithm may look like this:
Get new VC from storyboard, or creating new instance, if you don't prefer to use it
Push it over your existing controller
Reload stack of navigation controller, in which you are now
you can try this
let activeViewIdentifier = self.navigationController?.childViewControllers[(self.navigationController?.childViewControllers.count)!-1]
You can use the restorationIdentifier, it's right above the Storyboard identifier and it's a UIViewController property.
let activityIdentifierStr = activeViewIdentifier?.restorationIdentifier
self.performSegueWithIdentifier(activityIdentifierStr!, sender:self)
I'm trying to learn how delegates work and wrap my head around the concept. I'm finding I get some of the ideas. I understand you use it to pass data from one view controller to another, however wouldn't it work the same if I just sent data from a segue and every time the 1st view controller would appear, it would use that data?
So for example I have 2 view controllers.
1 is homeViewController and
2 is editViewController.
I have a variable titled "addressOfHome" which is a string in homeViewController(1).
In homeViewController under the method "viewDidAppear"
I also set the addressLabel = addressOfHome.
Then I just pass the data from editViewController(2) to homeViewController(1)
when the segue's destination vc is homeViewController ?
I'm terrible at explaining things so I apologize for that, but I gave it my best shot. Thanks for your time!
Delegates are mainly used to "trigger action" on an object from another one.
An object delegates a way to handle something to someone else, for example when you click on an UIAlertView button, if its delegate is set on a viewController, alertView:clickedButtonAtIndex will be executed on the VC, which can so react as it want
I'm terrible at explaining things
Haha, yes, you are !
A delegate isn't for that - a delegate is a way to over-ride the default behaviour of some feature(s) of a class, without creating your own sub-class. See this post : How does a delegate work in objective-C?
Are you trying to understand how delegates work (in which case, I don't think your example is one that requires a delegate) or are you trying to implement the functionality you describe, and think that a delegate is the way to do it? (I think you actually want a data source).