Swift - Force view to load data after appearing - ios

Heyho,
i got a little problem with two of my view controllers.
They are both collection view controllers.
My problem is, if i click on the button to open the second view it lags and the transition is not liquid. The reason for this lag is the bunch of data the view loads for the collection view(around 400 photos and strings).
Maybe someone of you got a idea how i could defeat this loading inhibition. If you need more information --> just ask.

An easy way to fix that is to load you data in a background thread and reload your collection view (in the UI thread) when it's done:
DispatchQueue.global(qos: .background).async {
// load your data here
DispatchQueue.main.async {
// reload your collection view here:
self.collectionView.reloadData()
}
}

you can use this method to achieve the required result.
override func viewDidLayoutSubviews() {
// Configure the views
}
On the other hand, you have self.view.setNeedsLayout() and self.view.layoutIfNeeded(). Find the one which suits you.

Related

How to quickly open a view controller without executing it's processes?

I have to show various folders which contain a heavy amount of images and videos , but when I click on the folder it takes few seconds to load which seems like it's lagging or hanging ...
I wanna open view controller first and then show the process of loading....
How to do that ???
you can load data in background like this
DispatchQueue.global(qos: .background).async {
// load data here
}
after that need to load UI in main thread
DispatchQueue.main.sync {
// show data here
}
you can solve this problem by using SDWebImage for problem of photos or images loading...
myimageview.sd_setImage(with: imageURL, placeholderImage: UIImage(named: "empty_image_icon"))
//imageURL is URL of image.
//empty_image_icon id the default image which will show during process.
Fetch data in viewWillAppear() method not in viewDidLoad() method.
You can fetch your data/media in viewDidAppear() method and start animating your loading indicator in viewDidLoad() method.
If you load data in viewWillAppear() than your viewController take a time with few second.
You can call your fetching data function after your view created. The viewDidAppear() method is working after your view created but also, this method works whenever the view you create is visible on the screen so it could not be the best solution for every case. It means that, your data could be fetching unnecessarily. For example, viewDidAppear() method is working whenever you change your view controller and come back that screen again or switch your application or your app comes foreground.
Therefore, using dispatchQueue or SDWebImage library could be your answer.

How to make your API run only when the containers view is shown?

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 :)

How can I detect a subview being added anywhere in the view hierarchy (including subviews)?

I am creating a framework for the other apps to use it. I want to find when the display presented to the user changes. These changes include addition and removal of subviews, scrolling down, adding text, etc. Is there a way I can directly check when the content presented on the screen is changing. Above question is a part of the problem.
Did you mean viewDidLoad?
That function called first time after all view loaded same as ViewTreeObserver.OnGlobalLayoutListener.
After you explanations I would simply do something like this:
class MyViewController:UIScrollViewDelegate{
func addSubview(){
self.takeSnaphot()
}
func scrollViewDidScroll(scrollView:UIScrollView){
self.takeSnaphot()
}
func takeSnaphot(){
//the code to take snaphots
}
}

MKMapView using a lot of memory each time i load its view

I have a pretty simple app, with a couple of view controllers. There is a MKMapView in the second view controller. It is set up correctly, and functions fine. The problem is, each time I load its view the Memory usage jumps ~30mb, and never goes back down, so each time i go into the view it keeps jumping and eventually gets super high.
I tried removing the map view when i leave the controller like this:
override func viewWillDisappear(animated: Bool) {
map.removeFromSuperview()
}
but it doesn't have any effect on the memory. The map views delegate is set to its view controller.
I tried checking for leaks using Xcode instruments but didn't find anything.
Does anyone know how to fix this?
Thanks
EDIT:
Adding this seems to work:
func removeNastyMapMemory() {
map.mapType = MKMapType.Hybrid
map.delegate = nil
map.removeFromSuperview()
map = nil
}
override func viewWillDisappear(animated: Bool) {
removeNastyMapMemory()
}
This is not Swift issue, is coming from Objective-C days. The possible ways to handle this issue is depending upon the situation and behavior of the app.
If you're using a Map for multiple times (or places), only create a single (shared) instance of it. Which you can use it whenever you want.
Or If you're only using it for once, then try a solution from here, https://stackoverflow.com/a/25419783/1603234. This may help. Reduce little. But not all.

Swift : collectionView takes too long to display

I am developing an iOS application in Swift.
I display data from database inside a collectionview but it takes too much time to appear on screen.
Surely a thread problem because on Xcode console, I can see data being displayed 20 seconds before it appears on the screen. Here is my code :
https://github.com/ProjetCedibo/projet/blob/master/Projet-L3-master/appli/SJEPG/SJEPG/CenterViewController.swift
How can I make the collectionView being displayed faster ?
If this happens, it means you are making UI changes from a thread other than the main thread. Try this:
func refresh() {
dispatch_async(dispatch_get_main_queue(), {
self.eventsCollection.reloadData()
})
}
What happens is that code is probably run on a secondary thread. Any UI changes you make should be made on the main thread. So try this:
dispatch_async(dispatch_get_main_queue()){
// reload your collection view here
})
In addition to #StefanArentz answer
For Swift 3:
DispatchQueue.main.async {
// code to reload collection view
}

Resources