Multiple MapKit overlay colours from array - arrays

How do I make each bubble a different colour?
Here is my array of colours:
var tableColors = [UIColor(red: 220.0/255.0, green: 95.0/255.0, blue: 19.0/255.0, alpha: 0.9), // Rust
UIColor(red: 255.0/255.0, green: 191.0/255.0, blue: 59.0/255.0, alpha: 0.9), // Yellow
UIColor(red: 255.0/255.0, green: 91.0/255.0, blue: 51.0/255.0, alpha: 0.9), // Red
UIColor(red: 0.0/255.0, green: 160.0/255.0, blue: 174.0/255.0, alpha: 0.9), // KAL
UIColor(red: 0.0/255.0, green: 121.0/255.0, blue: 95.0/255.0, alpha: 0.9), // Green
UIColor(red: 104.0/255.0, green: 68.0/255.0, blue: 88.0/255.0, alpha: 0.9), // Purple
UIColor(red: 244.0/255.0, green: 97.0/255.0, blue: 119.0/255.0, alpha: 0.9), // Pink
UIColor(red: 1.0/255.0, green: 116.0/255.0, blue: 200.0/255.0, alpha: 0.9), // Blue
UIColor(red: 0.0/255.0, green: 188.0/255.0, blue: 111.0/255.0, alpha: 0.9), // Light Green
UIColor(red: 0.0/255.0, green: 196.0/255.0, blue: 179.0/255.0, alpha: 0.9), // Aqua
UIColor(red: 246.0/255.0, green: 50.0/255.0, blue: 62.0/255.0, alpha: 0.9)] // Hot
Here is the code which creates the locations from CloudKit data.
func fetchBubble() {
let query = CKQuery(recordType: "Collection", predicate: NSPredicate(format: "TRUEPREDICATE", argumentArray: nil))
publicDB!.performQuery(query, inZoneWithID: nil) { results, error in
if error == nil {
for collection in results! {
let collectionLocation = collection.valueForKey("Location") as? CLLocation
let collectionName = collection.valueForKey("Name") as! String
dispatch_async(dispatch_get_main_queue(), { () -> Void in
if CLLocationManager.isMonitoringAvailableForClass(CLCircularRegion.self) {
let intrepidLat: CLLocationDegrees = (collectionLocation?.coordinate.latitude)!
let intrepidLong: CLLocationDegrees = (collectionLocation?.coordinate.longitude)!
let title = collectionName
let coordinate = CLLocationCoordinate2DMake(intrepidLat, intrepidLong)
let regionRadius = 50.0
let region = CLCircularRegion(center: CLLocationCoordinate2D(latitude: coordinate.latitude,
longitude: coordinate.longitude), radius: regionRadius, identifier: title)
self.locationManager.startMonitoringForRegion(region)
let restaurantAnnotation = MKPointAnnotation()
self.mapView.addAnnotation(restaurantAnnotation)
restaurantAnnotation.coordinate = coordinate
let circle = MKCircle(centerCoordinate: coordinate, radius: regionRadius)
self.mapView.addOverlay(circle)
self.numberOfObjectsInMyArray()
}
else {
print("System can't track regions")
}
})
}
}
else {
print(error)
}
}
}
Then I draw the circles with the following code
func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer {
let circleRenderer = MKCircleRenderer(overlay: overlay)
for index in 1...5 {
circleRenderer.fillColor = self.tableColors[index + 1]
}
return circleRenderer
}
I've tried a few ways of looping through the colours but at the moment it is applying the same colour from the array to each of the bubbles.
Any help would be hugely appreciated!

In the rendererForOverlay callout method you are setting same last color to all the circleRenderer. So instead of your code
for index in 1...5 {
circleRenderer.fillColor = self.tableColors[index + 1]
}
replace with
circleRenderer.fillColor = self.randomTableColors()
And implement this method to give the random color as follow.
func randomTableColors() -> UIColor {
let randomIndex = Int(arc4random_uniform(UInt32(tableColors.count)))
return tableColors[randomIndex]
}

Related

SwiftUI & Contentful Client Error: Type of expression is ambiguous without more context

The code below shows the code I am using to fetch data from Contentful API to my SwiftUI app. However, by calling the function client.fetchArray, I got an error message saying that the type of expression is ambiguous. I tried look up the documentation and the example code for client.fetchArray uses the exact parameters and hence I assume the error message should be gone? Can anyone please help me out here! I am super confused! Thank you!
import SwiftUI
import Contentful
import Combine
let client = Client(spaceId: "qqq2yu4vbtpl", environmentId: "master", accessToken: "LurTiklxcr0ARTpI9z7GVTz-mjMO6OFVsoSZ8V7GJ4c")
//let client = Client(spaceId: "0ge8xzmnbp2c", accessToken: "03010b0d79abcb655ca3fda453f2f493b5472e0aaa53664bc7dea5ef4fce2676")
func getArray(id: String, completion: #escaping([Entry]) -> ()) {
let query = Query.where(contentTypeId: id)
client.fetchArray(of: Entry.self, matching: query) { result in
switch result {
case .success(let array):
DispatchQueue.main.async {
completion(array.items)
}
case .error(let error):
print(error)
}
print(result)
}
}
class CourseStore: ObservableObject {
#Published var courses: [Course] = courseData
init() {
let colors = [#colorLiteral(red: 0.3635728061, green: 0, blue: 0.8927152753, alpha: 0.8470588235), #colorLiteral(red: 0.2461163998, green: 0.3063159585, blue: 1, alpha: 0.8470588235), #colorLiteral(red: 0.3414418995, green: 0.653152287, blue: 0.405282855, alpha: 0.8470588235), #colorLiteral(red: 0.8906980753, green: 0.684363246, blue: 0, alpha: 0.8470588235), #colorLiteral(red: 0.5725490451, green: 0, blue: 0.2313725501, alpha: 1), #colorLiteral(red: 0.5058823824, green: 0.3372549117, blue: 0.06666667014, alpha: 1), #colorLiteral(red: 0.1411764771, green: 0.3960784376, blue: 0.5647059083, alpha: 1), #colorLiteral(red: 0.5568627715, green: 0.3529411852, blue: 0.9686274529, alpha: 1), #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)]
getArray(id: "course") { (items) in
items.forEach { (item) in
self.courses.append(Course(
title: item.fields["title"] as! String,
subtitle: item.fields["subtitle"] as! String,
image: item.fields["image"] as! String,
logo: item.fields["logo"] as! String,
color: colors.randomElement()!,
show: false))
}
}
}
}
For my Data.swift file, I have written the following code fyi:
import SwiftUI
struct Post: Codable, Identifiable {
var id = UUID()
var title : String
var body : String
}
class API {
func getPosts(completion: #escaping ([Post]) -> ()) {
guard let url = URL(string: "https://jsonplaceholder.typicode.com/posts") else { return }
URLSession.shared.dataTask(with: url) { (data, _, _) in
guard let data = data else { return }
let posts = try! JSONDecoder().decode([Post].self, from: data)
// Must be async to run API call
DispatchQueue.main.async {
completion(posts)
}
}
.resume()
}
}
And here is the code for my DataStore.swift, think it will be helpful for my data fetching script:
import SwiftUI
import Combine
class DataStore: ObservableObject {
#Published var posts: [Post] = []
init() {
getPosts()
}
func getPosts() {
API().getPosts { (posts) in
self.posts = posts
}
}
}

How to change colors of a cell of collection view on scrolling swift5

i want to change color of the cell of my collectionview on scrolling in swift.
here is an image of my viewcontroller. i want to change background color of the specific cell to white on scroll. and i used animatedcollectionViewLayout for animation.
This may help you, call it in scrollViewDidScroll. Don't use indexPathsForVisibleItems、visibleCells, they have a few issues.
func updateCellsApperance() {
let visibleRect = CGRect(origin: modesCollectionView.contentOffset, size: modesCollectionView.frame.size)
let center = CGPoint(x: visibleRect.midX, y: visibleRect.midY)
var indexPaths: Set<IndexPath> = []
let step = 10.0
var x = center.x
while x > visibleRect.minX {
if let indexPath = modesCollectionView.indexPathForItem(at: CGPoint(x: x, y: center.y)) {
indexPaths.insert(indexPath)
}
x -= step
}
x = center.x + step
while x < visibleRect.maxX {
if let indexPath = modesCollectionView.indexPathForItem(at: CGPoint(x: x, y: center.y)) {
indexPaths.insert(indexPath)
}
x += step
}
indexPaths.forEach { indexPath in
if let cell = modesCollectionView.cellForItem(at: indexPath),
let attrs = modesCollectionView.layoutAttributesForItem(at: indexPath) {
let distanceX = visibleRect.midX - attrs.center.x
// >= 0.0
let ratio = abs(distanceX) * (1.0 / attrs.frame.width)
cell.xxx.color = UIColor(red: 0.0, green: max(0.0, 1.0 - ratio), blue: 0, alpha: 1.0)
}
}
}

How can I highlight a UIImageView from an array when the view is tapped/clicked

I have an array of UIImageViews (8 of them) and I want to highlight which ever one is tapped or clicked. NOTE: It doesn't have to be highlighted I am open to other way as well. As you will see in my code I tried a different way.
As you will see below I tried to access the index.layer.borderColor and then created and if else statement. next I created a UITapGuestureRecognizer function and called this in the viewDidLoad. App is crashing with an "out of bounds" error.
func setHandleTap() {
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleTap))
imageArray[index(ofAccessibilityElement: 0..<7)].addGestureRecognizer(tapGesture)
}
#objc func handleTap() { // this funtion checks to see what the boarder image is and chages it to other once tapped.
if imageArray[index(ofAccessibilityElement: 0..<7)].layer.borderColor == #colorLiteral(red: 0.01680417731, green: 0.1983509958, blue: 1, alpha: 1).cgColor {
imageArray[index(ofAccessibilityElement: 0..<7)].layer.borderColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0).cgColor
}else{
imageArray[index(ofAccessibilityElement: 0..<7)].layer.borderColor = #colorLiteral(red: 0.01680417731, green: 0.1983509958, blue: 1, alpha: 1).cgColor
}
}
}
I call the setHandelTap() in ViewDidLoad hoping it would run allowing the image to be highlighted.
Iterating through the array should be enough for this.
Maybe something like this in your handleTap():
let desiredColor = #colorLiteral(red: 0.01680417731, green: 0.1983509958, blue: 1, alpha: 1).cgColor
for imageView in imageArray {
if imageView.layer.borderColor == desiredColor {
imageView.layer.borderColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0).cgColor // Sets it to Black Color.
}
}
Note: By the way there is no need for the else code because the current color is already the color you wanted to set on the else

MDCTabBarViewController Get Bar To Top Position

I'm using iOS Material components in my app and I came across the Tabs here. Implementing it was easy and after I made a few minor changes to match my design the result was what I wanted:
I achieved this using the following code:
func setupTabBar() {
let customTabBar = MDCTabBar(frame: view.bounds)
customTabBar.items = [
UITabBarItem(title: "Cards", image: nil, tag: 0),
UITabBarItem(title: "Mobile", image: nil, tag: 0)
]
customTabBar.itemAppearance = .titledImages
customTabBar.alignment = .justified
customTabBar.itemAppearance = .titles
//colors
customTabBar.tintColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)
customTabBar.selectedItemTintColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
customTabBar.unselectedItemTintColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
customTabBar.barTintColor = UIColor(red:0.00, green:0.33, blue:0.59, alpha:1.0)
tabBarContainerView.addSubview(customTabBar)
customTabBar.sizeToFit()
tabBarContainerView.layer.shadowOffset = CGSize(width: 0, height: 2)
tabBarContainerView.layer.shadowRadius = 8
tabBarContainerView.layer.shadowOpacity = 0.5
tabBarContainerView.layer.shadowColor = UIColor.black.cgColor
}
However, this is just the Tar bar, I need to have a functional tab view where the user can switch between the two pages. No problem, as the docs say just inherit from MDCTabBarViewController, this ensure my pages are being tabbed, but this also added another tab bar at the bottom, which is fine, now I do not net to create one myself, so I removed mine but now I would just like it to bo the top but cannot find a property to set to get it in the top position:
and here is the code for that:
func setupTabViews() {
let storyboard = UIStoryboard.init(name: "Main", bundle: nil)
let cardsVC = storyboard.instantiateViewController(withIdentifier: "cardsWalletViewController")
let mobileVC = storyboard.instantiateViewController(withIdentifier: "mobileWalletViewController")
let vcArray = [cardsVC, mobileVC]
viewControllers = vcArray
let childVC = viewControllers.first
selectedViewController = childVC
tabBar?.delegate = self
tabBar?.items = [
UITabBarItem(title: "Cards", image: nil, tag: 0),
UITabBarItem(title: "Mobile", image: nil, tag: 0)
]
tabBar?.itemAppearance = .titledImages
tabBar?.alignment = .justified
tabBar?.itemAppearance = .titles
//colors
tabBar?.tintColor = #colorLiteral(red: 0.8039215803, green: 0.8039215803, blue: 0.8039215803, alpha: 1)
tabBar?.selectedItemTintColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
tabBar?.unselectedItemTintColor = #colorLiteral(red: 1, green: 1, blue: 1, alpha: 1)
tabBar?.barTintColor = UIColor(red:0.00, green:0.33, blue:0.59, alpha:1.0)
tabBar?.selectedItem = tabBar?.items.first
}
I noted that on the documentation for MDCTabBarViewController it will create a bottom-anchored tab bar, but how does one use it in the way they clearly illustrate on the 'Tabs' components example where the tabs are located at the top?

Is it possible to draw a clear SCNSphere with a bright red SCNSpotlight?

The last few days I am struggling a bit with SceneKit. I am trying to plot a clear/transparent SCNSphere, with a red spotlight. It appears that my red spotlight is becoming transparant as well if I set my SCNSphere to transpararent / clear colour. Is it possible to unlink the SCNLight Node to the SCNSphereNode, so that the bright red colour of the spot remains if the SCNSphere is transparant? Images of both spheres are below the code.
My code:
func setupView() {
scene = SCNScene()
caliView.scene = scene
caliView.allowsCameraControl = true
caliView.backgroundColor = UIColor.clearColor()
let clearMaterial = SCNMaterial()
clearMaterial.diffuse.contents = UIColor(white: 0.9, alpha: 0.5)
clearMaterial.locksAmbientWithDiffuse = true
let shape = SCNSphere(radius: 5)
shape.materials = [clearMaterial]
let shapeNode = SCNNode(geometry: shape)
let spotLight = SCNLight()
spotLight.type = SCNLightTypeSpot
spotLight.color = UIColor.init(colorLiteralRed: 180, green: 0, blue: 0, alpha: 0.0)
let lightNode = SCNNode()
lightNode.light = spotLight
lightNode.position = SCNVector3(x: 0.0, y:0.0, z:15.0)
lightNode.orientation = SCNQuaternion(x: 0.0, y:0, z:30, w:0.0)
let ambientLight = SCNLight()
ambientLight.type = SCNLightTypeAmbient
ambientLight.color = UIColor(white: 0.8, alpha: 0.2)
let ambientNode = SCNNode()
ambientNode.light = ambientLight
shapeNode.position = SCNVector3(x: 0.0, y: 0.0, z: 0.0)
scene.rootNode.addChildNode(ambientNode)
scene.rootNode.addChildNode(shapeNode)
shapeNode.addChildNode(lightNode)
}
Darker sphere with bright red spotlight:
More transparent sphere with soft red spotlight:
In this line...
shapeNode.addChildNode(lightNode)
...you added the light node to the sphere node.
If you want to un-link them while still having them move together, you can create an empty SCNNode and add the other two SCNNode instances to it as children (the one for the light and the one for the sphere):
func setupView() {
scene = SCNScene()
caliView.scene = scene
caliView.allowsCameraControl = true
caliView.backgroundColor = UIColor.clearColor()
let clearMaterial = SCNMaterial()
clearMaterial.diffuse.contents = UIColor(white: 0.9, alpha: 0.5)
clearMaterial.locksAmbientWithDiffuse = true
let emptyNode = SCNNode()
let shape = SCNSphere(radius: 5)
shape.materials = [clearMaterial]
let shapeNode = SCNNode(geometry: shape)
let spotLight = SCNLight()
spotLight.type = SCNLightTypeSpot
spotLight.color = UIColor.init(colorLiteralRed: 180, green: 0, blue: 0, alpha: 0.0)
let lightNode = SCNNode()
lightNode.light = spotLight
lightNode.position = SCNVector3(x: 0.0, y:0.0, z:15.0)
lightNode.orientation = SCNQuaternion(x: 0.0, y:0, z:30, w:0.0)
let ambientLight = SCNLight()
ambientLight.type = SCNLightTypeAmbient
ambientLight.color = UIColor(white: 0.8, alpha: 0.2)
let ambientNode = SCNNode()
ambientNode.light = ambientLight
shapeNode.position = SCNVector3(x: 0.0, y: 0.0, z: 0.0)
emptyNode.addChild(shapeNode)
emptyNode.addChild(lightNode)
scene.rootNode.addChildNode(emptyNode)
scene.rootNode.addChildNode(ambientNode)
}

Resources