I am aware of most of navigation handling in Compose, but just curious to know how to change the starting screen based on some dynamic login.
Currently my code is like this
WeatherWalaTheme {
CompositionLocalProvider(
LocalDependencyContainer provides dependencyContainer
) {
DestinationsNavHost(navGraph = NavGraphs.root)
}
}
And here the first screen is automatically the one which has start = true for Root navigation graph. But I want to go to different screen based on the API Response on this activity which contains this code.
The normal NavHost has an overload where you can specify a starting destination.
Related
I know that the component List has an UITableView behind. I also know I can change the background by changing the UITableView.appearance().backgroundColor.
What I want is to change this for a single View that has a List component, without affecting the rest of the application. Is this possible? If so, how?
Thanks!
This is what I know needs to be done to achieve this:
var body: some View {
List {
//Your content
}
.onAppear {
//The specific table view settings.
//UITableView.appearance().separatorColor = .black
}
.onDisappear {
//The general table view settings
//UITableView.appearance().separatorColor = nil
}
}
But it is problematic for several reasons.
The biggest reason is the fact you might have 2 table views in the same View and you want them to have different appearances.
The second issue is that not all cases will call onAppear (I don't remember specific cases but I remember having issues with TabViews)
I hope there's already a better solution waiting in the next version of SwiftUI.
I am using a 5 container view inside one view controller. All container view are of same size (same width and same Height). Different API are performed on different container view.
The approach which I am implementing is showing and hiding the container view as per the button action.
Example : On click of button one, ContainerViewOne is shown and rest are hidden.
Problem which I am facing is that when the view controller is loaded all the api in all container view is called at the same time. I want it to run when the container view is shown. Can anyone help me with the same?
Try This One
I think you find something like this.
1) create APICaliing and data reload function in yourContainerViewController.
2) Find yourContainerViewController from YourMainViewController childViewControllers.
3) call APICalling Function.
#IBAction func btnClickEvent(_ sender: UIButton) {
//Find yourContainerViewController from your all childViewControllers
for vcObj in self.childViewControllers{
if vcObj.isKind(of: yourContainerViewController.self){
// Here your api call and reload data inside this function
// apiCallFunction() Function create in you yourContainerViewController and put api calling and data reload code in this function.
(vcObj as! yourContainerViewController).apiCallFunction()
break
}
}
}
Happy To Help You :)
I have prototyped siri shortcuts in my app using custom intents successfully. I would like to define custom UI for different shortcut types. For example IntentA would show a tall card with lots of labels and IntentB would show a short card with an image and one label.
I don't see any direct link in the code between the IntentViewController used in the MainInterface storyboard and the intent definition file.
If possible, I would like to have IntentAViewController and IntentBViewController defined in the MainInterface storyboard and handle them accordingly, but I don't see where I would tell the extension which viewcontroller or storyboard id to load for each intent.
If not possible, then what is the best practice for accomplishing multiple intent UIs? (I haven't found any tutorials that had more than one intent).
I found the solution inside the SoupChef example app from Apple. Since there is only one main IntentViewController and one MainInterface storyboard, using intents you should detect the intent type and add the necessary view controller as the child of the IntentViewController.
From IntentViewController in SoupChef:
/* Different UIs can be displayed depending if the intent is in the confirmation phase or the handle phase.
This example uses view controller containment to manage each of the different views via a dedicated view controller.
*/
if interaction.intentHandlingStatus == .ready {
let viewController = InvoiceViewController(for: intent)
attachChild(viewController)
completion(true, parameters, desiredSize)
} else if interaction.intentHandlingStatus == .success {
if let response = interaction.intentResponse as? OrderSoupIntentResponse {
let viewController = OrderConfirmedViewController(for: intent, with: response)
attachChild(viewController)
completion(true, parameters, desiredSize)
}
}
(where attach child calls addChild, addSubview, didMove and sets up constraints)
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'm looking for a way to show a UIView "InventoryView" in 2 view controllers.
I'm working on an inventory system for my game that I trying to make but I need to be able to access it from my main view, where it will go to a InventoryViewController (in this ViewController is my InventoryView) but I also need to be able to access the InventoryView from my BattleViewController where it does not go to my InventoryViewController but where it print the InventoryView on my BattleViewController so I can access everything durning the battle.
Example:
(evrything is dragand drop, the UIView and the UIButtons)
InventoryViewController
class InventoryViewController: UIViewController {
class InventoryView: UIView {
//here are some UIButtons and labels
}
}
BattleViewController
class BattleViewController: UIViewController {
class InventoryView: UIView {
//it should print the Inventory Screen on my BattleViewController
//here are the same properties as it shows in the InventoryViewController
}
}
This is a great example to look at the way OOP programming works best.
Ask yourself the following questions:
What is the purpose of the view?
Are the interactions on the view homogenous across all the instances? (touch events, specific behavior, etc...)
What is the minimum amount of information you need to make the view look the way you want?
Once you have those answers, you can approach the concept of reusability of views safely.
The way to go about it is to subclass UIView, create the necessary elements of your view, setup your constraints (still in the view, either in a nib or programmatically), and implement any behavior that will be consistent across views (For example if the view is a segmented control, every time you click a segment all the others go grey and the one you clicked go blue. Since that's the primary purpose of the segmented control, the code for it should belong to the segmented control).
Chances are you will find the docs very useful: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/
Lastly write a setup method that takes all the information you need and sets up all your graphical elements accordingly. Remember, views should never own their data (they should be templates, the controller will provide the data).
I have no idea what you view looks like but I assume the inventory is represented as an object. Then something like could be a good start:
class InventoryView: UIView {
var inventory: Inventory? {
didSet {
if let newInventory = inventory { //in case we set it to nil
setup(withInventory: newInventory)
}
}
}
private func setup(withInventory inventory: Inventory) {
//do your setup here
}
}
Then in your controller you can call:
let inventoryView = InventoryView()
inventoryView.inventory = myPlayer.inventory
You cannot use a view in two places, at least not within the UI. Every view can be added to only one super view at a time.
If you need the same contents to be displayed twice, create a UIViewController class which's view contains the common UI, create two of those and add them to your UI.