Hi All,
I am new to coding and have a question that I think might be easy to answer but am not sure. I have created a Storyboard based, Tabbed application with 3 tabs.
Tab 1: Dashboard
Tab 2: Air Quality Map
Tab 3: Fire Map
For Tab 2 (Air Quality Map) I want to use the new system image aqi.medium as the tab bar image. However that image is only available in iOS 14 or later. So I created the function below to change the image based on iOS version and put it in the viewDidLoad method of the View Controller for Tab 2 (Air Quality Map). This function works however...
The problem is that when the App is first launched no tab bar image is displayed on the screen, however the tab title, "Air Quality Map", is shown. Only after the user selects the Air Quality map tab is the tab bar image displayed.
The question is how do I get the correct system tab bar image to be displayed upon app launch depending on the iOS version of the User's device?
Tab 2 (Air Quality Map) View Controller:
import Foundation
import UIKit
import MapKit
import CoreLocation
class AirQualityMapViewController: UIViewController, CLLocationManagerDelegate {
@IBOutlet weak var mapView: MKMapView!
var locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
checkLocationServices()
mapView.showsUserLocation = true
setTabBarImage ()
}
func setTabBarImage () {
if #available(iOS 14.0, *) {
tabBarItem.image = UIImage(systemName: "aqi.medium")
}
else {
tabBarItem.image = UIImage(systemName: "globe")
}
}
Post
Replies
Boosts
Views
Activity
Hi All, I am trying to code something that seems very simple but have not found any documentation online for my scenario. Here are the App Details:
Storyboard app built using Interface Builder and a Tab Bar Controller
There are 3 tabs and no Navigation Controller (No Navigation controller on purpose to make the App simple)
Tab 1 = Dashboard (ViewController)
Tab 2 = Air Quality Map (AirQualityMapViewController)
Tab 3 = Fire Map (FireMapViewController)
The issue is that I would like Users to be able to navigate to the Maps from the Dashboard when they touch different buttons on the Dashboard(disguised as an image) or use the Tabs.
Segues won't work since the new screen covers the tab bar at the bottom of the screen. I am looking for a solution that does not cause the tab bar to be hidden after the User is presented the new screen.
So I put the following code in the View Controller for Tab 1 (Dashboard) after the viewDidLoad method hoping it would work, but I get an error, "Swift runtime failure: Unexpectedly found nil while unwrapping an Optional value" when the code hits the line below:
Do I need to create a new class for the UITabBarController? If so how? Any advice would be appreciated as I am new to coding!!!
Line where the error occurred:
let tabBarController = appDelegate.window!.rootViewController as? UITabBarController
Here is the full function:
@IBAction func fireMapButton(_ sender: Any) {
print("Fire Map Button tapped")
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let tabBarController = appDelegate.window!.rootViewController as? UITabBarController
tabBarController?.selectedIndex = 2
self.dismiss(animated: true, completion: nil)
}
Hi,
I am coding my first App and have never coded before and need some guidance with the @escaping completion handler logic.
I am trying to get the count of fires from a third party API and then pass the count using a shared Data Container class to my main View Controller.
The issue is that when I call the func loadInitialFireMapData on my main View Controller, I am getting an error "Expected expression in list of expressions"
This is because I don't quite understand yet how to call a function when there is a completion handler
The @escaping completion handler is necessary since the main View Controller needs to wait for the API call (func loadInitialFireMapData) to finish in order to get the fire count.
Any advice would be greatly appreciated!
See the code from the Main View Controller and the API call with the @ escaping function from my FireDataManager.swift file.
Here is the code from my Main View Controller:
// ViewController.swift
class DataContainer {
static let shared = DataContainer()
var fireCount: Int = 0
var fires: [Fire] = []
var totalFireCount: Int = 0
}
class ViewController: UIViewController, CLLocationManagerDelegate {
let dataContainer = DataContainer.shared
let fireDataManager = FireDataManager ()
override func viewDidLoad() {
super.viewDidLoad()
//Retrieve Fire API data from Fire Data Manager
fireDataManager.loadInitialFireMapData (completion: ([Fire]) -> return) {
self.FireStatusLabel.text = (String(DataContainer.shared.totalFireCount) + " fires within 100 miles of your location.")
}
Here is the FireDataManager.swift file with the API call/@escaping completion handler function.
// FireDataManager.swift
class FireDataManager {
func loadInitialFireMapData(completion: @escaping () -> Swift.Void) {
if let url = URL(string:
"https://opendata.arcgis.com/datasets/68637d248eb24d0d853342cba02d4af7_0.geojson")
{
URLSession.shared.dataTask(with: url) {data, response, error in
if let data = data {
do {
let features = try MKGeoJSONDecoder().decode(data)
.compactMap { $0 as? MKGeoJSONFeature }
let validWorks = features.compactMap(Fire.init)
DataContainer.shared.fires.append(contentsOf: validWorks)
DataContainer.shared.totalFireCount = validWorks.count
print("Fire Data Manager Count of Total Fires: ", DataContainer.shared.totalFireCount)
DispatchQueue.main.async {
completion()
}
}
catch let error {
print("FireMap URL Session error: ", error.localizedDescription)
}
}
}
.resume()
}
}
}
Hi,
I created a comment in the forum related to my own question that I want to delete because it was an unformatted blob and is confusing to anyone reading the post. How do I delete my comment.
This is my first time using the forum and I have to say it is NOT user friendly!
Hi All. I am coding my first IOS App and have never coded before and am stuck on a crucial part.
The issue is that when the app is launched, a Dashboard is displayed to the User in the First View Controller.
There is a field on the Dashboard that needs be retrieved from the Second View Controller.
The field in the Second View Controller is the count of records from the mapViewDidFinishRenderingMap function.
Note this is a Storyboard app, with a Tab Bar Controller
The question is: What is the best way for the First View Controller to retrieve the count from the rendered map in the Second View Controller so that the count is displayed on the Dashboard to the User upon launching the App?
Thanks in advance for any suggestions!