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 .
Related
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)
Say I have an app that has a fixed layout: one button and a few labels. It makes sense not to use multiple view controllers throughout the app since I have the same button and labels. I don't want to copy and paste them because their look and style will never change. If I decide to change their look later on, I would have to go through every single view controller and this is a bad practice (as it is with copying and pasting code).
Though, I want to be able to let the user go back and forward "layouts" the app, but this code doesn't let me do that:
class MyViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
enterFirstLayout()
}
func enterFirstLayout() {
// do things such as change labels' text property
exitFirstLayout()
}
func exitFirstLayout() {
// do things
enterSecondLayout()
}
func enterSecondLayout() {
// ...
}
}
What can I do to avoid creating multiple view controllers and giving the user the possibility to skip and go back to a specific layout of the app?
I'm assuming that you are trying to achieve something like wizard that you can go back and foreword thru screens.
In this case I would use a UICollectionView with UICollectionViewFlowLayout. Build one custom cell that represents your single 'screen' layout than build a simple datasource as an array of custom objects. Datasource should contains for example all label's content as a String variables.
Nice and elegant code.
You get scrolling animation and swipe gesture detection for free. If you like you can add your custom fancy animation.
This is my solution. Going back to your question, if you want to do this your way, you can for example use subclassing. Build your base view controller class with all layout configured and labels exposed as public, read-only variables, then inherit from this class. Please keep in mind that subclassing is tightest possible coupling.
Other option is to build this view controller once and reuse with different dataset.
So decision is your. I would go in 1, 3, 2 order :)
I am new to both iOS development and programming in general. I need some clarification as to what sort of things should be declared in the viewDidLoad function of a UIViewController subclass
Thanks
In order to properly understand what viewDidLoad does, you should understand the View Controller Lifecycle. The best point to start is reading the Apple Documentation, e.g. the learning guides for developing iOS Apps: https://developer.apple.com/library/prerelease/ios/referencelibrary/GettingStarted/DevelopiOSAppsSwift/Lesson4.html
Declare elements that don't need to be refreshed or recreated when the view reloads. For instance, viewDidLoad is called only when it is created while viewDidAppear will be called every time the view is shown.
Read up on some apple docs.
Everything you write inside the viewDidLoad function will run the the View(which can be TableView, ViewController & more..) is loaded.
For example, if you got a label called 'label' and you want to set it's by the code so you type:
override func viewDidLoad() {
super.viewDidLoad()
label.text = String("any text here")
}
and then the text of the label will change when the View will load.
I have created a timer class in swift and when a user clicks a button I segue to another view and pass data between the two views. The time class uses 3 separate labels for hour, minute and second however I would like to pass all 3 in a single variable.
My question is, how do I access the text inside a label. If I use "\(hourLabel.text)" (for example) I get a message "Optional(00)".
If you're trying to access another view controller's view objects (a UILabel, for example) don't do that. It violates the principle of encapsulation, and also often doesn't work.
If try to evaluate hourLabel.text where hourLabel is an outlet in your current view controller, the outlet link is probably broken (and nil.)
Post the actual code you are trying to use.
Use this...
if hourLabel.text != "" {
println("\(hourLabel.text!)")
}
Why don't you try this...
if(!hourText.text){
// Do something...
}
The solution in this question* uses setHidden to hide and unhide a WKInterfaceGroup:
atypeofGroup.setHidden(true)
atypeofGroup.setHidden(false)
But the problem is, the group will appear and disappear abruptly, it doesn't look professional. Can someone guide me please? Not sure whether it is related to this:
atypeofGroup.animationDidStart(anim: CAAnimation!)
*hide and show WKInterfaceGroup programmatically
This is a great question, but it just isn't possible to animate a change between two groups with the current implementation of WatchKit. I definitely wish it was as well.
The only options you have are to switch interface controllers entirely through the reloadRootControllersWithNames:contexts: or to show/hide a couple of groups using the approach you listed first. Here's a small example of how you could switch from a SimpleInterfaceController to a FirstInterfaceController and SecondInterfaceController in a page set.
class SimpleInterfaceController : WKInterfaceController {
override func willActivate() {
super.willActivate()
let names = ["FirstInterfaceIdentifier", "SecondInterfaceIdentifier"]
WKInterfaceController.reloadRootControllersWithNames(names, contexts: nil)
}
}
I am not sure where you found the following code snippet, but it is certainly not part of the public APIs on WKInterfaceGroup.
atypeofGroup.animationDidStart(anim: CAAnimation!)
While I understand none of these answers are ideal, they are all we have access to at the moment. If you have the time, I'd suggest filing a feature request on Apple's bug reporting system.