I have made it with Scale to fill aspect for ImageView and it look perfect. Closing.
Post
Replies
Boosts
Views
Activity
@Claude31 - with UICollectionViewDelegateFlowLayout I have managed to do that:
It looks much better, but photos arent the same size, as you can see on the screenshot.
Ok, so I have added this in ViewController.swift:
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
collectionView.collectionViewLayout = UICollectionViewFlowLayout()
}
extension TrasyOpisyController: UICollectionViewDelegateFlowLayout{
func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
return CGSize(width: 700, height: 700)
}
}
And it looks much better:
Now I need to realize how to center it to be in the center of VC, like here:
Ok, I moved on a little bit:
This is my Collection View Size Inspector:
And Collection View Flow Layout:
And CollectionViewCell:
Ok, so far I got this, and the layout is ride off:
import UIKit
class TrasyOpisyController: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource {
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return nazwy_modernizm.count
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "ModernizmCollectionViewCell", for: indexPath as IndexPath) as! ModernizmCollectionViewCell
cell.imageCell.image=self.images_modernizm[indexPath .row]
cell.title.text=self.names_modernizm[indexPath .row]
cell.subTitle.text=self.opisy_modernizm[indexPath .row]
//cell.locationLabel.text=self.czas_rower[indexPath .row]
return cell
}
@IBOutlet weak var collectionView: UICollectionView!
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath){
collectionView.deselectItem(at: indexPath, animated: true) //this does not work
}
let names_modernizm = [("One"),("Two"),("Three")]
let opisy_modernizm = [("one"),("two"),("three")]
let images_modernizm = [UIImage(named: "one.jpeg"), UIImage(named: "two.jpeg"), UIImage(named: "three.jpeg")]
override func viewDidLoad() {
super.viewDidLoad()
collectionView.delegate = self
collectionView.dataSource = self
// collectionView.collectionViewLayout = UICollectionViewFlowLayout()
}
}
//extension ViewController: UICollectionViewDelegateFlowLayout{
// func collectionView(_ collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAt indexPath: IndexPath) -> CGSize {
// return CGSize(width: 10, height: 10)
// }
//} // I was trying with this, but it gets worst
And ModernizmCollectionViewCell:
import UIKit
class ModernizmCollectionViewCell: UICollectionViewCell {
@IBOutlet weak var imageCell: UIImageView!
@IBOutlet weak var iconLabel: UIImageView!
@IBOutlet weak var title: UILabel!
@IBOutlet weak var subTitle: UILabel!
@IBOutlet weak var locationLabel: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
}
In storyboard it looks fine, but when I run the app everything rides off:
@Claude31, for now I think Im doing fine with the collectionView. I will put a tick, when I'll finish. How can I input distance from some point in the label? I have locationLabel in this ViewController (In the cell in CollectionView), but I would like to input the distance in kilometers between user current location and from the point in Struct, which is in another ViewController called simply 'ViewController':
This is this struct from another ViewController:
struct Place {
let name: String
let description: String
let typ: String
let lattitude: CLLocationDegrees
let longtitude: CLLocationDegrees
var coordinate: CLLocationCoordinate2D {
.init(latitude: lattitude, longitude: longtitude)
}
}
let places = [Place(name: "one", description: "desc_one", typ: "one", lattitude: 81.108187, longtitude: 37.075812),
Place(name: "two", description: "two", typ: "two", lattitude: 31.076187, longtitude: 87.000563),
Place(name: "Three", description: "three", typ: "three", lattitude: 31.096688, longtitude: 26.991312),
I have the same issue here. On Xcode an in Simulator. Seems to a be a bug in new software.
@Claude31 Sorry, I think I misled you. I did not added the main class to the question. Thats why your code can't work that way. Here is the correct code:
class AnnotationButton: UIButton {
var annotation: MKPointAnnotation?
}
class ViewController: UIViewController, MKMapViewDelegate {
func findPlace(_ places: [Place]) {
for place in places {
let annotations = MKPointAnnotation()
annotations.title = place.name
annotations.subtitle = place.description
annotations.coordinate = CLLocationCoordinate2D(latitude:
place.lattitude, longitude: place.longtitude)
mapView.addAnnotation(annotations)
}
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
guard !(annotation is MKUserLocation) else { return nil }
let identifier = "identifier"
guard let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier, for: annotation) as? MKMarkerAnnotationView else { return nil }
let leftButton = AnnotationButton(frame: CGRect(
origin: CGPoint.zero,
size: CGSize(width: 25, height: 25)))
leftButton.setBackgroundImage(#imageLiteral(resourceName: "nav"), for: .normal)
annotationView.leftCalloutAccessoryView = leftButton
leftButton.addTarget(self, action: #selector(didClickDetailDisclosureNavigation(button:)), for: .touchUpInside)
if let pointAnnotation = annotation as? MKPointAnnotation {
leftButton.annotation = pointAnnotation
}
@objc func didClickDetailDisclosureNavigation(button: AnnotationButton) {
let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving]
if let mapItem = button.annotation?.mapItem {
mapItem.openInMaps(launchOptions: launchOptions)
}
}
extension MKPointAnnotation {
var mapItem: MKMapItem {
let placemark = MKPlacemark(coordinate: self.coordinate)
return MKMapItem(placemark: placemark)
}
}
@OOPer I've got Value of type 'UIButton' has no member 'annotation' when I try to add:
if let pointAnnotation = annotation as? MKPointAnnotation {
leftButton.annotation = pointAnnotation
}
@OOPer I mean permission to use user location. When user click 'never' while the app is starting, I would like to show an alert after clicking the myLocationButtonTapped that loacation services for this app are off and user need to take an action in settings o turn it on.
@Claude31 one more question - how not to display enumerate titles? Now it shows on the map number and title: 0-One ; 1-Twoetc. I just Want to display names, as before. The names are not dynamic, so maybe better option is to use titles withou "tags"?
Ok, I found a problem - I've added
rightButton.addTarget(self, action: #selector(didClickDetailDisclosure(button:)), for: .touchUpInside)
before the switch, so program was compiling just this one instead of others in switch. Thank you @Claude31
@Claude31 Ok, let me explain:
This one works with couple of VCs, but it does not change the annotation color and image:
switch annotation.title {
case "0-One" :
annotationView.markerTintColor = UIColor.gray
annotationView.glyphImage = UIImage(named: "one")
rightButton.addTarget(self, action: #selector(didClickDetailDisclosure(button:)), for: .touchUpInside)
case "1-Two":
annotationView.markerTintColor = UIColor.gray
annotationView.glyphImage = UIImage(named: "two")
rightButton.addTarget(self, action: #selector(didClickDetailDisclosure2(button:)), for: .touchUpInside)
case "2-Three":
annotationView.markerTintColor = UIColor.gray
annotationView.glyphImage = UIImage(named: "three")
rightButton.addTarget(self, action: #selector(didClickDetailDisclosure3(button:)), for: .touchUpInside)
case .none:
rightButton.addTarget(self, action: #selector(didClickDetailDisclosure(button:)), for: .touchUpInside)
case .some(_):
rightButton.addTarget(self, action: #selector(didClickDetailDisclosure(button:)), for: .touchUpInside)
}
This one changes just the color and image in annotation, but does not change the VCs:
switch annotation.title!! {
case "0-One":
annotationView.markerTintColor = UIColor.gray
annotationView.glyphImage = UIImage(named: "kopula")
rightButton.addTarget(self, action: #selector(didClickDetailDisclosure(button:)), for: .touchUpInside)
case "1-Two":
annotationView.markerTintColor = UIColor.black
annotationView.glyphImage = UIImage(named: "two")
rightButton.addTarget(self, action: #selector(didClickDetailDisclosure2(button:)), for: .touchUpInside)
case "2-Three":
annotationView.markerTintColor = UIColor.red
annotationView.glyphImage = UIImage(named: "three")
rightButton.addTarget(self, action: #selector(didClickDetailDisclosure3(button:)), for: .touchUpInside)
default:
annotationView.markerTintColor = UIColor.darkGray
annotationView.glyphImage = UIImage(named: "place")
rightButton.addTarget(self, action: #selector(didClickDetailDisclosure(button:)), for: .touchUpInside)
}
return annotationView
}
Yes, I have different viewcontrollers, I've tested them with normal buttons.
Ok, I've changed that, thanks
@Claude31 These is same code that Im running:
import UIKit
import MapKit
class ViewController: UIViewController, MKMapViewDelegate {
let initialLocation = CLLocation(latitude: 85.10786543576327, longitude: 11.03851472106171)
let locationManager = CLLocationManager()
struct Place {
let name: String
let description: String
let type: String
let lattitude: CLLocationDegrees
let longtitude: CLLocationDegrees
var coordinate: CLLocationCoordinate2D {
.init(latitude: lattitude, longitude: longtitude)
}
}
let location = CLLocation()
let places = [Place(name: "One", description: "One", type: "one", lattitude: 81.108187, longtitude: 12.075812),
Place(name: "Two", description: "Two", typ: "two", lattitude: 81.076187, longtitude: 11.000563),
Place(name: "Three", description: "Three", typ: "Three", lattitude: 81.076187, longtitude: 11.000563)]
[...]
func findPlace(_ miejsca: [Place]) {
for (i, place) in places.enumerated() {
let annotations = MKPointAnnotation()
annotations.title = String(i) + "-" + place.name
annotations.subtitle = place.description
annotations.coordinate = CLLocationCoordinate2D(latitude:
place.lattitude, longitude: place.longtitude)
mapView.addAnnotation(annotations)
}
}
@objc func didClickDetailDisclosure(button: UIButton) {
guard let vc = storyboard?.instantiateViewController(withIdentifier: "second_vc") as? SecondController else {
return
}
present(vc, animated: true)
}
@objc func didClickDetailDisclosure2(button: UIButton) {
guard let vc = storyboard?.instantiateViewController(withIdentifier: "third_vc") as? SecondController else {
return
}
present(vc, animated: true)
}
@objc func didClickDetailDisclosure3(button: UIButton) {
guard let vc = storyboard?.instantiateViewController(withIdentifier: "fourth_vc") as? SecondController else {
return
}
present(vc, animated: true)
}
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
guard !(annotation is MKUserLocation) else { return nil }
mapView.delegate = self
let annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: String(annotation.hash))
let identifier = "identifier"
annotationView.canShowCallout = true
guard let annotationView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier, for: annotation) as? MKMarkerAnnotationView else { return nil }
let rightButton = UIButton(type: .detailDisclosure) // HERE IS THIS BUTTON, BUT I NEED EACH BUTTON FOR EACH ANNOTATION - THIS WAY IT SHOULD BE ONE FOR ALL OF THEM
rightButton.tag = annotation.hash
annotationView.canShowCallout = true
annotationView.rightCalloutAccessoryView = rightButton
rightButton.addTarget(self, action: #selector(didClickDetailDisclosure(button:)), for: .touchUpInside)
let leftButton = UIButton(frame: CGRect(
origin: CGPoint.zero,
size: CGSize(width: 25, height: 25)))
leftButton.setBackgroundImage(#imageLiteral(resourceName: "nav"), for: .normal)
annotationView.leftCalloutAccessoryView = leftButton
leftButton.addTarget(self, action: #selector(didClickDetailDisclosure2(button:)), for: .touchUpInside)
switch annotation.title!! {
case "0-One":
annotationView.markerTintColor = UIColor.gray
annotationView.glyphImage = UIImage(named: "kopula")
rightButton.addTarget(self, action: #selector(didClickDetailDisclosure(button:)), for: .touchUpInside)
case "1-Two":
annotationView.markerTintColor = UIColor.black
annotationView.glyphImage = UIImage(named: "two")
rightButton.addTarget(self, action: #selector(didClickDetailDisclosure2(button:)), for: .touchUpInside)
case "2-Three":
annotationView.markerTintColor = UIColor.red
annotationView.glyphImage = UIImage(named: "three")
rightButton.addTarget(self, action: #selector(didClickDetailDisclosure3(button:)), for: .touchUpInside)
default:
annotationView.markerTintColor = UIColor.darkGray
annotationView.glyphImage = UIImage(named: "place")
rightButton.addTarget(self, action: #selector(didClickDetailDisclosure(button:)), for: .touchUpInside)
}
return annotationView // Without this one the app shows different VC for each annotation, but without this it does not show markerTintColor and glyphImage.
}
}
@Claude31 Hi, it only works with the number before like this and it does NOT change the tint color and image :
switch annotation.title {
case "0-One" :
annotationView.markerTintColor = UIColor.gray
annotationView.glyphImage = UIImage(named: "photo")
rightButton.addTarget(self, action: #selector(didClickDetailDisclosure(button:)), for: .touchUpInside)
case "1-Two":
annotationView.markerTintColor = UIColor.black
annotationView.glyphImage = UIImage(named: "photo1")
rightButton.addTarget(self, action: #selector(didClickDetailDisclosure2(button:)), for: .touchUpInside)
case .none:
rightButton.addTarget(self, action: #selector(didClickDetailDisclosure2(button:)), for: .touchUpInside)
case .some(_):
rightButton.addTarget(self, action: #selector(didClickDetailDisclosure2(button:)), for: .touchUpInside)
}
If I do case "One" without number before it dont get that. Is there any way to start with 1 instead of 0?